Skip to main content

Keep your API fast—even at peak

Rate limiting and admission checks that help reduce overload and protect expensive work.

Reliable at peak

Set admission budgets for launch spikes and promos before excess work reaches your handlers.

Lower cloud costs

Fewer moving parts to run and monitor. Spend less on Redis and ops.

Dev‑first adoption

Add via SDK. Keep your stack. Clear limits your customers understand.

UNDERSTAND OVERLOAD · KEEP USEFUL WORK MOVING

Keep useful work moving.

For developers, architects, and managers: 27 narrated lessons on why services overload and how to protect them. No cloud experience required. Start with one request, or jump to any lesson.

Course map Lesson 10 of 27 Browse all lessons

Four chapters, one learning path. Read or listen in any order. ~41 minutes total · Times shown at 1×.

Keep enough capacity to finish work and recover.

  1. 01 A useful result starts with one request
  2. 02 Unfinished work grows when arrivals outrun completions
  3. 03 More waiting space does not make work finish faster
  4. 04 A timeout ends waiting, not necessarily the work
  5. 05 Retained work can exhaust a process’s memory
  6. 06 One failed copy can push its neighbors over capacity
  7. 07 Refuse new work while the application can still recover
  8. 08 Different compute platforms still have finite resources
  9. 09 A shared database failure can spread back into every app
  10. 10 Restore capacity before restoring full traffic You are here
  11. 11 A circuit breaker stops repeating a failing call

Contain one customer's excess without punishing everyone.

  1. 12 One customer’s excess should not ruin another’s day
  2. 13 A rate limit checks one customer’s recent allowance
  3. 14 Copies and languages must share the same intended policy
  4. 15 Fairness helps contain damage without reserving every resource
  5. 16 A legitimate crowd can exceed shared capacity

Reduce work entering a shared dependency when it slows.

  1. 17 Measure the operation whose pressure you want to observe
  2. 18 A shared tracker observes; a guard decides; your app acts
  3. 19 Even the fastest recent observations can become slow
  4. 20 Separate local histories can reopen into the same burst
  5. 21 Replace optional expensive work before refusing essential work
  6. 22 A local breaker learns after calls have already piled up
  7. 23 Fast errors explain why the protections remain complementary
  8. 24 Latency feedback helps without measuring exact spare capacity

Choose, combine, and test the right protections.

  1. 25 Ask three different questions before expensive work
  2. 26 Recovery attempts need limits too
  3. 27 Measure useful service, not how much work you accepted

Read the explanation or use the course map above. Audio is optional.

10 / 27

Restore capacity before restoring full traffic

Recovery capacity and feedback

Load balancerRequests from customersServer ASame service codeApplication copyReady to serveServer BSame service codeApplication copyReady to serveServer C0 available / sSTARTINGNo serving capacityCount ready capacity, not processes requestedLoad balancerRequests from customersServer AApplication copySame service codeReady to serveServer BApplication copySame service codeReady to serveServer CSTARTING0 available / sNo serving capacityCount ready capacity, notprocesses requested
  1. Ready copies Can attempt work

    Only useful end-to-end results establish service.

  2. Starting copy Not ready capacity

    Do not count desired or booting copies as ready.

Illustrative capacity and request counts, not a deployment recipe. Readiness requires useful results; the traffic-ramp diagram is a decision guide, not measured recovery.

Read the numbered steps in order. The explanation below follows the narration.

A partially restarted fleet has less ready capacity.

Control admission while dependencies, replicas, and caches recover.

0:00
Read transcript & diagram walkthrough

What you will learn

Control admission while dependencies, replicas, and caches recover.

Restarting processes is not the same as restoring useful service. In our earlier example, two ready copies could finish two hundred requests per second. Sending the old two hundred forty can overload them before the third copy is ready.

Remember that a cache reuses an answer instead of asking the database again. Suppose, among one hundred requests, a warm cache answers eighty and twenty need one database call each. A cold cache has none of those answers: the same hundred requests now need a hundred database calls. That is five times the database work, without more customers.

Reduce or temporarily stop admitted traffic through a tested control. Keep resource limits active during recovery. Restore required dependencies and ready application copies. Where warming caches helps, bound that work too; warming itself loads the database.

Send a small trial of real work. Check that complete reports arrive, waiting clears, and memory stays bounded. A healthy process alone is not enough. Increase in small steps, observing each step before adding more. If waiting or failures grow, hold or reduce traffic again. A timer or fixed ramp percentage is not proof that capacity has recovered. Recovery order and useful cache preparation depend on the application. Rehearse this with its actual dependencies, instead of assuming every restart can immediately take full traffic.

