Real-Time Backend

Design: Live Auction

USD 69 million for a JPG file, and the whole sum landed in the last 20 minutes of trading. Christie's online Beeple auction in 2021: the system processed bids in real time while millions watched. One bug in the bidding engine and the largest deal in the history of digital art could have become a scandal.

  • eBay: 1.4B active listings, proxy bidding has run since 1995. The mechanism has not changed in 30 years, only the scale has
  • Christie's online auction 2021: a Beeple NFT sold for USD 69 million, the last 20 minutes were an avalanche of bids, soft close extended the timer many times
  • Sotheby's BidNow: a platform with anti-sniping (2-minute extension on a bid in the last 2 minutes), running physical and online trading at the same time
  • A scarce item at USD 0.01: when Amazon or Sony run a flash sale, race conditions in a naive system can lead to thousands of buyers 'winning' at the same time

Auction platform architecture

eBay carries 1.4B active listings at the same time. Behind every auction sits a system where 200 ms of latency can cost the win and the platform's reputation. The architect's task: keep bid consistency at peak load without locks on hot lots.

Key components

Auction State in Redis is the system's hot spot. Every bid operation goes through it. To rule out race conditions a Lua script is used: an atomic compare-and-set (CAS) guarantees a bid is accepted only if it beats the current one.

WebSocket is the standard for live auctions. Sotheby's BidNow and Christie's use persistent connections: the client receives price updates instantly, no polling. With 50,000 simultaneous watchers on one lot that is critical.

ComponentTechnologyWhy
Auction stateRedis clusterSub-ms latency, atomic Lua scripts
Client connectionsWebSocket + sticky sessionsPersistent duplex, notification fan-out
Bid auditPostgreSQL (append-only)ACID, history for disputes
Notification fan-outRedis Pub/Sub or KafkaScalable broadcast to every watcher

Why does the bid acceptance run through a Lua script on Redis rather than via standard GET + SET commands?

Bidding Engine: processing bids

Proxy bidding is the mechanism eBay has used since 1995 and which still drives trust in the platform. The participant declares a maximum amount, the system automatically outbids competitors by the minimum increment, and reveals the real maximum only if it is exceeded.

Proxy Bidding: the algorithm

How proxy bidding works in practice

The lot starts at USD 100. Participant A sets a maximum of USD 500. The system bids USD 100 on their behalf. Participant B bids USD 200. The system automatically bids USD 210 (USD 10 increment) for A. Participant C bids USD 550 and wins. The system has revealed that A's max was USD 500. Result: A lost at USD 550, even though their real max was USD 500.

Bid increment: a dynamic ladder

Price rangeMinimum increment
USD 0 to USD 99USD 1
USD 100 to USD 999USD 5
USD 1,000 to USD 9,999USD 25
USD 10,000 to USD 99,999USD 100
USD 100,000+USD 500

Christie's online auction for the Beeple NFT set a record: USD 69 million. The system processed bids seconds apart while millions watched at the same time. The bidding engine has to guarantee bid order even under network glitches, via sequence numbers and idempotency keys.

An idempotency key protects against duplicate bids on retry. The client generates a UUID for each bid. If the network drops and the request is retried, the server recognizes the duplicate by the key and returns the result of the original request.

A participant set a proxy bid of USD 300 at a current price of USD 100. A competitor bids USD 250. What price will the system show?

Anti-sniping: defense against the last second

Sniping is a bid in the last 2 to 5 seconds of an auction, when competitors do not have time to respond. It is not a bug, it is a feature of any system with a hard deadline, and at the same time a core fairness problem. eBay long avoided fighting sniping, treating it as part of the game. Today most platforms implement soft close.

Soft Close: extending the timer

Sotheby's BidNow extends the auction by 2 minutes on every bid in the last 2 minutes, up to 10 extensions. This turns a hard deadline into a sliding window. The auction ends only when nobody bids for 2 minutes straight.

Sniping detection: server time

