LearnastraTHE DESIGN COURSE

Make the right trade-off / CHAPTER 32

Token bucket versus leaky bucket

Control bursts and steady work deliberately, including atomic accounting and overload behavior.

Intermediate1h of deliberate study10 questions

Builds on Functional and non-functional requirements, Back-of-the-envelope estimation.

By the end, you can
  • Calculate token replenishment and burst allowance.
  • Distinguish policing from queued shaping.
  • Prevent two servers from spending the same token and define accounting-store failure behavior.

01A rate and a burst are different limits

A customer organization shares an API allowance across all its users and servers. We want to allow occasional bursts without letting it consume unlimited sustained work.

A token represents permission to do some work. A token bucket:

  1. Keeps up to B tokens as saved credit.
  2. Adds r tokens per second, stopping at B.
  3. Lets a request proceed only if it can spend the required tokens.

An ordinary read may cost one token and an expensive export five. Idle time earns credit up to the limit, so a short permitted burst can proceed immediately. A component making this immediate allow-or-reject decision is a policer.

“Leaky bucket” has two related meanings. A queued shaper holds requests and releases them at a controlled rate, adding waiting time. A meter instead estimates how much work an imaginary queue would still contain and immediately rejects work exceeding its limit. State which behavior you mean; the name alone does not tell callers whether they wait.

02Implement accounting as one decision

Give the organization 20-token capacity and refill at 5 tokens/s. All API servers must use the same allowance or reserved portions of it.

For each request, one indivisible operation does the following:

  1. Read the balance and last-refill time stored under the organization's key.
  2. Calculate earned credit: elapsed seconds × 5, then cap oldBalance + earnedCredit at 20.
  3. Compare the request's cost with that available balance.
  4. If enough credit exists, deduct the cost and allow the request. Otherwise reject it without deducting its cost. Save the newly refilled balance and time in that same indivisible operation, including on rejection.

“Atomic” means another caller cannot slip between the comparison and deduction. If two servers each read one token and later write separately, both can spend that last token. A shared transaction or script must protect the complete decision, not just each final write. Define clock source, precision and state expiry; recreating a full bucket too early can grant unearned credit.

Mechanism What is stored? What happens to an excess request?
Token bucket Available credit and refill time. It is normally rejected immediately when credit is insufficient.
Queued leaky shaper Requests waiting for controlled release. It waits while space exists, then is rejected when the finite queue fills.
Leaky meter An estimate of unfinished work that decreases with elapsed time. It is immediately allowed or rejected against that estimate, without an actual request queue.

03Worked example: a permitted burst

Start at time zero with 20 tokens and one token per read.

  1. Twenty simultaneous reads spend all 20. An immediate twenty-first read is rejected; merely receiving a request does not earn a token.
  2. Wait 0.4 seconds from empty. Five tokens/s × 0.4 seconds earns two tokens, enough for two reads. Two idle seconds earns ten.
  3. Charge an export five tokens. It consumes the same allowance as five ordinary reads, making the limit better reflect expensive work.
  4. Avoid independent full buckets on ten servers. They permit ten bursts and about 50/s aggregate refill. To enforce 5/s total, share the balance or reserve constrained portions from one total.

Now queue 20 requests in a shaper that releases one every 200 ms, equivalent to 5/s. If the first release is immediate, the twentieth leaves after 19 gaps: 3.8 seconds. That cannot fit a 200 ms interactive target unless most requests are rejected or the queue is much smaller. A different first-release convention changes the calculation, so state it.

Also protect unfinished work separately. At 10 admitted requests/s and 0.1 s mean duration, average in-flight work is one. At two seconds it becomes 20 under stable load. The arrival rate stayed allowed, but the requests now occupy many more worker slots or connections.

Token bucket versus leaky bucket — decision flow

Token bucket versus leaky bucket — decision flowLook up the organization’s stored balance and last-refill time. In one indivisible operation, add earned credit, check the request cost and deduct it if allowed. Reject work without credit and provide retry guidance; do not promise an unlimited waiting queue. Numbered arrows correspond to the connection key below. All connections are directional.Customer APIrequestsRead costs 1 token;export costs 5Shared tokenbalanceCapacity 20; earn 5tokens/secondProtected APIAlso limit unfinishedrequestsReject excessworkTell the caller whenit may retry123Token bucket versus leaky bucket — decision flowLook up the organization’s stored balance and last-refill time. In one indivisible operation, add earned credit, check the request cost and deduct it if allowed. Reject work without credit and provide retry guidance; do not promise an unlimited waiting queue. Numbered arrows correspond to the connection key below. All connections are directional.Customer APIrequestsRead costs 1 token;export costs 5Shared tokenbalanceCapacity 20; earn 5tokens/secondProtected APIAlso limit unfinishedrequestsReject excessworkTell the caller whenit may retry123Token bucket versus leaky bucket — decision flowLook up the organization’s stored balance and last-refill time. In one indivisible operation, add earned credit, check the request cost and deduct it if allowed. Reject work without credit and provide retry guidance; do not promise an unlimited waiting queue. Numbered arrows correspond to the connection key below. All connections are directional.Customer APIrequestsRead costs 1 token;export costs 5Shared tokenbalanceCapacity 20; earn 5tokens/secondProtected APIAlso limit unfinishedrequestsReject excessworkTell the caller whenit may retry123

