Grokking the System Design Interview, Volume II
Vote

0% completed

Unique ID Generator: Requirements

Step 2: Clarifying and Defining Requirements

Step 2: Clarifying and Defining Requirements

Functional Requirements:

Functional requirements
Functional requirements
  • Generate Unique IDs on Demand: The system must provide an interface (e.g., a service API) that clients can call to obtain a new unique identifier at any time. Every ID returned must be globally unique - no two calls should ever produce the same ID, even if they come from different services or geographic regions.
  • Support Time-Sortable and Opaque IDs: Clients should be able to request two formats of IDs: (1) a time-sortable ID (an ID which, when compared to others, reflects creation time order), and (2) an opaque ID (an ID which carries no obvious relation to creation time or sequence). This could be exposed via two API endpoints or a parameter (for example, a type field on the request, as Step 4 specifies). Both types must still be globally unique across the entire system.
  • Simple Client API: Provide easy-to-use APIs for services to request IDs. Likely a REST or gRPC endpoint that returns a new ID (or even a batch of IDs) with low overhead. For instance, POST /ids could return a JSON containing a new ID. Supporting batch requests (e.g., ask for 100 IDs in one call) could be useful to reduce call overhead for clients that need many IDs.
  • No Offline Client ID Generation: All ID generation will occur in the centralized service (clients won’t generate their own IDs offline). This simplifies the design – we don’t need to accommodate merging offline-generated IDs or resolving conflicts from offline nodes. Clients must be online and able to reach the service to get an ID.

Non-Functional Requirements:

Non-functional requirements
Non-functional requirements
  • High Throughput: The system should handle hundreds of thousands of ID requests per second. We target at least 100,000 IDs/sec sustained, with the ability to scale beyond (e.g., peak bursts of 200k-500k/sec) by horizontal scaling. Each generator node should handle a large share of this (tens of thousands per second each), and we'll run enough nodes to meet demand.
  • Low Latency: ID generation is a few processor instructions, so almost all of the time a caller waits is network. In region, the service should answer in under 5ms at p99. A client using the library from Step 5 makes no network call and sees microseconds. Treat any p99 above 10ms as a fault rather than a busy period. Nothing in this service does enough work to be slow, so a slow response means a garbage collection pause, a saturated network card, or a node that should be replaced.
  • High Availability & Fault Tolerance: The service must be reliable and highly available - target 99.99% uptime or better. It should have no single point of failure: if a server or even an entire datacenter goes down, ID generation should continue unaffected (perhaps with clients failing over to another region's service). Redundancy and failover mechanisms are essential.
  • Global Consistency: Ensure global uniqueness of IDs across all datacenters/regions. The design must coordinate or partition ID space such that two different regions never produce colliding IDs. We also want consistency in format - e.g., an ID generated in Europe should have the same structure and length as one from the US region.
  • Scalability: The system should scale horizontally. We should be able to add more ID generator instances (in existing or new regions) to increase capacity without major reconfiguration. If traffic doubles, we can deploy more nodes or even introduce new bit partitions (if needed) to handle more IDs. The architecture should accommodate growth in QPS and the number of clients smoothly.
  • Precision and Ordering Guarantees: The time-sortable IDs should preserve insertion order at least within reasonable bounds (i.e., if one ID is created after another, it should usually have a higher sortable value). Minor anomalies due to distributed clocks are acceptable, but generally, the ordering should hold. The system's design (especially for time-sortable IDs) should minimize clock skew issues and handle them gracefully (e.g., if clocks drift or jump, avoid generating duplicates or significant disorder).
  • Maintain ID Size Constraints: Many use-cases prefer IDs that are not too large. The time-sortable IDs will be numeric (we aim for 64-bit, which is efficient for databases). Opaque IDs might be larger (e.g., 128-bit UUID format), but we should avoid excessively large identifiers to reduce storage and indexing overhead.

Next: Step 3, where those requirements become numbers.

On This Page

Step 2: Clarifying and Defining Requirements