70 microservices was too many

2026-05-02 · 4 min read
ArchitectureMicroservicesEngineering

This is the post I've been trying to write for six months. The platform I work on at the bank ships at 300,000 transactions per hour, holds up under regulatory scrutiny, and survives the kind of failures that would have taken the legacy system offline for a day. It also has 70+ microservices, and I think that's wrong.

I want to be careful here. The team built the right system. The decomposition wasn't reckless. Each service maps to a real banking concept: subscriptions, redemptions, settlement, NAV calculation, compliance reporting, fee accrual, shareholder register. Every service was justified on paper. But "justified on paper" isn't the same as "load-bearing".

What microservices actually buy you

Microservices solve coupling. That's the whole pitch. When two pieces of business logic change for different reasons at different times by different teams, you don't want them in the same deployable. You split them. Independent deploys, independent failure modes, independent scaling.

That's a real win when the coupling is real. The problem is that coupling is often imagined. A team draws domain boundaries on a whiteboard, gets attached to the diagram, and ships seven services where two would have done the work. Each of those services then needs its own deployment pipeline, its own database, its own observability, its own on-call runbook, its own version of the same retry logic written slightly differently.

The operational cost is not linear in the number of services. It's worse than linear. Distributed tracing is non-negotiable past about 10 services. Schema coordination between services produces meetings that wouldn't exist in a monolith. CI/CD complexity grows because you now have ordering dependencies on deploys ("the new subscription service needs the new fee-accrual contract first"). All of this is real engineering work and none of it ships product.

What worked on the bank platform

Bounded contexts around real banking operations were correct. Subscriptions and redemptions genuinely have different consistency requirements, different SLAs, different stakeholders. Splitting them was right.

Independent deploys cut lead time substantially. Without the split we'd be doing weekly release trains and waiting for the slowest team. With it we deploy when we're ready, multiple times a day in some services.

Fault isolation works. A degraded compliance service does not take down trading. That's worth a lot.

What didn't

Most of the splits inside each bounded context were premature. Subscription processing alone became roughly a dozen services. In hindsight maybe four of them needed to be services. The rest could have been modules in a larger subscription service with the same logical separation and a quarter of the operational overhead.

We had services that called exactly one other service, in a one-to-one pipeline, with no other consumer. That's a function call wearing a network. We had services with fewer than 300 lines of code and a deployment pipeline that took longer to write than the service itself.

The hidden tax was the worst part. Adding a new field to a domain event meant updating five services in the right order, coordinating across two teams, and rolling forward through compatibility states. In a monolith with the same domain split into modules, that's one PR.

What I'd do today

I'd ship the same system with maybe 15 to 20 services. The bounded contexts stay. The splits inside them collapse. A subscription service contains the subscription pipeline as modules. A redemption service does the same. NAV calculation stays separate because its consistency model is genuinely different. Compliance stays separate because the regulator wants it that way.

The lesson generalizes. "Microservices" is a coupling answer, not an architectural style. Default to fewer, bigger services. Split when coupling pain demands it, not when the whiteboard looks pretty.

The cleanest heuristic I've found: a service should be small enough that one person can hold its responsibilities in their head, and big enough that you don't need to coordinate a release across multiple services to change one business behavior. By that test, half of what we shipped was too small.

If I started over tomorrow I would not be ashamed to ship a system with 15 services for the same workload. The team would be faster. The bill would be smaller. The system would still hit 300,000 transactions an hour. We'd just spend less time keeping the lights on.