Auctions, Ticketing, And Real-Time Messaging
Asked of: Software Engineer
Last updated
What's being tested
These prompts test whether you can design low-latency, high-concurrency distributed systems where many users observe or mutate the same shared object in real time. For auctions and ticketing, the hard part is preserving correctness under contention: one winning bid, one ticket allocation, no oversells, deterministic ordering, and recoverable state transitions. For messaging, the emphasis shifts toward delivery semantics, fanout, presence, and multi-device synchronization. Meta cares because many product surfaces combine real-time updates, massive fanout, partial failures, abuse pressure, and user-visible latency; a strong SWE should reason clearly about APIs, storage, sharding, consistency, and operational tradeoffs.
Core knowledge
-
Clarify the consistency boundary early. An auction’s highest bid or a ticket seat allocation usually needs strong consistency per auction, listing, or event; global strong consistency is unnecessary. The common design is “single-writer per hot entity” using a shard leader, partition lock, or transactional row update.
-
Model the write path around invariants, not just entities. For auctions:
Auction(id, seller_id, status, end_time, current_price, version),Bid(id, auction_id, bidder_id, amount, ts, status). The invariant is: accepted bid amount must exceed current price and auction must be open. Useversionor compare-and-swap. -
Optimistic concurrency control works well for moderate contention:
UPDATE auctions SET current_price=?, version=version+1 WHERE id=? AND version=? AND status='OPEN'. If the update count is zero, retry or reject. Under extreme contention, move to a per-auction serialized command queue. -
Partition by contention domain. For auctions, shard by
auction_id; for chat, shard byconversation_id; for tickets, shard byevent_idorsection_id. This keeps ordering local. A single partition can handle thousands to tens of thousands of ops/sec, but celebrity auctions may need special handling. -
Ordering is scoped, not universal. Use a monotonically increasing sequence number per auction or conversation, e.g.
bid_seqormessage_seq. Wall-clock timestamps are useful for display but unsafe for correctness because clocks skew and retries reorder requests. -
Real-time push typically uses WebSockets, Server-Sent Events, or mobile push notifications.
WebSocketssupport bidirectional low-latency updates; SSE is simpler for server-to-client streams. For disconnected clients, store durable events and resume fromlast_seen_seq. -
Delivery semantics should be explicit. Most real systems provide at-least-once delivery plus client-side deduplication using
message_id,bid_id, or an idempotency key. Exactly-once end-to-end is usually too expensive; exactly-once effects are achieved by idempotent writes and sequence checks. -
Fanout strategy depends on group size. For small chats or auction watchers, fan out updates directly to connected sessions. For large rooms or popular auctions, publish once to a broker such as
Kafka,Pulsar, orRedis Streams, then have gateway nodes pull and push to local connections. -
Hot keys are the central scaling risk. A viral auction, concert ticket drop, or large group chat can overload one shard. Mitigations include queueing, rate limits, per-user throttles, read replicas for state snapshots, batching updates, or subdividing inventory by section/block when correctness allows.
-
End-of-auction logic must be deterministic. Do not rely on a best-effort timer alone. Store
end_time, reject bids with server receive time after close, and run a closing job that transitionsOPEN -> CLOSING -> CLOSED. Late bids should have clear semantics: rejected, grace-period accepted, or anti-sniping extension. -
Ticketing introduces reservation leases. A seat can move
AVAILABLE -> HELD -> PURCHASEDwith a TTL, often 5–10 minutes. Use transactional updates or conditional writes to prevent oversell, and have an expiration worker release abandoned holds. Payment completion must be idempotent. -
Backpressure and degradation are design features. Track
p50,p95,p99latency, queue depth, droppedWebSocketconnections, retry rate, and accepted/rejected bid counts. Under overload, degrade by slowing reads, batching notifications, or rejecting low-priority requests before corrupting state.
Worked example
For Design an online auction platform, start by asking: are bids ascending only, is there a fixed end time, do we support automatic proxy bidding, what is the target scale, and what latency is expected for bid visibility? A strong assumption set might be: millions of users, thousands of active auctions, p99 bid acceptance under 200 ms, strong correctness per auction, and eventual consistency for watcher notifications.
Organize the answer around four pillars: data model, bid acceptance path, real-time propagation, and failure handling. The write path could route POST /auctions/{id}/bids through an API service to the shard owning auction_id, where a transaction checks auction state, compares amount against current_price, writes a durable bid row, increments bid_seq, and updates the auction snapshot. After commit, the service publishes BidAccepted(auction_id, bid_seq, amount) to a stream consumed by WebSocket gateway nodes.
The key tradeoff to call out is optimistic concurrency versus serialized command processing. Optimistic updates are simple and fast when contention is low, but a celebrity auction may cause heavy retries and tail latency; a per-auction queue or actor model serializes commands and gives deterministic ordering at the cost of queueing delay. Close by saying that, with more time, you would cover anti-abuse rate limits, seller/buyer trust controls, payment escrow, and observability around hot auctions and delayed fanout.
A second angle
For Design a real-time messenger, the same real-time infrastructure appears, but the correctness boundary changes from “one highest bid” to “ordered message history per conversation.” Instead of rejecting conflicting writes, the system assigns each accepted message a per-conversation message_seq and persists it before fanout. Delivery can be at-least-once, because duplicate messages can be removed by message_id; auctions cannot tolerate duplicate accepted bids changing state. Messaging also needs multi-device sync, read receipts, offline storage, and presence, while auctions focus more on contention control, close-time semantics, and state transitions.
Common pitfalls
Pitfall: Designing the system as if
Kafkaordering solves bid correctness.
A broker can preserve order within a partition, but it does not by itself enforce “bid must be higher than current price” or “auction must still be open.” Correctness belongs in the state transition layer: a transaction, compare-and-swap, single-writer actor, or conditional write around the authoritative auction record.
Pitfall: Jumping straight into components without defining invariants.
A weak answer lists load balancer, cache, database, queue, and WebSocket but never says what must never happen. A stronger answer states invariants first: no accepted bid below current price, no bids after close, no ticket oversell, monotonic sequence numbers, idempotent retries, and recoverable event history.
Pitfall: Treating real-time push as the source of truth.
WebSocket messages are a notification path, not durable state. Clients should be able to reconnect with last_seen_seq, fetch missed events from storage, and reconcile their local view with the authoritative auction, ticket, or conversation state.
Connections
Interviewers may pivot from here into rate limiting, idempotency, distributed locking, event sourcing, leader election, or cache invalidation. Ticketing variants often test the same ideas through inventory reservations and payment idempotency, while messaging variants probe delivery semantics, offline replay, and fanout at very large scale.
Further reading
-
Designing Data-Intensive Applications — Martin Kleppmann’s book is the best single source for replication, partitioning, transactions, streams, and consistency tradeoffs.
-
The Log: What every software engineer should know about real-time data’s unifying abstraction — Jay Kreps’ essay explains why ordered logs are so useful for replay, fanout, and recovery.
-
RFC 6455: The WebSocket Protocol — useful background on the protocol commonly used for bid updates, chat delivery, and real-time client sessions.
Featured in interview prep guides
Practice questions
- Design an online auction systemMeta · Software Engineer · Onsite · easy
- Design Real-Time Auctions for Social PostsMeta · Software Engineer · Onsite · medium
- Design ticketing system with seat holdMeta · Software Engineer · Onsite · medium
- Design an online auction platformMeta · Software Engineer · Onsite · medium
- Design an online auction platformMeta · Software Engineer · Onsite · hard
- Design a real-time messengerMeta · Software Engineer · Onsite · hard
- Design a ticketing purchase systemMeta · Software Engineer · Onsite · hard
- Design an online auction systemMeta · Software Engineer · Technical Screen · hard
- Design leaderboard ranking and messenger servicesMeta · Software Engineer · Onsite · hard
- Design leaderboard and messenger systemsMeta · Software Engineer · Onsite · hard
- Design Ticket Booking Auto ReleaseMeta · Software Engineer · Technical Screen · medium
Related concepts
- Messaging, Event Pipelines, and Delivery SemanticsSystem Design
- Real-Time Messaging And Collaboration SystemsSystem Design
- Distributed Systems Consistency And Low-Latency DesignSystem Design
- Slack-Like Messaging SystemsSystem Design
- Adobe Real-Time Collaboration Messaging
- Real-Time Systems, WebSockets, and Long-Lived Connections