Ah, microservices.
In the grand Hegelian tradition of programmer dialectics—React vs. Angular, Emacs vs. Vim, Tabs vs. Spaces—the great debate of Microservices vs. Monoliths rages on.
Generally speaking, “doing microservices” at inception is premature abstraction. Therefore, most microservice architectures emerge through migrations from a monolithic architecture. This migration is often a make-or-break moment for a software organization. Migrate well and you’ll unlock the ability to maintain velocity as your app serves more and more users. Migrate poorly and your entire engineering team could be stuck in stasis for months or years, bogged down in a never-ending slog that blocks critical features and hamstrings your ability to scale.
At Sourcegraph, we’ve had the privilege of working with some of the best engineering organizations in the world and have enabled major architectural migrations across many different industries. Here, we share a common template we’ve discovered after witnessing what works and what doesn’t.
Here are five critical elements to a successful, large-scale architectural migration:
- Designate a single owner and identify all the stakeholders
- Define what success is and isn’t
- Alternate between big non-breaking changes and small breaking ones
- Automate with the human in the loop
- Track progress
1. Designate a single owner and identify all stakeholders
Identify a single team or person who will be responsible for driving the migration. A common choice is the leader of the developer experience team. This person must understand that the task at hand is not just a technical one, but one of stakeholder alignment and communication. They will be pushing changes that impact the work of many teams. It’s important they are able and willing to help those teams understand the importance the change and enlist their cooperation in the effort.
Tactically, it’s important for the owner to identify all the stakeholders whose input is necessary as early as possible. This will ensure those stakeholders will support the effort as something they helped define, instead of something that feels like it’s being imposed on them without their input. The stakeholders list should include all the owners of the code that will need to be modified. The “find-references” feature of your editor or code browser is your friend in this endeavor!
2. Define success
Lay out a clear vision for what the end state of the migration looks like and tie this to the goals you want to achieve. A lot of big migrations drag on because the original objectives were not clearly defined. The migration may also be abandoned if it has dragged on and it remains unclear how far away the finish line is.
Defining the end state also helps you justify the bigger changes that are necessary to make a real difference. Avoid the inertia of incrementalism by picking a desired end state that reflects your true architectural goals. For example, if your goal is to modularize the major components of a monolith, some pretty big changes will be necessary and you’re unlikely to reach your goal if you limit yourself to local, conservative changes.
Here is a template derived from a few examples of planning docs for large-scale migrations.
Share this document with the list of stakeholders you created in step 1. Feedback serves two purposes:
- Feedback will improve the proposal by