Over-Engineering is the Enemy of Shipping
I've seen startups launch their MVP on Kubernetes with a 12-microservice architecture, load-balanced across three zones using custom API gateways... before they even have their first 100 users.
Let's ground ourselves in 2026 reality.
The Majestic Monolith
If you are a solo developer or a small team, start with a monolith. Next.js API routes or a single Express server connected to a PostgreSQL database will easily handle hundreds of thousands of users if your SQL indexes are correct and you cache appropriately.
Why Monoliths Rule Initially
- Developer Velocity: Running the entire stack locally is exactly
pnpm dev. You don't need a Docker Compose file with 5 dependent services just to test a frontend login button. - Atomic Commits: Changing the database schema and adjusting the API logic happens in a single PR. Microservices require careful schema backward-compatibility across separate repos.
- No Network Overhead: Function calls inside a monolith are instant. Network calls between microservices introduce latency and points of failure.
When Do Microservices Make Sense?
At XRide Labs, we started to break the monolith when:
- We had distinct teams: Team A only cared about the real-time routing engine, while Team B only cared about user billing and subscriptions.
- Resource Scaling: The socket server needed massive concurrent connection capabilities (memory/CPU intensive), while the billing API barely got 10 hits a minute. Scaling them together in a monolith was bleeding money.
The Middleware Glue: tRPC & gRPC
When you finally do split into services, REST becomes painful because you lose types across the network gap.
Why I use tRPC for Node-to-Node
If both my services are TypeScript (e.g., Next.js frontend and a Node.js microservice), tRPC guarantees my frontend knows exactly what the backend is returning without code-gen steps.
Why I use gRPC for Polyglot
When we wrote the high-frequency ride-matching algorithm in Rust, we couldn't use tRPC. We adopted gRPC to define strict .proto schemas so that our Node.js services could talk to the Rust backend natively over HTTP/2.
TL;DR
Don't build Microservices because Netflix did. Netflix has 10,000 engineers. Build a solid monolith, index your database, and scale out only when the code boundary becomes a bottleneck.