</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 2: Writing the Contract - Requirements (Functional & Non-Functional)

Executive Summary: This section converts Section 1's clarifications into promises a test could verify. We pin the exact meaning of "active between" (half-open events, a closed window, open events included, point queries for free), define the read surface (city-scoped listing, pagination, counts, async exports) and the ingest surface (start, end, correction), and give every non-functional requirement a number, from latency per query class to 5-second freshness and zero loss of acknowledged events. The most important line is the correctness contract, no misses as of as_of, possible duplicates across pages, because it will shape the read and write paths more than any latency target does.

The interviewer caps the marker: "Good questions. So what exactly are we promising?" The interviewer wants requirements someone could be paged on. "Fast" and "accurate" are decoration. "The 'now' query returns its first page in 100 ms at p99, and never omits an event committed before its as_of" is a commitment every later section has to deliver on.

The Functional Contract

Semantics come first, because Section 1 showed the obvious query gets them wrong:

  • Events are half-open intervals [start, end). A ride that ends at exactly 17:10:00 was not active at 17:10:00. Back-to-back rides by one driver hand off cleanly.
  • The query window [qs, qe] is closed, and qe is clamped to now. An event is active in the window iff start <= qe AND (end IS NULL OR end > qs).
  • Open events count. A ride still in progress is returned with end_ts: null.
  • A point query is just qs = qe. "Who was riding at exactly 17:20:00?" needs no separate endpoint.

Run the running example through those rules. The safety-ops query is SF, 17:10:00Z to 17:40:00Z, executed at 17:45:00Z:

Ride Interval Verdict Rule that decides it
Maya's trip_8f3a 16:52:10Z – 17:31:45Z Included start ≤ 17:40 and end > 17:10. The naive start BETWEEN query misses it
trip_c41e 17:38:20Z – (open) Included, end_ts: null start ≤ 17:40 and end IS NULL
trip_77d0 … – 17:09:59Z Excluded end ≤ qs

Then the operations:

  1. List active events: required city, required [qs, qe], optional type filter. Returns full event records, open events included.
  2. Paginate: default and maximum page size 1,000, using an opaque cursor. SF's busy half hour returns ≈ 25,000 rides, which is 25 pages.
  3. Count: the same parameters with no payload.
  4. Async export: anything past the synchronous ceilings (more than 250K estimated rows, a window longer than 7 days, or a lookback beyond 90 days) becomes a job rather than a request.
  5. Ingest: accept start, end and correction for each event. About 5% of events get a later correction (an end time adjusted, or a cancellation), so corrections are a normal input, not an edge case.
  6. Generic event types: rides are the first tenant, but the contract is keyed by type, so Eats deliveries or scooter rentals can join without a new service.

The Pushback: "Why make city mandatory? Ops will want 'all rides worldwide, right now.'"
You: "Worldwide at peak is about a million open rides. That isn't a list anyone reads. It's an aggregate, and aggregates over time get a separate stream of +1 on start and −1 on end, per city per minute, written into an OLAP store. Scanning intervals to answer 'how many, every minute, worldwide' is the wrong tool. A mandatory city also lets each city live in one home region. A real multi-city list goes through the export path."

Quick check before moving on:


Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.