The quota is yours to spend. Watch how much is left, fire a request, follow it to the limiter, and find out why it came back a 200 or a 429 — in the selected algorithm's own numbers.
Real-time quotaOne click, one requestNo outbound requests
Tokens accrue continuously up to capacity. Spend a burst instantly, then move at the refill rate.
Algorithm
Capacity
Refill / second
Request cost
11
request you can still make
8.0 / 8 units · 7 per request
Bucket
ready now
Request path0 in flight
CLIENT—
EDGE—
LIMITER—
HTTP—
Press Space to fire. Spam it — requests overlap, and each one is decided the moment it reaches the limiter.
Sent
0
Admitted
0
429
0
Streak
0
Best streak
0
Last verdict
Send a request. The verdict, the quota it spent, and the reason behind it land here.
Your requests
none yet
Nothing sent yet.
Request lifecycle
The useful detail lives between the boxes.
LimitLine expands a decision into the state reads, time math, mutations, and response signals that make it safe to operate.
01
Identify
Build a stable quota key from the smallest trustworthy identity: tenant, user, route, or a deliberate combination.
02
Restore
Use elapsed time or a window boundary to calculate the capacity available at the instant the request arrives.
03
Decide
Spend quota only when enough remains. Atomic execution keeps concurrent requests from spending the same unit twice.
04
Explain
Return the status, quota fields, and Retry-After signal a client can use to shape its next request.
Capacity 20 · refill 2 tokens/sec
The token model
Restore lazily. Spend atomically.
No background job adds tokens. Each request calculates what elapsed time earned, clamps the result to capacity, and attempts to spend its cost in the same storage operation.
available = min(capacity, stored + elapsed × refill) allowed = available ≥ request_cost retry_in = (cost − available) ÷ refill
Choose the failure shape
Precision is not always the goal.
Token bucket
Executable
Absorbs controlled bursts while a refill rate governs sustained traffic.
Fixed window
Executable
Uses minimal state, but two adjacent windows can admit a boundary spike.
Sliding log
Executable
Produces exact rolling-window decisions and pays with timestamp state per admitted request.
Leaky bucket
Reference
Shapes output at a fixed pace; useful when downstream work must remain uniform.
Production policy
The algorithm is the easy part.
A limiter remains trustworthy only when identity, topology, failure, and observability choices match the risk of the protected endpoint.
Key cardinality
Expire idle identities and reject attacker-controlled key dimensions before they create unbounded state.
Fail open or closed
Public reads may preserve availability; login and payment endpoints usually choose stronger protection.
Global or regional
A nearby quota is fast. A global promise is stricter. Making both claims at once requires coordination.
Measure decisions
Observe admissions, rejections, storage latency, failures, fairness, and key growth without logging raw identity.
modeled atomic decision
local restored = math.min(capacity, tokens + elapsed * refill)
local allowed = restored >= cost
local remaining = allowed and (restored - cost) or restored
redis.call('HSET', key, 'tokens', remaining, 'updated_at', now)
redis.call('EXPIRE', key, ttl)
return { allowed and 1 or 0, remaining, retry_after }
Redis guarantees atomic script and Function execution. LimitLine models those semantics; it does not connect to a hosted Redis instance. Redis documentation
HTTP response / current draft shape
HTTP/1.1 429 Too Many Requests
RateLimit-Policy: "default";q=12;w=3
RateLimit: "default";r=0;t=1
Retry-After: 1
The consolidated RateLimit fields shown in the lab follow active IETF draft -11 and are labelled as work in progress. Read the draft
Protect capacity. Preserve trust.
A good rate limiter is predictable to clients, cheap for the service, and boring for the people operating it.