task—
ambient traffic · simulated
current platform (V1)V2the task you followcontrol
The 3D view needs WebGL, which is turned off in this browser. The story still reads top to bottom.
Case study · Platform engineering · October 2026
Rebuilding a live API, one key at a time.
The product I work on is an HTTP API that customers send work to around the clock. I designed its next platform, V2, to run beside the current one, with a router in front that moves customers across one API key at a time, and a way back that takes seconds.
Jamal Aldeen · Backend engineer and acting team lead
- 10,000
- requests a second the routers are load-tested to carry, with zero errors
- ≈80M
- new tasks a week behind it
- 10.3M
- requests in the router's first hours live, 0.001% upstream errors
- ≤10 s
- to move a customer to V2, or back
Scroll to follow one task ↓
The problem
The current platform carries every customer, every minute.
It works, and it can't stop. But the next stage needs things it can't prove, and a "big bang" switchover would put every integration at risk in the same minute. So V2 had to keep four promises:
- Exact limits. Never admit one task more than the customer's concurrency plan.
- No lost results. Every accepted task ends exactly once: done, failed or timed out.
- Honest capacity. Grow the fleet with demand, inside a budget, counting only proven workers.
- Reversible moves. Move customers one key at a time. Moving back is instant and has no conditions.
Follow one task · 1 of 8
A customer sends work to the same endpoint as always.
No new SDK and no code change. The request reaches the load balancers customers already use. Everything new sits behind them.
Follow one task · 2 of 8
A small Go router decides who answers.
It hashes the API key and looks it up in a route map it refreshes every 10 seconds. A migrated key goes to V2. Every other key goes to the current platform, exactly as before. The map holds only SHA-256 hashes, never the keys.
Follow one task · 3 of 8
V2's edge picks the least-busy API server.
Caddy ends TLS and balances across four Laravel Octane servers. A compatibility layer accepts the old request format, so answers come back in the shape the customer's code already parses. The key, the task type and the payload are checked before anything is stored.
Follow one task · 4 of 8
One atomic step decides whether the task gets in.
Each customer's plan allows a set number of tasks at once. A Lua script in Redis counts the customer's live leases, compares them with the limit and, if there's room, creates the task and takes a 300-second lease. All in one step, so four API servers can race and the limit still holds exactly.
Follow one task · 5 of 8
Handed to its queue, with a receipt.
Each of the 14 task types has its own RabbitMQ queue. The publish waits for the broker to confirm it. If the broker refuses, a second script rolls the admission back and frees the slot, so retrying is always safe.
Follow one task · 6 of 8
A worker does the work and touches nothing else.
Workers read only their own type's queue and publish results back. They never connect to the database. The fleet grows and shrinks with demand, and it only counts workers that have proven they are healthy.
Follow one task · 7 of 8
The first result wins. Duplicates are ignored.
Queues redeliver and workers crash, so V2 expects every result to arrive twice. The result consumer validates the message, takes the worker's identity from the authenticated connection, and finalizes through a script guarded by a once-only marker. The customer's slot is released in the same step.
Follow one task · 8 of 8
The answer goes back the way the customer expects.
The customer polls for the result or gets a signed webhook. Webhooks retry after 30 and 120 seconds, then stop in a dead-letter queue where an operator can see them. Nothing retries forever, and nothing disappears quietly.
Now break it
The happy path is easy. Pick a failure.