
Breaking down large applications without breaking your business.
Bo Clifton
You have a monolith. It’s old, it’s profitable, and everyone is terrified to touch it.
Deployments take hours. A change in the billing module somehow breaks the user profile page. Onboarding a new developer takes three months because they have to "learn the system."
You want to rewrite it. You dream of microservices, clean domains, and independent deployments. But if you try to rewrite it from scratch, you will likely fail.
The "Big Bang" rewrite is the most common way large modernization projects die. You spend two years building the new system while the old system keeps evolving. You never catch up.
You should stop trying to replace the system and start trying to strangle it.
Before you write a single line of microservice code, you need to accept an uncomfortable truth: Microservices are more complex than your monolith.
Your monolith has function calls; microservices have network calls. Your monolith has a database transaction; microservices have eventual consistency. Your monolith has one log file; microservices have distributed tracing (or a lack thereof).
Martin Fowler calls this the Microservice Premium. You should only pay this premium if your system is too complex to manage as a monolith. If you are decomping just because it's trendy, you are trading a management problem for a distributed systems problem. Distributed systems are harder.
If you are sure you need to proceed—because of team scaling issues or deployment bottlenecks—you need a strategy that manages this risk.
You should not shut down the old system until the new one is done. Instead, you should place a proxy in front of your legacy application and route traffic to new services piece by piece.
This is the Strangler Fig Pattern.
Named after a fig tree that grows around a host tree and eventually kills it, this pattern allows you to move functionality gradually.
This approach lets you deliver value immediately. You don't wait two years for a release; you wait two weeks for the first slice.
When you extract that "Shipping" service, you will find that the legacy database is a mess. The Orders table probably has columns for shipping, billing, and customer preferences all mixed together.
If you let your new microservice read directly from that legacy schema, you have failed. You have created a distributed monolith. Your new service is now coupled to the old database structure.
You should use an Anti-Corruption Layer (ACL).
An ACL is a translation layer. It sits between your new service and the legacy system. It prevents the legacy domain model from "corrupting" your new, clean domain model. When the legacy system changes, you only update the ACL, not your entire new service.
This is the part everyone ignores because it is hard.
You cannot share a database between microservices. If you do, you lose the ability to deploy independently. If Service A changes a column and Service B breaks, they are not decoupled.
You should aim for Database per Service.
This means your new Shipping service controls its own data. It does not reach into the monolith's database. If it needs data from the monolith (like Customer addresses), it should either:
This is difficult. It forces you to deal with data synchronization and eventual consistency. But if you don't do it, you aren't building microservices; you're just building many ways to crash one database.
Your legacy frontend is likely just as tangled as the backend. As you split up the backend, your frontend shouldn't have to know which service hosts which endpoint.
You should consider using Backends for Frontends (BFF).
Instead of a generic API for all clients, you create a backend specifically for your web app (or mobile app). This layer aggregates calls to your new microservices and your legacy monolith. To the frontend, it looks like one API. Behind the scenes, the BFF handles the messy work of stitching data together.
AI will not architect your system for you. It cannot understand your domain boundaries or your business constraints. Do not ask it to "convert this monolith to microservices."
However, modern AI tools are excellent tactical assistants during decomposition:
Decomposition is a marathon. It requires discipline. The goal is not "to have microservices." The goal is to have a maintainable, deployable system.
If you follow these patterns, you might actually survive the transition. If you try to rewrite it all at once, we'll see you in two years when you start the next rewrite.
The High Cost of Cool — Why Boring Tech Wins
Stop chasing the latest trends. For most businesses, simple, proven technology drives more value with less risk.
The State of AI Augmentation — Doing More With The Team You Have
How small business leaders can use generative AI to scale their impact and capabilities without replacing their people.