Diagram walkthrough
  1. Starting a process does not prove the service is ready.

    The application copies return at different times. C is still starting and supplies no ready capacity. Even a running copy also needs working dependencies before it can complete the customer’s report.

  2. The old demand can overload an only partly restored fleet.

    Using the earlier equal-cost model, two ready copies provide 200/s while the offered demand is 240/s. A third starting copy adds no ready capacity yet. Actual recovery capacity can be lower while caches or dependencies recover.

  3. A reusable answer avoids a database call.

    A valid cached answer can serve a repeated request without asking the database again. Restart behavior depends on where the cache lives; the following example explicitly considers a cache whose reusable answers are absent.

  4. Warm cache: 100 customer requests need 20 database calls.

    In this illustration, eighty requests reuse valid answers and twenty each need one database call. Every tile represents ten customer requests, so the C tiles avoid database work and the D tiles require it.

  5. Cold cache: the same 100 requests need 100 database calls.

    The same 100 customer requests now find no reusable answers. Assuming one database call per miss, every request reaches the database. We did not add customers; we removed the reuse that previously avoided work.

  6. 20 → 100 calls: five times the work, not five times the customers.

    Compare the two cases for the same one hundred requests. Database calls increase fivefold in this simplified example. That does not imply five times the latency, or establish any safe traffic rate for the recovering database.

  7. Control the input while useful capacity is being restored.

    Use a recovery control that has actually been rehearsed. Reducing or stopping admitted work keeps the recovering system from being immediately overwhelmed by the old demand; the exact mechanism depends on your application.

  8. Recovery still needs room to finish work and respond.

    Do not disable the application’s resource bounds just because it is recovering. Accepted work, cleanup, and refusals still need working space while dependencies and traffic conditions are changing.

  9. Restore the components that the complete result depends on.

    Required dependencies must respond and enough application copies must be ready. This is an end-to-end readiness relationship, not a universal process restart order; your dependency structure determines the recovery sequence.

  10. Cache warming is work too; it also needs a budget.

    Preparing useful cache entries can reduce later misses, but the preparation itself may query the database. Bound that work against recovering capacity. Some caches remain warm or do not benefit from preparation; warming is not a universal prerequisite.

  11. Test with a small amount of real customer work.

    Follow the highlighted trial step. A real report exercises the useful path through the application and dependencies. The rest of the diagram is a decision guide, not a claim that its success conditions have already been observed.

  12. Observe useful completion and bounded retained work.

    Check complete reports reaching customers, waiting work clearing, and memory remaining bounded. A health check proving that a process is alive is not enough evidence that its dependencies and real request path can handle the offered work.

  13. Only then try one small increase and observe again.

    A successful trial justifies testing a little more traffic, not jumping to the former full load. Allow meaningful request lifecycles and cleanup to reveal the effect of each change before making another increase.

  14. Worsening results mean hold or reduce—not keep increasing.

    Follow the alternative branch when waiting or failures grow. Pause the increase or reduce admitted work, then reassess. Capacity changes during recovery, and an earlier successful trial cannot justify blindly continuing the ramp.

  15. A schedule is not evidence of recovered capacity.

    An elapsed timer, fixed percentage, or desired replica count is not proof that capacity has recovered. Rehearse admission controls and dependency-specific recovery, including cache behavior and meaningful observation between traffic changes.

Content revision: 07c7dd00db17

Download review copy (27 lessons)
Check your understanding & apply it

The same 100 requests previously needed 20 database calls. With no reusable answers, each needs one call. What changed before adding any customers?

Show the explained answer

Database calls rose from 20 to 100: five times the work in this illustration. That does not imply five times the latency, or prove that restarting processes restored useful capacity.

Integration guidance

Keep admission and resource bounds active; send a small trial, observe complete customer results and retained work, then increase, hold, or reduce traffic based on the observed effect.

Where the promise stops

Cache preparation and recovery order depend on the application. Do not invent one universal restart procedure.

Technical depth & sources

Concepts used here

Implementation detail

Recovery capacity is time-varying. Rehearse cache misses, dependency readiness, caller repeat attempts, routing delays and the cost of warming. Observe each ramp step over meaningful request lifecycles; a timer or desired replica count does not establish recovered capacity.

Original explanation inspired by Fred Hébert and operational references; no endorsement implied.

AI-generated narration: ElevenLabs Eleven v3, Daniel stock voice. Audio streams only when you start listening.

ElevenLabs

Why teams choose us

Happier customers
Consistent response times when it matters most.
Faster delivery
Ship features, not DIY limiters and brittle ops workarounds.
Clear controls
Per‑tenant and per‑route limits your stakeholders can reason about.

Engineering blog

View all posts →

Why you shouldn’t use Redis as a rate limiter: Part 1 of 2

A tour of the common Redis-based rate limiter implementations — and the correctness and performance traps each one hides.

Auto-Scaling Won’t Save You

The myth of infinite serverless scale — why adding machines doesn’t fix overload, and what to do instead.