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.

24 components, 21 connections, 12 steps. Updated 4 November 2026.

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.

  1. 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.

    Components Listing Service, Seller App, Listing DB, Media StoreVia create listing

  2. 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.

    Components Search Index, API GatewayVia index

  3. 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.

    Components Bid Service, Bidder AppVia place bid

  4. 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.

    Components Auction State DBVia conditional update

  5. 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.

    Components Bid ServiceVia conditional update

  6. 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.

    Components Bid LogVia bid accepted

  7. 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.

    Components Update Fan-out, Auction ChannelsVia consume

  8. 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.

    Components Live Gateway, Auction ChannelsVia price update

  9. 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.

    Components Notification ServiceVia outbid events

  10. 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.

    Components Closing SchedulerVia close auction

  11. 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.

    Components Settlement Service, Payment Provider, Notification ServiceVia auction closed

  12. 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.

    Components Fraud Checker, Analytics StoreVia consume

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.

Online auction: sequence diagram of the walkthroughAPI GatewayListingsClientsBiddingReal-timeUpdatesClosingAnalytics Storecreate listing1HTTPS1write1photos1index2search2place bid3HTTPS3conditional update4conditional update5bid accepted6consume7publish price7price update8deliver8outbid events9close auction10auction closed11charge11won / sold11consume12load12

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.

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.