Microservices and GenAI in 2026: my Dear Architects conversation
architecting microservice architecture dark energy and dark matter generative AI genAI development socio-technical architecture fast flow success triangle team topologies service granularity design-time coupling runtime coupling anti-patterns deployment pipeline testing refactoring to microservices decision makingContact me for information about consulting and training at your company.
The MEAP for Microservices Patterns 2nd edition is now available
Earlier this year I was a guest on Luca Mezzalira’s Dear Architects podcast. We talked about where microservices are in 2026 and what GenAI changes. My take is that the best software development practices we had before GenAI - you could even say extreme programming - are even more necessary now, because of the nature of GenAI.
Here are the main points. The full conversation is on the episode:
We are still building big balls of mud
Painting with a very broad brush, I think far too many enterprises just muddle along and mostly build big balls of mud.
Software serves two constituencies
Software is an unusual kind of artifact. With most things, how you build one today does not affect how you build the next one. With software, the design decisions you make today affect how easy it is to make changes tomorrow.
Software also serves two constituencies. The end users need features. The organization that builds the software needs it to be easy to change, so that it can keep delivering those features. The second need is the one that gets neglected. The emphasis is on feature development to the exclusion of proper architecture and improving the -ilities. So the software gradually becomes harder to change, and shipping features slows down. As the requirements grow, an application’s architecture has to be improved so that it stays easy to change.
Good practices get devoured
The other part of the problem is what organizations do to good practices. Agile practices came along and got devoured by the organization’s change-resistant antibodies, and morphed into that abomination called SAFe. Then microservices came along and got devoured as well.
The red flags of a distributed monolith
When I start working with an organization, there are a few red flags I look for:
- The ratio of services to developers - For a long time my rule of thumb was one service per team. These days I would say you should only have a service if it solves a problem. A really common anti-pattern is to have almost as many services as developers, or more. I repeatedly see a team of five people with five services, asking how to solve some distributed problem across them. Usually the answer is to merge them together, and then you do not have a distributed problem anymore.
- A go-faster architecture that is not delivering any faster - Look at your deployment frequency and your lead time.
- Testing and releasing services in lockstep - 99% of the reason you have services is so that you can deploy them independently, but then the old QA practice of a system release takes over: we have to test them all together and release them in lockstep.
Either way, you are incurring the cost and complexity of microservices without any of the benefit. They are all symptoms of a distributed monolith.
Dark energy and dark matter
Your default architecture should be a monolith unless you have a clear, tangible problem that introducing one or more services would actually solve. So the question is what problems a service would solve, and conversely, what problems it would create.

