Your Side Project Hit the Front Page — Surviving a Spike on One Container
Someone posted your project somewhere popular and traffic is arriving faster than it ever has. Most advice for this moment assumes you can add instances — you can't. An app here is a single container, so the spike is absorbed by one process, and your options are to make each request cheaper or to give that process more resources. The good news is that a small container serves a surprising amount of traffic when the work per request is small. The bad news is that the single most tempting reaction — pushing a quick fix — is the worst thing you can do, because deploying replaces the container, dropping every connection and emptying every cache at the moment you can least afford it.
Find what's expensive per request
Before touching anything, work out what each request actually costs you. It's rarely raw CPU, and almost always something you do per visitor:
- A database query per page view, especially an unindexed one
- An API call per request — a model call is the extreme case, both slow and billed
- Rendering something identical for everyone, over and over
- A connection pool sized for a bigger machine, so requests queue behind connections
If everyone is getting the same page, you're paying to produce it thousands of times. That's the thing to fix, and it's usually a ten-line change.
Cache the identical work
The highest-leverage change during a spike is not doing the same work repeatedly:
- Cache the computed response in memory with a short TTL. Ten seconds is enough to collapse a stampede into one computation per ten seconds, and nobody notices ten-second-old data on a landing page.
- Set HTTP caching headers so browsers stop asking. Be realistic about what this buys: there's no CDN in front of your app, so headers help repeat visitors and not the first wave.
- Serve static assets from the image, not from a database or a computed route.
An in-process cache is genuinely the right tool here — there's one container, so there's nothing to share state with, and a dictionary with a TTL is faster than any network round trip.
Reject cheaply, before doing work
Not all of a spike is people you want. Bots and scrapers arrive with the crowd.
- Rate limit per IP in your process — nothing in front of your app does it.
- Cap request sizes so a large body can't consume memory you don't have.
- Return early. Validate and reject before touching a database or an external API — the cheapest request is one you refuse in a few microseconds.
If you have an endpoint that calls a paid API, protect it specifically. A spike on that route is a bill, not just load.
Raise the preset — before, not during
You scale up rather than out: choose a larger preset within your account limits. Billing is per-minute on what you allocate, so running larger for a day costs a day.
The catch is timing. Changing CPU or RAM recreates the container, so doing it mid-spike drops everything in flight. If you know a spike is coming — you're posting the launch yourself — resize first. If it's already happening, weigh a few seconds of downtime now against continued struggling, and accept that either choice is defensible.
Lower it again afterwards. A preset raised during a launch and forgotten is the most common way a hosting bill quietly grows.
Degrade instead of failing
A slower site that works beats a fast error:
- Serve stale content rather than recomputing under load.
- Turn off the expensive feature. A flag that disables search, or the personalised panel, or the model-backed summary, is worth having before you need it — and an environment variable makes it flippable without a code change.
- Queue writes rather than doing them synchronously, if the user doesn't need the result immediately.
Decide in advance what you'd turn off. Deciding under pressure produces worse choices.
What not to do
Don't deploy. This is the important one. A deploy stops the container and starts a new one with no overlap, so you lose every in-flight request, every open connection, and every cache you'd warmed. That's the opposite of what a struggling app needs, and it's the reflex most people have. Unless the fix is genuinely load-related and certain, wait.
Don't add infrastructure mid-incident. A cache server, a queue, a second app — all of these are good ideas on a calm afternoon and terrible ones now. Each is a new failure mode introduced while you're already firefighting, and a second app can't even share your data.
Don't chase autoscaling. There isn't any, and looking for it wastes the time you could spend on a ten-second cache.
Don't panic about being slow. Requests queuing is not the same as being down. A page that takes two seconds during the busiest hour of your project's life is a success story.
Afterwards, keep the numbers
The spike is the best data you'll ever get about your app, and it's gone unless you wrote it down.
- What was the actual peak? Requests per minute, if you counted them.
- What broke first? That's your real bottleneck, not the one you assumed.
- Did you hit CPU throttling or memory? Both are measurable rather than guessable.
- What did it cost? Both hosting and any per-request API spend.
Then make the one change that would have mattered most, while it's fresh. Not all of them — just the one.
FAQ
Can I autoscale during a traffic spike?
No. An app is a single container, so you scale vertically by raising the CPU and RAM preset, and reduce the work per request.
What helps most in the moment?
Caching identical responses in memory with a short TTL. It converts thousands of identical computations into one every few seconds.
Should I resize during the spike?
Only if you accept a brief interruption — changing the preset recreates the container. Resize before a spike you're expecting.
Can I deploy a fix while it's happening?
Avoid it. A deploy drops all connections and clears your caches, which makes things worse before they get better.
Is being slow the same as being down?
No. Queuing requests still get served. Don't take drastic action because response times rose.
What should I do afterwards?
Record the peak, identify what broke first, and make the single highest-value change. The data expires from your memory faster than you'd expect.
Wrapping up
Handling a spike on one container is mostly about arithmetic: how much work you do per request, multiplied by requests you didn't plan for. You can't change the multiplier, so you change the work — cache the identical parts, reject the unwanted ones early, and turn off what's expensive. Then leave it alone. The instinct to ship a fix mid-spike is strong and almost always wrong, because on this platform a deploy is the one action guaranteed to make the next thirty seconds worse.