Marketplaces, an interactive architecture walkthrough
Online auction: how the architecture works
How an online auction serializes concurrent bids with conditional updates, streams price changes to watchers, and closes auctions on time.
This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate.
Interactive diagram
Overview
An online auction lets sellers list items with an end time and lets many bidders compete, with the highest valid bid winning when the auction closes. The hard part is concurrency on a single item: in the final minutes many bids arrive at once, and exactly one must win each race. This design keeps one row of current state per auction and applies every bid as a conditional update on that row's version, so concurrent bids are serialized without a global lock.
Accepted bids are appended to a log partitioned by auction, which feeds real-time price updates to watchers over WebSockets, outbid notifications, fraud checks and analytics. Proxy bidding stores each bidder's private maximum and raises their bid automatically. A scheduler closes auctions with the same conditional update, and settlement charges the winner. This is a simplified learning design, not any company's production system.
Trade-offs and what changes at scale
Optimistic updates on one row per auction are simple and correct but limit a single auction to the write rate of one row, which is enough for almost every auction; extreme cases move an auction's bidding into a single in-memory owner fed by an ordered queue. Live updates are best effort, so clients refresh state on reconnect. Extending the end time after late bids reduces sniping but makes closing times less predictable. At larger scale auctions are partitioned by id, since bids never span auctions.
How it works, step by step
The walkthrough above, as text. Each step lights up the components named under it.
A seller lists an item through the Listing Service with photos, a starting price, an optional reserve and an end time. Photos go to object storage and the listing row to the Listing DB.
The listing is added to the Search Index, where bidders find active auctions by keyword, category and time left. The index shows the current price only approximately; the auction page reads the live value.
A bid reaches the Bid Service, which checks that the auction is open, the bidder is not the seller and the amount meets the minimum increment. Rejecting bad bids before touching shared state keeps contention low on hot auctions.
The bid is applied with a conditional update to the auction's row in the Auction State DB: set the new price and leader only if the version is unchanged and the auction has not ended. If two bids race, one update fails and that bid is re-evaluated against the new price.
With proxy bidding, a bidder stores a private maximum and the Bid Service raises their bid by one increment whenever someone else outbids them, up to that maximum. Only the second-highest maximum plus an increment is ever shown as the price.
Every accepted bid is appended to the Bid Log, keyed by auction id so each auction's bids stay in order. The log is the audit trail when a bidder disputes the result.
The Update Fan-out consumes the log and publishes the new price on the auction's channel in Auction Channels. Bid handling never waits on the many viewers who want to see the change.
The Live Gateway pushes the update to everyone watching the auction over a WebSocket. Channel messages can be missed, so a reconnecting client reloads the current price before trusting new pushes.
When a bidder loses the lead, the Notification Service sends an outbid alert, and it sends "ending soon" reminders to watchers. Alerts come from the log, so a slow push provider never delays bidding.
At the end time, the Closing Scheduler marks the auction closed with the same conditional update, so no bid can commit after it. If a bid arrives in the last minutes, the end time can be extended to stop last-second sniping.
The Settlement Service checks the reserve, creates the invoice and charges the winner through the Payment Provider. If payment fails, the item can be offered to the next-highest bidder.
The Fraud Checker looks for patterns such as accounts linked to the seller bidding up their own item. Bids also load into the Analytics Store for price history.
Sequence diagram
The same walkthrough as a UML sequence diagram, one lane per layer or group (19 components in all), left to right in the order a request reaches them, numbered by step. A loop on a lane is a step that stays inside that group. Solid arrows are synchronous calls, dashed are asynchronous.
Key components
Clientslayer
- Bidder App: watch, bid, set maximum bids
- Seller App: list items, set reserve and end time
Listingsdomain
- Listing DB: items, reserve, start and end times (postgresql)
- Listing Service: create and edit auctions
- Media Store: item photos (s3)
- Search Index: active auctions by keyword and category (elasticsearch)
API Gateway
- API Gateway: auth, per-user bid rate limits
Biddingdomain
- Auction State DB: current price, leader, version per auction (postgresql)
- Bid Log: every accepted bid, per auction in order (kafka)
- Bid Service: validates and places bids
- Fraud Checker: shill bidding and account patterns
Real-time Updatesdomain
- Auction Channels: one channel per auction (redis)
- Live Gateway: pushes price changes to watchers (websocket)
- Update Fan-out: publishes new prices per auction
Closingdomain
- Closing Scheduler: closes auctions at their end time
- Notification Service: outbid, won, ending soon
- Payment Provider: charges the winner
- Settlement Service: winner, invoice, payment
Analytics Store
- Analytics Store: bid history and prices (clickhouse)
Sources
Public writing this explainer draws on. Read these for what the real systems actually do.
Make it yours
Copy this diagram and its walkthrough into your own workspace, then change anything: swap Postgres for DynamoDB, add a cache, rewrite the narration. Free, and it uses no AI credits.
Related walkthroughs
- Ride-hailing platformHow a ride-hailing platform streams driver locations, matches a rider to a nearby driver, prices the trip with surge, and takes payment.
- Ticket booking with seat reservationHow a ticketing system sells each seat once under heavy demand: waiting room, cached seat map, time-limited holds, conditional updates and safe payment.
- E-commerce checkout and inventoryHow an online store turns a cart into an order: stock reservation, idempotent payment, a saga with compensation, and reliable order events.
This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate. Real systems differ in the details. Browse the library.