Follow the numbered arrows

  1. Customer API requests → Shared token balancerefill, compare and spend atomically
  2. Shared token balance → Protected APIallow the request after deducting tokens
  3. Shared token balance → Reject excess workreject when credit is insufficient
One atomic operation refills, checks and spends the organization’s token balance. Excess work is rejected rather than hidden in unlimited waiting.
Trace the diagram in words
  1. Look up the organization’s stored balance and last-refill time.
  2. In one indivisible operation, add earned credit, check the request cost and deduct it if allowed.
  3. Reject work without credit and provide retry guidance; do not promise an unlimited waiting queue.

04Match the rule to the protected resource

Match the control to the resource:

  • Use a token bucket when a short burst is useful and the backend can absorb it.
  • Use queued shaping when smoother output matters and callers can tolerate the calculated wait. Set a finite queue limit.
  • Limit concurrency as needed. An arrival limit does not stop slow requests from occupying every connection.
  • Limit total work as well as each organization. Many customers respecting their own limits can still overwhelm one database.
  • Choose behavior when the allowance store fails. Fail-open accepts work without exact shared accounting; fail-closed rejects because remaining credit cannot be established. A strict spending cap cannot safely become unlimited during an outage.
  • Reserve limited local credit if useful. Subtract each server's allocation from the shared total in advance; during failure it can spend only that amount.
  • Guide rejected clients. Estimate when refill would cover the missing tokens and tell the client when to try again. This is not reserved credit: other requests may spend it first. Encourage longer waits after repeated rejection, with varied retry times so clients do not all return together.

State the accounting key, capacity, refill rate, cost, atomic update, maximum wait and outage behavior. These details determine what the algorithm actually permits.

DRAW. CALCULATE. EXPLAIN.

Walk a weighted burst

20 minutes · guided practice

Capacity is 30, refill 10/s. A tenant sends 24 one-token reads and two five-token exports simultaneously through four servers. Assume reads are processed first. After one idle second, another export arrives. Calculate admission and choose behavior when shared accounting fails.

Your self-check
Compare the worked solution
  1. Process the reads first against one shared balance. Twenty-four one-token reads leave 6 of the original 30 tokens.
  2. One five-token export fits and leaves 1. The second export is rejected.
  3. One idle second at 10 tokens/s raises the balance to 11. The next export fits and leaves 6.
  4. Four servers must not each create a new 30-token balance. Use one atomic balance update or portions reserved from the shared total.
  5. For a strict spend cap during an outage, reject unknown-credit requests or spend only preallocated local credit. State the finite total that can still be spent.

The checkboxes record your own assessment. The worked solution gives you a way to check the reasoning.

RETRIEVE BEFORE YOU REVEAL

Keep the important ideas.

Say the answer aloud, then turn the card over.

CARD 01How does a token bucket decide?

In one indivisible update:

  1. Refill earned tokens up to capacity.
  2. Compare the request cost.
  3. Deduct only if allowed.

Capacity permits bursts; refill rate controls sustained credit.

CARD 02How do leaky-bucket variants differ?
  1. A queued shaper holds requests and releases them at a controlled rate.
  2. A meter tracks an imaginary unfinished-work count and immediately allows or rejects.

State whether callers wait and how much work may accumulate.

CARD 03What can a rate limit miss?
  1. An allowed arrival rate can still fill every worker when requests slow down.
  2. Limit simultaneous work separately.
  3. State whether allowance covers one user, organization or the entire service.
Practise this topic in the revision deck ↗

CHECK THE REASONING

Can you explain the choice?

Answer every question, then finish for an immediate score and an explanation for each answer. Aim for 80%, then revisit any gaps.

1 / 10A full 20-token bucket receives 21 one-token calls at once. How many initially fit?
2 / 10An empty bucket refills at 5/s for 0.4 seconds. How many one-token requests fit?
3 / 10An export costs five tokens and balance is seven. What remains after admission?
4 / 10Two servers read one remaining token before either writes. What must change?
5 / 10Ten servers each own an independent 5/s full tenant allowance. What sustained aggregate may result?
6 / 10A 5/s shaper releases its first of 20 queued requests immediately. When does the twentieth depart?
7 / 10Why can an aggressively expired bucket violate the intended burst budget?
8 / 1010 requests/s now take 2 s on average. Mean in flight under stability?
9 / 10Which outage policy best fits a strict external spending cap?
10 / 10Why add an overall cap when each tenant has a limit?
0 of 10 answered

CLOSE THE LOOP

Explain it without the page.

Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.

Go to the source