Monolith vs microservices in 2026: I still start with one deployable — here’s when I split

Elena Vasquez

Elena Vasquez

August 28, 2026

Monolith vs microservices in 2026: I still start with one deployable — here’s when I split

I still start a new product with one deployable. Not because I have not seen microservices work. I have. I have also seen a six-person company run seven services, three queues, and a “temporary” shared library that was the real monolith, only harder to step through. In 2026 the fashion is quieter than it was in 2018, but the reflex is still there: draw boxes, name them, ship them separately, call it architecture.

I draw modules. I ship one thing. I split when a calendar or a scaling boundary shows up, not when a diagram does. Here is the default, and here is when I break it.

What I mean by one deployable

One repo can still have many packages. One process can still have a worker next to HTTP. I am not arguing for a single file. I am arguing for one thing you roll back on a Friday. One pipeline. One set of env vars you can name. A second process for jobs is fine if it is the same release. A second service with its own release train is the thing I will not start with.

Modular monolith is the phrase. I use it without the conference tone. Packages with names. Database tables that know which package owns them. An API module that is allowed to call inward and not the other way around. If we cannot keep that hygiene in one process, we will not keep it over the network.

Why the default is still one

A new product’s first job is a checkout, a webhook, a row, a deploy that survives. Distributed transactions are not a first job. Neither is “who owns this proto file.” One deployable means the types are in one language, the tests run in one command, and the person who broke billing can see the auth change in the same diff.

Hiring in 2026 does not give you a platform team on week two. Microservices assume someone will own the mesh, the tracing, the CI matrix, the versioning. If that someone is also writing the feature, you do not have microservices. You have a second job. I have been that job. I shipped less product and more YAML.

Local development is a product feature. One compose file that starts the app is a feature. Eight services and a script that only works on one person’s machine is how you lose a week of onboarding. I will pay that cost when the services have earned it. They have not earned it on day one.

A single deploy pipeline with a green check on a quiet office monitor

When I split: a team boundary with a clock

I split when two teams cannot ship without waiting on the same release, and that wait is measured in days, not in feelings. If frontend platform and billing are stepping on each other every week, and they have different on-call rotations, a split can buy them a calendar. If they are the same four people wearing two hats, a split buys them two deploys and the same wait.

The test I use: can I name the other team and the last three times we blocked them. If I cannot, I am splitting for an org chart we do not have. Draw the module. Put a codeowner on it. Revisit in a quarter.

When I split: a scaling boundary I can measure

I split when one part of the system has a cost or a risk the rest should not share. Image conversion that eats CPU. A webhook flood that should not sit on the checkout process. A compliance island that cannot see the rest of the data. Those are measured. “We might scale” is not measured. I have split a worker out of a monolith without calling it a microservice culture. Same release, different process, then a different service when the worker’s deploy cadence actually diverged.

I also split when the failure domain is wrong. If a search reindex can take down login, that is a process problem first. If it is already a separate process and still shares a blast radius we cannot accept, then a service boundary might be real. I do not skip the process step. Node taught me that. Every language taught me that.

When I split: a technology I cannot honestly keep inside

Sometimes the work is a different runtime. A Go ingest next to a TypeScript API. A Python job next to a JVM core. I will start that as a worker if I can. I will make it a service when the language boundary is already a team boundary or a scaling boundary. I will not make it a service so the diagram has more colors.

I will not split because a talk said each service should be one language of choice. That is how you get five languages and one customer.

Two teams at separate whiteboards linked by a messy run of network cables

When I will not split

I will not split to make the architecture look like a slide from a company with 400 engineers. I will not split because the monolith feels embarrassing. Embarrassment is not a production metric. I will not split because deploys are slow until I have asked why they are slow. Slow tests and a fat image are cheaper to fix than a mesh.

I will not split a module that still shares a database with no ownership. That is a distributed monolith. I have lived there. Every “simple” change became a migration conversation across two repos and a backward-compatible window we always underestimated. If I cannot give the new service its own data, I am not ready to give it its own process. I extract the data ownership first, even if it stays in the same cluster, then I extract the deployable.

I will not split because we want independent scale and we have 200 users. Independent scale is a gift you buy with complexity. At 200 users the gift is unused and the complexity is not.

How I split when I do

I pick one seam. I give it a contract. I dual-run if I have to. I do not boil the ocean. The rest of the monolith stays. The new service gets its own on-call from day one, even if that on-call is the same humans. The name on the page has to exist. If nobody wants the page, the seam was vanity.

I keep a way to run the old path. Feature flags are not optional on an extract. I have flipped a split and watched a retry storm because we assumed the new service was equivalent. Equivalence is a test, not a hope.

I do not extract shared libraries as a substitute for a service. A shared lib that every service must bump in lockstep is a monolith with more ceremony. Sometimes that is fine. I just will not lie about it.

What 2026 changed, and what it did not

Platforms got easier. You can stand up a service on a Friday with less pain than in 2016. That made splitting cheaper. It also made splitting tempting for people who have not paid the tax yet. Agents will write the boilerplate for the fifth service. They will not own the outage when the fifth service’s queue backs up. The default I want from an agent is a module. The default I will accept from a human is the same.

What did not change: distributed systems are still distributed. Timeouts, retries, idempotency, tracing. If the team cannot name those without a slide, they are not ready for a second deployable. Teach the module. Then teach the network.

The checklist I use on day one

  • Can we name the first seam that would actually hurt if it stayed in-process for a year?
  • Do we have two teams with two calendars, or two hats?
  • Is there a measured CPU, traffic, or compliance island?
  • Can the new thing own its data?
  • Who gets the page, by name?

Zero yeses: one deployable. One yes: maybe a second process, same release. Two or more: I will consider a service, and I will still try to extract one seam, not five. I still start with one. I still split on purpose. I still refuse to split so the architecture looks busy. Busy is not an architecture. It is a week you will not get back, and a Friday you will not want to own.

A founder once asked me to “just make it microservices so we can hire in parallel.” I asked who the second team was. There was not one. There was a hope. Hope is not a boundary. We kept the monolith, named three packages, and hired the second person into a codeowner file. Six months later we split billing because two teams existed and the release wait was real. That split was boring. Boring is the compliment. The early split would have been a story. I am done collecting those stories for people who have not yet shipped a checkout.

More articles for you