</> 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 4: Three Calls and a Refusal - API Design (with Pushback)

Executive Summary: This section writes the generator's contract: an internal gRPC service with three calls (NextId, NextIds with a batch of up to 1,000, and Decode), a thin HTTP/JSON gateway that returns IDs as strings, and exactly one interesting error, UNAVAILABLE, which the server returns instead of ever handing out an ID it can't vouch for. Then the interviewer pushes on every choice: why a service and not a library, whether batching breaks ordering, why a number travels as a string, why there is no idempotency key, and why the timestamp isn't returned as its own field. The contract is small because Section 3's arithmetic says the hard part is rate, not features.

The interviewer taps the bit-budget diagram from Section 3: "Fine, you can mint a million a second on paper. What does a caller actually call?" You begin with who the caller is, because that decides the shape. The caller is never a human. It is the messaging service, the orders service, the payments service, each one asking for an ID on the write path of every record. So the API should be boring, fast, and impossible to misuse.

service IdGenerator {
  rpc NextId(NextIdRequest)   returns (NextIdResponse);   // one ID
  rpc NextIds(NextIdsRequest) returns (NextIdsResponse);  // count: 1..1000
  rpc Decode(DecodeRequest)   returns (DecodeResponse);   // debugging only
}

message NextIdResponse  { int64 id = 1; }
message NextIdsRequest  { uint32 count = 1; }           // > 1000 -> INVALID_ARGUMENT
message NextIdsResponse { repeated int64 ids = 1; }      // ascending
message DecodeResponse  { int64 timestamp_ms = 1;        // Unix ms, epoch already added back
                          uint32 region = 2; uint32 worker = 3; uint32 sequence = 4; }

"Notice what the request does not carry," you say. "No caller name, no entity type, no region, no hint about which table the ID is for. The generator doesn't need to know. An ID for a payment and an ID for a chat message are the same kind of object: 64 bits that will never be issued again."

The Hot Path: Client Library and Prefetch

Callers don't speak this protocol directly. They link a thin client library whose public surface is a single function, nextId(), that returns from a local buffer. The library talks to the service with NextIds in the background:

  • The buffer holds 100 IDs by default and is refilled when it drops to half.
  • Any buffered ID older than 1 s is discarded, never handed out. That keeps the "sorting by ID approximates creation order within about a second" promise from Section 2.
  • With a full buffer, a caller using up to ~100 IDs a second rides out a generator blip of up to about 1 s without noticing.

Here's the common case for a caller with a warm buffer. The messaging service in eu-west calls nextId(), and the library answers from IDs worker 17 handed it in an earlier refill:

Sequence: the messaging service calls nextId() and the client library returns a buffered ID with no network; when the buffer drops to 50 of 100 the library calls NextIds(count=50) on generator worker 17 in eu-west and gets 50 ascending IDs; IDs older than 1 s are dropped, never served; the next nextId() is again served from the buffer

The point of the picture is the first return arrow. The common case touches no network at all, so the p99 ≤ 2 ms service SLO from Section 2 is the cost of a refill, not of every write. Leo's own message hit a cold buffer, so his ID was minted on the spot; Section 6 traces that slow path.

Key Insight: The API callers program against is not the RPC. It is a local function backed by a buffer. Most of the latency and availability budget is won in the client library, before a packet leaves the host.

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.