Section 6: Eight Boxes and the Queue That Isn't There - High-Level Architecture
Executive Summary: Section 5 put the whole contract on one row; this section draws the boxes around it. Eight carry the system: an API Gateway, a stateless Bid Service, an Auction Store of 32 sharded SQL primaries with synchronous replicas, a 20 GB Hot-State Cache, an Outbox Relay feeding an Event Bus, a 60-node Realtime Gateway, per-shard Closers, and a Notification Service. Four more are borrowed, not built: Identity, Listing, Search, Payments. We trace Elena's Thursday bid through the boxes and land it at roughly 19 ms of a 100 ms server-side budget. Then the scored part: six components every candidate draws by reflex, each refused with a ledger number and a named trigger that would bring it back. The queue is not missing. It is on the other side of the commit.
Section 5 settled the hard thing: an auction is one row that holds the secret maximum, and a bid is an append to a ledger on the same shard. Once you believe that, the architecture is mostly a question of what you can leave out. Draw it small, then defend every gap.
The Eight Boxes
| Box | Its job | Sized by |
|---|---|---|
| API Gateway | TLS, Identity token check, 1 bid/s per bidder per auction (429), idempotency pre-check | 5,000 bids/s plus 35,000 state reads/s at peak |
| Bid Service | Stateless. Stamps accepted_at on ingress, routes by auction_id, runs the accept transaction, returns the verdict |
1.5 MB/s ingress; clock skew under 10 ms or the node stops accepting |
| Auction Store | 32 relational shards by auction_id, each with a synchronous replica in a second availability zone; auction row and bids co-located |
~220 writes/s per shard; 14.5 TB/year, which is why there are shards at all |
| Hot-State Cache | Write-through, best-effort, never blocks the verdict: price, high bidder, bid count, end_time, version. Never the max |
100 M live auctions x 200 B = 20 GB |
| Outbox Relay and Event Bus | Publishes the outbox rows the transaction wrote: bid.accepted, watcher.outbid, auction.closed; feeds the "my bids" projections |
5,000 events/s on the bid stream |
| Realtime Gateway | Holds open item pages, subscribes once per auction with a local viewer, coalesces to 2 updates/s/auction | 2 M viewers at 50,000 connections per node = 40 nodes; run 60 |
| Closer | One worker per shard sweeps (status, end_time) every second, claims OPEN to CLOSING, finalises |
1,600 closes/s in the worst 7 p.m. minute, 50 per shard |
| Notification Service | Consumes the bus: outbid, won, sold | About 10,000 notifications/s in the close burst |
The four external boxes are things we would be reckless to own. Identity hands the gateway a verified bidder. Listing holds the title and photographs of Priya's booster box, none of which sit on the bid path. Search ends where we begin. Payments takes over after the close, because a bid is a binding commitment, not a charge; authorising a card on 5,000 bids a second, mostly for losers, is a cost we decline unless the marketplace takes deposits, as car auctions do.
Key Insight: Only three of the eight boxes sit on the path that carries the 99.99% promise: the gateway, the Bid Service and the Auction Store. The cache, the relay, the bus, the realtime gateway, the closer and notifications run at 99.9% and can each be down for minutes without a single verdict being wrong. Knowing which boxes are allowed to fail is the architecture.
Quick check before moving on:
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson