Your App Will Break at 10K Users. Here's How to Prevent It.
Every app hits a wall#
Your app works great with 100 users. At 1,000 it's slow. At 10,000 it's on fire. At 100,000 it's dead.
This isn't a bug. It's a design problem. And "throw more servers at it" is not the answer — that's just burning money.
Here are the five patterns that actually work.
1. Put a load balancer in front#
Dead simple. Instead of one server doing everything, spread the load across many.
But here's what most tutorials skip: which algorithm?
- Round-robin — fine for stateless APIs
- Least connections — better when some requests are heavier than others
- IP hash — need it when you have sticky sessions
If you're starting out, round-robin with health checks. Don't overthink it.
2. Cache everything you can#
The fastest database query is the one you never make.
- CDN for images, CSS, JS — this is free performance
- Redis for computed results and session data
- Query cache for repeated database queries
I've seen caching alone reduce database load by 90%. Ninety percent. Before you add a read replica, add a cache.
See these patterns in an interactive diagram
Try it →3. Stop making users wait#
If something takes more than 200ms, it shouldn't be in the request path. Push it to a queue.
- User uploads a video? Queue it. Process async.
- Sending a welcome email? Queue it.
- Generating a report? You get the idea.
Kafka for high-throughput event streams. SQS for simple task queues. RabbitMQ if you need routing logic. Pick one and use it everywhere.
4. Shard your database (but not yet)#
Everyone wants to shard their database. Almost nobody needs to. Sharding adds massive complexity — cross-shard queries, rebalancing, operational overhead.
Do this first:
- Add indexes (seriously, check your slow query log)
- Add a read replica
- Add caching
- Optimize your queries
- THEN consider sharding
If you're still hitting limits after all that, hash-based sharding is the safest bet.
5. Circuit breakers save your life#
When a downstream service dies, don't let it take everything down with it. Circuit breakers detect failures and fail fast instead of hanging.
Three states:
- Closed — normal, requests flow through
- Open — service is broken, return error immediately
- Half-open — test with a few requests to see if it recovered
This is the difference between "one service is down" and "the whole platform is down."
See it all together#
Here's what a properly scaled system looks like with all five patterns:
Build a scalable system now
Stop reading about architecture. Start building it. Describe any system and watch it come alive.
Launch CodelitContinue learning
Go deeper on performance and scale
As an Amazon Associate I earn from qualifying purchases. Codelit may receive a commission at no extra cost to you.
Systems Performance
Brendan Gregg · 2020
Reference tables and USE-method checklists for when every dashboard is green and latency is not.
4.8 (335)#1 in Computer Performance OptimizationBPF Performance Tools
Brendan Gregg · 2019
150+ ready-to-run bpftrace and BCC tools, with the one-liners and the output you get on a live box.
Release It!
Michael T. Nygard · 2018
Post-mortems of real outages, then the stability patterns (circuit breaker, bulkhead) that stop them.
4.6 (501)#4 in Client-Server Networking SystemsLearning Domain-Driven Design
Vlad Khononov · 2021
Turns bounded contexts and aggregates into decision rules for where service boundaries actually go.
4.6 (400)