I am a science-fiction nerd who is also into software patterns, and the intersection of the two prompted me to come up with the dark energy and dark matter forces. They are the criteria for deciding whether two subdomains should go together in the same service or be separated into different services. I made it up because it sounded really cool, but it turned out to be useful. Both terms come from astrophysics:
- Dark energy - the concept astrophysicists use to explain the accelerating expansion of the universe, an anti-gravity that pushes matter apart. It is the metaphor for the forces that push your subdomains apart into separate services. One is the need for a fast deployment pipeline: the more components you have, the smaller each one is, and the faster its deployment pipeline runs. Another is team autonomy: more services means teams can be more autonomous.
- Dark matter - the invisible matter that makes up most of the universe. You cannot see it, only its gravitational effect. It is the metaphor for the forces that resist decomposition and pull your subdomains together into a monolith. One is minimize runtime coupling: inter-service communication involves latency and can impact availability. Another is prefer ACID over BASE: operations that span multiple services are eventually consistent, not ACID.
There are five forces pushing your subdomains apart and five pulling them together. I described a couple of each on the episode; you can read about all ten on microservices.io. They are in conflict, and the job of the architect - whether choosing between a monolith and microservices, or defining service boundaries - is to find the set of trade-offs that resolves them.
Context matters
The strength of each force depends on your context: the complexity of your application and the number of teams you have. Team autonomy is an excellent thing, but if you only have one team it is not a reason to have multiple services. Similarly, a small application with a few developers committing regularly has a lightly used deployment pipeline that gives fast feedback. As the application grows and the number of teams grows, each build takes longer and more commits flow into the pipeline, and eventually it becomes a bottleneck. That is when you want to go from a monolith with a single deployment pipeline to multiple services, each with its own.
Low latency example
Luca raised the case of a latency-sensitive system where services are ruled out because of the overhead. Suppose an application has many REST endpoints and only a handful of them are latency sensitive. You put those operations, and all the code they touch, in the same service so that they are not distributed, and the operations that are not latency sensitive can be distributed. Low latency might constrain your service boundaries in certain ways, but it does not necessarily force you to use a monolith.
The microservice architecture is unforgiving
Where you put things matters more in a microservice architecture. In a monolith you can write a class and put it anywhere; it does not matter immediately, though modularity and coupling catch up with you later. In a microservice architecture, where you put things has an immediate impact on latency and coupling, and that is how you can very easily end up with a distributed monolith.
There is more to microservices than services
Delivering software with fast flow takes more than the right architecture. You also need the right organization and the right process. Specifically, you need an organization structured according to Team Topologies, DevOps as defined by the DevOps Handbook, and an architecture that enables both. That is what I call the success triangle. And that is the role of microservices when you are building at scale: a large organization and a large application.

