How the interviewer opens it
“Design a feature for a large booking site that shows visitors how many other people are looking at the same hotel right now.”
The prompt is vague on purpose. The first few minutes are yours: narrow it to the core features and agree on the numbers before you draw anything.
What to clarify first
- What counts as a viewer?
- Presence lifecycle
- Scale
- Read:write mix and initial request
- Traffic skew
- Latency and freshness
- Consistency and accuracy
- Durability and failures
- Presentation and privacy
- Scope boundaries
The answers stay with the interviewer. In a SysRound round, Alex answers them as an interviewer would.
Scope of a strong answer
Core requirements
- Track active viewers of a canonical hotel page.
- Deduplicate the same viewer across tabs and retries.
- Display the number of other viewers with bounded staleness.
- Expire presence after visitors stop sending updates.
Usually out of scope
- Historical visitor analytics and billing-grade counts.
- Proving that every browser belongs to a distinct human.
- Booking inventory, reservations, and payments.
- Showing viewer identities.
What interviewers probe
- Presence without reliable departures
- A browser can disappear without sending anything. The meaning of 'right now' must therefore be implemented through timeouts, and expiring a hotel key is not the same as expiring individual viewers inside it.
- Distinct viewers rather than tabs or events
- The displayed unit is a person-like identity, but the service receives repeated events from tabs and devices. Increment/decrement schemes drift under retries, missed departures, and overlapping sessions.
- Hot pages and count delivery
- A popular hotel concentrates both membership writes and count reads. Adding service instances does not spread a single hotel-owned key, and pushing every change to every viewer amplifies traffic.
Common mistakes
- Starting with an increment/decrement counter and assuming every arrival has a matching departure.
- Never defining whether a viewer is an account, browser, tab, connection, or IP address.
- Using hotel-level TTLs as though they expire individual viewers, or trusting raw set cardinality despite delayed cleanup.
- Counting tabs or events instead of distinct viewer–hotel pairs.
- Estimating only periodic heartbeats, forgetting immediate registrations, or adding an initial GET without accounting for its extra traffic.
- Ignoring hot-page writes after caching reads, or showing zero when the service is unavailable.
The bar by level
- Mid-level (L4/E4)
- Defines a viewer and a heartbeat timeout, proposes idempotent membership keyed by hotel and viewer, and explains how expired viewers stop contributing. Provides a working registration-and-refresh flow, excludes the current viewer, and keeps feature failure off the main page path.
- Senior (L5/E5)
- Correctly accounts for immediate registrations as well as periodic heartbeats and states whether count reads share those requests. Handles overlapping tabs and retries, separates logical expiry from cleanup, and budgets end-to-end freshness. Uses shared snapshots, addresses a single hot hotel, and explains recovery after ephemeral state loss.
- Staff (L6+/E6+)
- Makes identity and accuracy limits explicit, separates read amplification from hot-key write ownership, and describes a safe path to striped aggregation without double-counting during migration. Can adapt the design to multi-region deduplication or tighter departure latency, explaining coordination, cost, and availability trade-offs rather than promising exact presence.