rapidlaunchcode.app
Enterprise StarterAdvisoryEngineeringProductsWritingAbout
Book a call
rapidlaunchcode.app

Independent technology advisory and engineering. København, Denmark.

Njalsgade 21F, 2. sal, København

CVR 45 44 13 93

Nicklas@rapidlaunchcode.app

WhatsApp +45 31 33 25 99

Work

  • Enterprise Starter
  • Advisory
  • Engineering
  • Products
  • Contact

Resources

  • Writing
  • Guides
  • Free tools
  • About

Elsewhere

  • HourIQ
  • Translately
  • NomadWorld
  • Privacy

© 2026 Rapid Launch Code ApS. All rights reserved.

Built in København with Next.js, Contentful, and zero consultancy bullshit.

Back to writing
2024-02 · 3 min

The microservices trap

Microservices became the default recommendation regardless of whether they were appropriate. For most teams that bought the pitch, the bill arrived 18 months later.

On this page
  • The conversation that always starts the same way
  • The promise vs. the bill
  • The modular monolith middle ground
  • When to split for real
  • The migration trap
Updated 2024-02
TL;DR
  • "We need microservices because we're scaling" is almost always the wrong sentence.
  • Distributed systems multiply your failure modes before they multiply your throughput.
  • A modular monolith gives you 80% of the benefit at 10% of the operational cost.
  • Split when team size, SLAs, or failure isolation force your hand. Not before.

The conversation that always starts the same way

Most microservices conversations start the same way. A founder, a CTO, or a head of platform sits across from me and says some version of: "We're growing, so we need microservices."

They almost never need microservices. They need a refactor, a few clear module boundaries, a database that isn't being abused, and an honest conversation about who is on-call. What they were sold was an architecture. What they actually have is a hiring problem, a coupling problem, or a deploy problem wearing an architecture-shaped costume.

The promise vs. the bill

The pitch is easy to fall for, because parts of it are true:

  • Independent services that can be developed, deployed, and scaled separately.
  • Teams that can pick the right tool for their service.
  • Failures isolated to a small part of the system.

The bill nobody quotes you up front:

  • Network is not your code. Every call that used to be a function call is now a request that can time out, retry, and double-fire.
  • Data has to live somewhere. Either you split your database (and lose joins, transactions, and referential integrity) or you keep one (and lose half the point of microservices).
  • Schema drift is forever. Two services on two release cycles will get out of sync. You will write a contract test suite, and you will hate it.
  • Observability is now a product. Tracing, log correlation, and request IDs become non-negotiable infrastructure, not a nice-to-have.
  • Eventual consistency is a UX problem. Users notice when their cart is empty for three seconds after they added something to it.
Distributed systems do not multiply your throughput first. They multiply your failure modes first.

The modular monolith middle ground

Almost everything people want from microservices — clean boundaries, parallel work, the ability to reason about a chunk of the system in isolation — you can get from a well-structured monolith. With one database, one deploy, and one set of dashboards.

The pattern is straightforward:

  • Bounded contexts as modules. Each module owns its tables, exposes a typed interface, and never reaches into another module's storage.
  • One transaction across modules when the business needs it, instead of distributed sagas you'll re-debug for the rest of your life.
  • Background work via a table-backed queue until you have a real reason to introduce a broker.
  • Strict module-to-module API tests, so the boundaries are real, not vibes-based.

When you actually need to extract a service, you extract a module. The boundary is already there, the tests are already there, and the team knows what they're carving off.

When to split for real

The honest signals that justify the cost of going distributed are:

  • You have more than one team that genuinely owns a slice end-to-end, including on-call.
  • Two parts of the system have different SLAs. A 99.99% checkout cannot share a deploy window with a 99% recommendation engine.
  • You need failure isolation. When the analytics pipeline catches fire, the storefront must keep selling.
  • You have genuinely divergent scaling profiles. One workload is CPU-bound and chatty, the other is memory-heavy and quiet.

"We might want to one day" is not on this list. Neither is "the new senior engineer is used to it."

The migration trap

If you've already inherited a microservices mess, do not big-bang it back into a monolith. Use the opposite of how you got there: a strangler fig in reverse. Pick the two services that talk to each other the most. Move them into one process. Delete the inter-service calls. Repeat.

The order matters. Start with the services that share data, not the ones that share a UI. The latency wins are immediate, the operational wins compound, and you stop paying for the network as a database.

What to actually do
  • If you are under ~50 engineers, your default is a modular monolith.
  • Make module boundaries explicit and enforced before you make them physical.
  • Justify every new service with a real, observed production problem.
  • Treat eventual consistency as a UX decision, not an implementation detail.
  • If you're already distributed and don't need to be, merge back. It's a feature, not a defeat.

Want this kind of judgment on your project?

I read every email within one working day. Bring a project, a quote, or a system you're stuck on.

Book a 30-min callSee the Enterprise Starter
More writing
  • 2026-05

    The 5 unbilled months hidden in every Contentful enterprise build

    Every Contentful enterprise build I have audited carries the same five hidden months: link references, redirects, i18n, schema-driven forms, and type safety. None of them are on the SOW. All of them are on the timeline.

  • 2024-03

    Why simple architecture always wins

    Complex systems fail in complex ways. The most successful projects I've seen are the ones that resisted the urge to over-engineer.

  • 2024-01

    The real cost of custom development

    Custom software isn't just the initial price. It's maintenance, updates, and the opportunity cost of not using existing solutions.