Design a Distributed Unique ID Generator
1. Problem Statement & Scope Clarification
System Mission
Design a distributed, highly available, low-latency 64-bit unique ID generation service (similar to Twitter Snowflake / Instagram ID generator) capable of generating globally unique, roughly time-sortable 64-bit numeric IDs across multiple data centers and AWS regions with zero runtime inter-node network coordination.
Functional Requirements
- Global Uniqueness: Zero ID collisions across all AWS regions, availability zones, and worker instances over a 70-year operating horizon.
- 64-bit Integer Representation: Must fit inside a standard 64-bit signed integer (
int64/BIGINTin SQL databases) to minimize primary key index bloat and fit cache lines efficiently. - Roughly Time-Ordered (K-Ordered): Chronologically sortable by generation timestamp to prevent database B-Tree index fragmentation and random page splits on insertion.
- High Throughput & Low Latency: Support aggregate throughput per cluster with sub-millisecond () generation latency.
- Batch Generation: Support atomic batch requests (up to 1,000 IDs per call) for high-throughput transactional ingest pipelines.
Non-Functional Requirements (SLAs & SLOs)
- Availability: ("six nines") uptime SLA β ID generation is in the critical path of every write request in an enterprise architecture.
- Latency: , , .
- Clock Drift Safety: Absolute monotonicity within individual worker processes; graceful wait-or-reject semantics if system hardware clock steps backward.
- Client JSON Compatibility: Safe serialization as string for 64-bit unsigned integers to avoid IEEE-754 double precision truncation in JavaScript clients (
Number.MAX_SAFE_INTEGER = 2^{53} - 1).
2. Capacity & Scale Estimation (Back-of-the-Envelope Math)
Traffic & Generation Scale
- Global Average Write QPS: .
- Peak Write QPS ( multiplier): .
- Annual ID Volume:
- Data Footprint for Generated IDs:
Bit-Space Longevity & Allocation Proof
A 64-bit integer is structured into 4 discrete bitfields:
- Sign Bit (1 bit): Fixed to
0to keep the integer strictly positive in signed 64-bit systems. - Timestamp (41 bits): Milliseconds elapsed since a custom epoch (e.g.,
2026-01-01T00:00:00Z= ). The service remains operational until year . - Data Center ID (5 bits): unique data center / AWS region partitions (e.g., 0 =
us-east-1, 1 =us-west-2, 2 =eu-west-1, etc.). - Worker Machine ID (5 bits): unique worker nodes per data center. Total possible concurrent generator instances globally .
- Sequence Number (12 bits): unique IDs per millisecond per individual worker node.
Peak Theoretical Generation Capacity
This capacity exceeds the peak requirement by over , providing massive headroom for multi-tenant enterprise growth.
3. High-Level Architecture & AWS Component Mapping
Interactive Architecture DiagramSynthesizing vector architecture diagram...
4. API Interface Design & ID Structure
64-bit Bitfield Layout
text0 (1 bit) 1...........................41 (41 bits) 42......46 (5 bits) 47......51 (5 bits) 52..........63 (12 bits) +----------+------------------------------------------+---------------------+--------------------+-------------------------+ | Sign (0) | Milliseconds Since Custom Epoch (69 yrs) | DataCenter ID (0-31)| Worker ID (0-31) | Sequence Counter (0-4095)| +----------+------------------------------------------+---------------------+--------------------+-------------------------+
gRPC Service Protocol (id_generator.proto)
protobufsyntax = "proto3"; package hispeeddesign.idgen.v1; service IdGeneratorService { // Generates a single 64-bit unique ID rpc GenerateId (GenerateIdRequest) returns (GenerateIdResponse); // Generates a batch of unique IDs atomically rpc GenerateIdBatch (GenerateIdBatchRequest) returns (GenerateIdBatchResponse); } message GenerateIdRequest { string caller_service = 1; } message GenerateIdResponse { int64 id = 1; // Signed 64-bit representation string id_str = 2; // String representation for JS safe integer parsing int64 timestamp_ms = 3; // Milliseconds since Unix epoch extracted from ID int32 datacenter_id = 4; int32 worker_id = 5; } message GenerateIdBatchRequest { int32 count = 1; // Max batch size: 1,000 string caller_service = 2; } message GenerateIdBatchResponse { repeated int64 ids = 1; repeated string ids_str = 2; int64 epoch_offset_ms = 3; }
5. Data Model & Worker Node Coordination Schema
Worker nodes dynamically acquire a (datacenter_id, worker_id) pair on startup via DynamoDB leases to prevent static configuration drift or duplicate assignments during Kubernetes / ECS auto-scaling.
DynamoDB Schema: WorkerNodeRegistryTable
| Attribute Name | DynamoDB Type | Description |
|---|---|---|
PK (Partition Key) | STRING | DC#<datacenter_id> (e.g. DC#01) |
SK (Sort Key) | STRING | WORKER#<worker_id> (e.g. WORKER#04) |
instance_id | STRING | ECS Task ARN / EC2 Instance ID |
ip_address | STRING | Private IP of the worker daemon |
lease_expiry_ts | NUMBER | Unix epoch in seconds (TTL enabled) |
version | NUMBER | Optimistic locking counter |
Worker Node Lease Acquisition Algorithm
- On container boot, the node discovers its AWS Region and sets
datacenter_id(e.g.,us-east-1= 1). - It loops through
worker_idfrom0to31, attempting a conditionalPutItem:json{ "TableName": "WorkerNodeRegistryTable", "Item": { "PK": {"S": "DC#01"}, "SK": {"S": "WORKER#04"}, "instance_id": {"S": "arn:aws:ecs:us-east-1:123456789:task/worker-04"}, "ip_address": {"S": "10.0.4.182"}, "lease_expiry_ts": {"N": "1767225630"}, "version": {"N": "1"} }, "ConditionExpression": "attribute_not_exists(PK) OR lease_expiry_ts < :now" } - Once claimed, a background daemon heartbeats every 10 seconds, extending
lease_expiry_tsby 30 seconds. - If the worker crashes, its lease automatically expires in 30 seconds, allowing a replacement container to reclaim the slot.
Unlock Complete Architecture & Production Runbooks
You have explored the free architectural preview (~43%). Spend 1 Coin to unlock the remaining 6 production deep-dive sections for a full 24 hours.