Contact

Technology

May 06, 2015

Of Mustard Seeds and Microservices

Micah Blalock

Micah Blalock

Default image background

The kingdom of heaven is like a mustard seed, which a man took and planted in his field. Though it is the smallest of all seeds, yet when it grows, it is the largest of garden plants and becomes a tree, so that the birds come and perch in its branches (Matthew 13:31-32). 

I’ve always loved this short parable because it makes a virtue of the weedy character of the mustard plant. Mustard grows very quickly, spreads easily, grows in every climate and soil, and though it can grow into something tree-like, as an annual it dies at the end of each growing season. I think these same weedy virtues characterize the best architectural style for organizations looking to become more innovative and agile.  

Conway’s Conundrum

I’ve worked with many organizations struggling to become more responsive to quickly changing market forces. Most have adopted some form of Agile to improve their development process; but success with Agile is anything but automatic. Conway’s law provides some useful context regarding this issue, an organization’s systems are always constrained by the organization’s structure. A successful Agile initiative will often require organizational transformation. But what are the constraints on organizational change?

Management’s commitment to cultural change is certainly important. But one of the least discussed factors in organizational transformation is system architecture. As a software architect, I’ve seen time and again how common architectural styles impact the organization. If you’ve just spent $10 million on a new database system, every new project will, not surprisingly, have a database requirement.

Traditional architecture emphasizes efficiency, cost control, ROI, restrictive governance, and long-range predictions. This approach creates a reality distortion field that:

  • Exaggerates the value of reuse and common standards and practices.

  • Under estimates the cost of coordination and management overhead.

  • Favors prediction over feedback.

  • Resists technological and cultural change.

Rise of the Rhizome

In their classic works, Schizophrenia and Capitalism and A Thousand Plateaus, Gilles Deleuze and Felix Guattari expand on the mustard seed parable to describe a set of organizational qualities they call rhizomatic. The most common organizational structure in the corporate world is the tree. Tree structures are hierarchical, linear, foundational, teleological, and singular. Rhizomatic structures, by contrast, have the following characteristics:

  • Rhizomes resist hierarchy and centralized control.

  • Rhizomes are non-linear and have no end point (non-teleological).

  • Rhizomes are resilient and respond quickly to environmental changes.

  • Each node is both autonomous and fully connected to every other node.

  • Rhizomes are complex systems that grow in unexpected ways and develop emergent behaviors (mutualism).

  • Rhizomes grow quickly and are hard to kill.

In the tree structure, the primary work of each resource is to support the existing structure. In a rhizome, the structure exists to support the individual nodes.

Rhizomatic Patterns

I once heard a talk on organizational transformation based on the Shakespearean quote, “The first thing we do, let’s kill all the lawyers.” It was a great talk, emphasizing the need to flatten our organizations, but suggesting a top-down approach. I understand executive ‘buy-in’ is necessary for any large initiative to succeed. However, I doubt a non-hierarchical, decentralized structure can be created (or imposed) by top-down, hierarchical means.

I believe a rhizomatic structure can be grown within almost any organization by making small, but consistent, choices that create a culture of autonomy, responsibility, collaboration, speed, and rapid course correction. For a rhizomatic culture to thrive, any practice that creates friction should be avoided. But, there are two common architectural patterns, in particular, that are responsible for a significant amount of friction: the monolith and the silo.

Monoliths

A monolith is the simplest approach to a new project. It is easy to develop, easy to build, easy to deploy. However, over time, as the application becomes larger and the team size increases, the application becomes more difficult to change. Multiple teams changing the same code base causes a dramatic increase in coordination overhead and risk. Higher risk makes testing and deployment more complex.

Silos

Silos exist in every non-agile organization: product management, user experience, development, quality assurance, database administration, system administration, operations, etc. To manage risk and complexity, organizations often create silos around shared enterprise resources (e.g., an enterprise service bus) and shared code libraries. These specialization silos ensure the integrity of these core systems and manage change requests from other teams. This dependency chain creates high coordination costs at best and severe gridlock at worst.

In an attempt to avoid gridlock, I’ve even seen a management silo (governance or review committee) created around a silo to “help” coordinate communication and approve/prioritize change requests. I know team leads that do nothing but attend coordination and planning meetings. From the standpoint of traditional architecture, this monolithic, siloed pattern meets all the requirements for efficiency, quality control, and cost control. However, it’s difficult to see how an organization stuck in ‘coordination hell’ can remain competitive.

If monoliths and silos are thriving in your organization, you might consider a rhizomatic architecture for new projects only. In time, you may be able to use these rhizomatic projects in a ‘strangler’ pattern to begin replacing a legacy monolith.

Rhizomatic Microservices

Service-oriented architecture is an established architectural style that many feel has not lived up to its promise. Many SOA implementations rely heavily on ‘enterprise’ tools such an ESB or a BPM engine. It’s almost inevitable that a specialization silo will be erected around these enterprise tools. Microservices transform this common architectural style into a rhizomatic pattern. A microservice architecture emphasizes autonomy, responsibility, speed, and evolutionary growth.

Freedom and Responsibility

Each service should be autonomous and ‘owned’ by a single team. Ownership means that the team is responsible for the entire life cycle of the service: from conception to deployment to maintenance. The team has the freedom to refactor, change, and replace as necessary, but also the responsibility to avoid changes that break consuming services.

Since the team is responsible for deployment, use the opportunity to begin developing an automated deployment pipeline from the beginning. Autonomous services do not need coordinated deployments and new features should be delivered as soon as ready to achieve the short feedback loop necessary for rapid course correction and customer responsiveness.

Speed

Speed is achieved by minimizing management overhead and coordination costs. Autonomy, team size, and code base size are the primary contributors to speed. To maintain autonomy, loose coupling must be preserved. Since the services are distributed, loose coupling should be easier for microservices. However, the danger comes from integration and shared resources. Integration should be exclusive to public APIs and pub/sub messaging. Any other point of integration should be avoided. Some architects even suggest that every service should have its own data repository so tight coupling does not eventually leak into their services.

GARY not DRY

We all know and understand the intrinsic logic of the design principle DRY (don’t repeat yourself). As a counterpoint to DRY, one of my colleagues recently created a new acronym, GARY (go ahead, repeat yourself). We keep this acronym on the board in our team room because we allowed a shared dependency to creep into our architecture at an early stage. At the time it seemed it might save us a good bit of boilerplate code in each of our services. It has been very much the opposite and will be removed in our first refactor. All shared dependencies have a cost. Avoid them whenever possible. If you must use a shared code library, make sure that it is compiled into a versioned jar that services can integrate as time allows.

Evolutionary Growth

Teams have the freedom to use ‘best fit’ technologies and experiment with new techniques. Shorter development cycles means shorter feedback loops so evaluation of a technology is fast. Successful experiments become repeatable patterns that spread quickly through the organization. Unsuccessful experiments are easily replaced with little risk or coordination cost.

Cultivating Weeds

If your organization is trying to become more competitive, look carefully at your organization and your architecture. Does your current architecture encourage or impede the development of a rhizomatic culture of autonomy, responsibility, collaboration, speed, and rapid course correction? If you’re struggling, consider growing some weeds.

Conversation Icon

Contact Us

Ready to achieve your vision? We're here to help.

We'd love to start a conversation. Fill out the form and we'll connect you with the right person.

Searching for a new career?

View job openings