skip to content
Mehdi Mehdikhani
Table of Contents

Every few years someone tells me their team is “moving to microservices.” When I ask why, answer is usually something like “that’s how Netflix does it” or “we need to scale.” Most of the time, they have 6 developers and one database.

Here’s the thing: replacing method calls with network calls makes everything harder, slower, and more brittle. It should be absolute last resort, not the default architecture choice.

Basecamp Example

Basecamp runs a monolith that serves millions of users across 6 platforms. Their team? 12 programmers and 7 designers. That’s it. The monolith has 200 controllers, 900 methods, 190 model classes. And one person can still understand the whole system.

They didn’t just keep their monolith, they doubled down on it. When building Basecamp 4, they decided not to rewrite from scratch. Instead of chasing microservices trend, they evolved existing codebase incrementally. Replaced jQuery with Hotwire, modernized frontend piece by piece.

Even more interesting they left the cloud entirely. Moved everything from AWS to their own hardware. Saved $1.5 million per year. Bought two server pallets for $500K and projected $7 million savings over five years. Without hiring single additional person.

Their deployment tool Kamal deploys in 20 seconds. Compare that to Kubernetes pipelines that take minutes and require dedicated ops team to maintain.

The Real Cost of Microservices

I wrote before about microservices and when they make sense. The honest answer is: rarely. What used to be function call becomes network request with timeouts, retries, and circuit breakers. Simple user registration turns into coordinated dance across multiple services that can each fail independently.

DHH’s five step recovery plan for teams stuck in microservices:

  1. Stop creating new services. Just stop.
  2. Consolidate critical paths first - signup, checkout, anything where coordination kills you.
  3. Leave performance hotspots for last - only keep services that genuinely need isolation.
  4. Drop esoteric implementations - if you have 4 programming languages across 12 services, you already lost.
  5. Learn module-based partitioning - use namespaces and modules before reaching for network boundaries.

GitHub runs a monolith with millions of lines of code. Shopify too. If they can do it with thousands of programmers, your team of 15 probably doesn’t need 23 microservices.

AI Agents Make This Problem Worse

Here’s where it gets interesting. AI coding agents can now scaffold entire microservice architectures in minutes. Need a new service? Just prompt it. API gateway, message queue, service mesh, Kubernetes configs all generated before lunch.

This is dangerous.

The hard part of software was never writing the code. It was deciding what to build and keeping it maintainable. AI agents remove the friction of creating complexity, but they don’t remove the cost of maintaining it. You can now build a distributed system in afternoon that will take months to debug when something breaks at 3 AM.

I see teams using AI to generate service after service, each one “clean” and “well-structured” in isolation. But the system as whole becomes unmaintainable. Nobody understands the full picture anymore. The AI generated it, but who’s going to fix the race condition between order service and inventory service when they disagree about stock levels?

More code doesn’t mean better software. AI makes it trivially easy to produce more code. That’s exactly why discipline about architecture matters more now, not less.

What Actually Matters

Before splitting anything, ask yourself honestly:

  • Do you have more than 20 developers stepping on each other? If no, monolith is fine.
  • Do parts of your system have genuinely different scaling needs? Not theoretically actually, right now?
  • Can one person still understand the critical paths in your system?

If your monolith feels messy, the answer is better modules and cleaner boundaries inside single codebase. Not network calls between separate deployments.

Basecamp proved you can serve millions of users with small team and simple architecture. They proved you don’t need the cloud, don’t need Kubernetes, don’t need microservices. And the fact that AI can now generate all that complexity in seconds doesn’t mean you should let it.

Complexity is still the enemy. AI just made it easier to invite inside.