Luca observed that companies often adopt microservices without changing anything about the socio-technical system around them. I described this in 2018 as the red flag law anti-pattern. In some jurisdictions, a pedestrian waving a red flag and blowing a whistle was required to walk in front of an automobile. You have a car that could go faster than a person, but rules and regulations slow it down. That is what exists in a lot of organizations: a go-faster architecture that the organization’s policies, procedures, and structure slow down to pedestrian pace.
The fundamentals matter even more with GenAI
The practices that make software easy to change matter more now than they did before GenAI. A coding agent depends on fast feedback and on guardrails. Both of those come from your architecture and your tests.
Coding agents need fast feedback
A coding agent essentially has to use test-driven development. It needs to be able to quickly run the tests and get feedback, so the inner developer loop has to run exceedingly quickly. The outer loop has to be fast too: a push triggers the deployment pipeline, and that needs to run quickly and get the change into production, where it gets more feedback.
The whole motivation for a fast-flow architecture is rapid feedback, so you want to structure your code, your tests, and your deployment pipelines so that your coding agents get prompt feedback. In that sense, microservices are even more likely to be used today than they were before GenAI.
Fast feedback is a property of the architecture
As I wrote in GenAI-based software delivery needs a fast flow architecture, fast feedback loops are a property of the architecture. Loose design-time coupling keeps the scope of a change as narrow as possible. Loose build-time coupling minimizes how much unchanged code has to be rebuilt and retested as a consequence of a change. And the decision to divide an application into services, each with its own deployment pipeline, is an architectural decision too. So architecture is absolutely essential if you are going to benefit from coding agents.
Agents need guardrails
I have had success with GenAI when there are strong guardrails in place:
- Automated tests - one of the first guardrails.
- The more boring, deterministic guardrails - pre-commit hooks that run code-quality checks (I use CodeScene) and vulnerability checks, to keep the AI from doing something stupid.
Otherwise it writes code that it never uses. On one project, 30% of the generated code was dead code - which admittedly happens with humans too, but this is meant to be world-changing technology.
Michael Feathers defined legacy code as code without tests. A tremendous amount of the code being written today does not have proper automated tests, so you let agents loose on it and who knows what bugs they are going to introduce.
Software development is still a human activity
There is also a troubling trend: the idea that AI generates code so fast that we can’t review it, so we must find other ways to validate it. Call me old-fashioned, but software development is still a human activity. It is your code, with your name on it, that you are committing and are accountable for. And I do not think coding agents are capable of the good design that human beings are.
Brownfield is not greenfield
Luca asked whether AI can really take a 20-year-old ERP and quickly move it to whatever architecture you want.
GenAI helps you understand legacy code
GenAI is a useful tool for understanding a legacy codebase, though you have to take steps to ensure that it does not hallucinate. I have had it produce architecture documentation that was quite imaginary: half of it was real, and half was how it thought the system should work, even though it does not.
Modernization is more than generating code
GenAI can also generate code, but it needs the guardrails, the tests, and the specification in order to generate the right code. And modernizing an application involves a lot more than generating code. Quite often you are having to reverse-engineer the requirements. You are also having to design how the new application should work, applying modern techniques such as domain-driven design, good boundaries, and modularity. And as you build it, you are having to learn the new technology you are building it with. There is all this learning going on, and you do it incrementally. That is why I much prefer the Strangler Fig pattern, where you migrate iteratively, over a big bang approach where you get no validation until you are done.
Next.js is not your legacy system
There are some well-known examples of rewrites. Someone rewrote Next.js in a week. But Next.js had a very exhaustive test suite, was well documented, and the web is full of content about it. That is not your legacy system.
I see the same thing on one of my side projects, a language interpreter. I can tell Claude Code “implement language feature X” and it goes off and implements it perfectly, because that language feature is incredibly well documented. Whereas when I am doing normal enterprise-style development, it muddles around and it is a whole lot harder to figure out what needs to be done. A legacy application is a million times worse: a 30-year-old application that might even predate the web.
Convince me
I am willing to be convinced that there is finally some magic technology where you press a button and, hey presto, you get a modern, well-architected application within a week. But people have to demonstrate that it works and that it is not just a big-tech smoke-and-mirrors demo, like a lot of stuff is. Convince me.
Get the fundamentals right
Luca asked me what advice I would give architects going into 2026. My answer has not changed much, because the problems have not changed much either.
A 50-year-old idea that still has not caught on
Most enterprises are struggling with the fundamentals. Modularity and loose coupling date back to Parnas in 1972. That is a 50-year-old concept, and it still has not caught on. A change should ideally happen within one team, but a lot of enterprises have built software that requires a massive number of meetings to coordinate and align in order to roll out a really simple change. There is all this new shiny stuff, but software development would be way better if people got the hang of the fundamentals. And maybe automated testing will catch on too.
The job of an architect is to solve problems
My advice is the same as always. The job of an architect is to solve problems, and you need a disciplined way of doing that:
- define the problem,
- come up with some success criteria,
- brainstorm candidate solutions,
- evaluate them against the criteria, and
- pick the best approach.
Above all, actually think things through.
Demand proof
Have a healthy skepticism. You do not want to be super negative, but you should demand proof: extraordinary claims require extraordinary evidence. Just because some random person on social media says “this worked for me” does not mean it is going to work for you. My mindset is heavily patterns oriented: proven solutions to problems in a given context. Your context is not the same as the random person on X’s context, and you have to carefully think it through.
What else we got into
On the episode, Luca and I also discuss:
- why code is not free - human attention is still a limited resource - and why “three commits before breakfast” leads to burnout: a relentless pair programming partner who won’t stop, and you can’t stop either
- agents for everything: the same overuse we saw with microservices, and how to decide which sub-problems actually need a non-deterministic agent
- “SaaS is dead”, and why big tech is so desperate to make GenAI look revolutionary
- why Luca thinks we are all juniors again, and what it feels like to use GenAI without a conceptual framework
- whether GenAI is undermining the business model of open source, and whether it is hard to justify hiring junior developers
- whether this can even be a profitable industry once you get past Nvidia, the cloud providers, and the consulting companies
- whether spec-driven development is a return to waterfall
You can watch the whole conversation on the Dear Architects podcast.
Need help with modernizing your architecture?
I help organizations modernize their architecture to enable fast flow and GenAI-powered software delivery. If you’re planning or struggling with a modernization effort, I can help.
Learn more about my modernization and architecture advisory work →
Premium content now available for paid subscribers at
