Dev

10x Traffic Doesn't Kill You. Your Assumptions Do.

Most engineers think scaling means rewriting everything. It doesn't. The bottlenecks that murder you at 10x traffic are almost never where you think they are, and I have the PagerDuty receipts to prove it.

10x Traffic Doesn't Kill You. Your Assumptions Do.

Black Friday 2021. Stripe-adjacent payments company, 8M daily active users. We'd spent six months 'preparing for scale' — new microservices, Kubernetes migration, the whole thing. Traffic spiked 9x. We fell over in 11 minutes. The culprit wasn't our services. It was a Postgres connection pool misconfigured since 2019 that nobody had touched because it was 'working fine.'

That outage cost $1.2M in lost transactions and two weeks of my life I'm not getting back.

Your Database Is Already On Fire

Here's the thing about 10x traffic: your application servers scale. Kubernetes adds pods, load balancers distribute, autoscaling does its job. That part actually works. What doesn't scale is everything your application servers talk to.

Postgres with PgBouncer misconfigured will let 500 connections queue silently and then start refusing them. MySQL with innodb_buffer_pool_size set to the default 128MB on a box with 64GB RAM is leaving 90% of its hardware on the floor. Redis with no maxmemory policy will consume all available memory and start evicting keys you thought were persistent. These aren't edge cases. I've seen all three in production systems at companies that had 'prepared for scale.'

Before you write a single line of new code, pull up your database metrics in Datadog right now. Look at connection count vs max connections. Look at cache hit ratio. If your Postgres cache hit ratio is below 99%, you have a problem that 10x traffic will turn into a disaster.

The Reads You're Paying For Twice

Don't rewrite. Add a read layer. This is the highest ROI change you can make and most engineers skip it because it feels too simple.

At Netflix I watched teams spend quarters on database sharding when adding a Redis read-through cache in front of their primary would've bought them two years. Sharding is a last resort. Caching is a first resort. The sequence matters.

The specific pattern that works: cache aggressively at the application layer with explicit TTLs, never rely on cache-aside as your only strategy, and build a stale-while-revalidate pattern for anything that can tolerate two seconds of staleness. Your users can't tell the difference. Your database can.

The Config Files Nobody Reads

NGINX worker_processes defaults to 1. In 2024. On a 32-core machine. That's not a bug, it's a trap, and it's been eating production systems for fifteen years.

Before any traffic spike, audit every default config in your stack. NGINX worker_connections. Gunicorn or uWSGI worker counts. JVM heap settings. TCP backlog limits. These are not interesting problems. They're not the stuff of conference talks. But they will absolutely kill you at 3am when traffic doubles and your on-call engineer is staring at a saturated single worker process wondering why the CPU graph looks fine.

The boring config you've never questioned is more dangerous than the complex code you review every week.

What You Actually Need to Rewrite

One thing. Synchronous calls in your critical path that could be async. If a user action triggers an email, a Slack notification, a webhook, and an audit log write — and all of that is synchronous — you've built a 4x latency multiplier into your hot path. Move it to a queue. SQS, RabbitMQ, whatever you already have. Do this before you touch anything else.

Everything else is premature. I've never seen a 10x traffic problem that required a rewrite. I've seen hundreds that required someone to finally read the documentation for tools they'd been running in production for three years.

OPEN IN REEDL_ FEED →← Back to feed