Critical point: every timestamp has to be generated on the server. If a client can tamper with a bid's timestamp, the system is broken. A bid is considered accepted at the moment it is received on the server, not when the client sent it.

  1. The client sends the bid with a client-timestamp (network diagnostics only)
  2. The server records server-received-at on receipt
  3. Comparison with auction.endsAt uses server-received-at
  4. Bids received after endsAt are rejected with code AUCTION_ENDED
  5. Edge case: a bid in flight at the moment of end is accepted if received-at <= endsAt

An auction is configured with soft close: 5-minute extension on a bid in the last 3 minutes, max 10 extensions. A participant bids 90 seconds before the end. Four minutes later another participant bids. What happens?

Fairness: integrity and consistency

Fairness in auctions is not just ethics. It is a survival requirement: a platform where participants feel cheated loses trust faster than it can grow. Two main threats: technical (race conditions, clock skew) and behavioral (bid shielding, shill bidding).

Technical fairness problems

  • Clock Skew — Servers in the cluster have different system clocks (typically +/- 100 ms). Bids from different nodes can receive the same timestamp. Fix: Lamport timestamps or a centralized sequence generator, a monotonically increasing counter that does not depend on wall clock.
  • Network Latency Inequality — A participant with a low-latency connection has an edge over one with a high-latency connection. Platforms from different regions receive bids with different delays. Partial fix: geo-distributed bid intake nodes, but full equality is unreachable.
  • Last-write-wins conflicts — On simultaneous bids at the same price, the one that landed first on the master node wins. Alternative: a tie-breaking rule (lower userId wins at the same price and timestamp). It is deterministic and auditable.

Bid shielding and shill bidding

Audit and dispute resolution

  • Every bid is written to an append-only log with a server-timestamp and a Lamport clock
  • Bid history is immutable: neither admin nor system can modify a record
  • A participant can request the full bid log for any lot (transparency)
  • The winning bid is confirmed with a cryptographic signature of the final state
  • Dispute resolution SLA: Christie's and Sotheby's guarantee a response within 24 hours

An immutable audit log is not just about fairness, it is also legal protection. In a court dispute about an auction result (especially for USD 1M+ lots) the platform has to provide a full chronology of bids with verifiable timestamps.

Fairness in an auction comes from a simple rule: 'first bid wins', whoever was fastest takes it

In a distributed system 'first bid' is undefined without causal ordering. A 100 ms clock skew makes the physical clock an unreliable criterion. You need Lamport timestamps or centralized sequence numbers.

In multi-node systems there is no shared notion of 'at the same time'. Bids that look simultaneous to different clients can land on different cluster nodes in different orders. Without causal ordering fairness is technically unreachable.

Two participants bid USD 1,000 at the same time (50 ms apart on the wire). Which mechanism guarantees a deterministic and auditable winner?

Takeaways

  • Atomicity is the foundation: compare-and-set through Redis Lua scripts rules out race conditions on auction hot spots
  • Proxy bidding hides a participant's real maximum and automatically outbids competitors by the minimum increment
  • Anti-sniping via soft close turns a hard deadline into a sliding window, the auction ends only on a pause in activity
  • Fairness requires causal ordering (Lamport timestamps) and an immutable audit log. Without them honesty is technically unreachable

Related topics

A live auction platform is built on core distributed-systems patterns:

  • Distributed Consensus — Lamport timestamps and causal ordering are a direct application of distributed clocks theory to bid conflict resolution
  • WebSocket and real time — Fan-out of new bid notifications to every watcher, the classic use case for persistent duplex connections
  • Redis and atomic operations — Lua scripts in Redis as a compare-and-set mechanism for the auction's hot state, the foundation of system correctness
  • Rate Limiting — Velocity checks for fraud detection and DDoS protection against fake bids, a standard defense layer

Вопросы для размышления

  • An auction platform caps anti-snipe extensions at 5. What trade-offs between fairness and UX does that create? How does participant behavior shift?
  • Proxy bidding hides a participant's maximum, but what if the platform technically has access to that data? Which architectural mechanisms prevent staff from abusing it?
  • When building Christie's online auction: how do you test anti-sniping logic and fairness mechanisms without the ability to reproduce the real traffic of a USD 69 million lot?

Связанные уроки

  • sd-01-intro
Design: Live Auction

0

1

Sign In