Why Twitter tweet IDs look like Snowflakes and what that costs you
Twitter uses Snowflake-style 64-bit IDs to generate globally unique tweet identifiers without a central bottleneck, trading perfect ordering for scalability and rough chronological sort.
21 Apr 2026, 12:56 UTC

Tweet IDs need to be globally unique, generated at massive scale, and roughly ordered by creation time. A central counter would be a bottleneck and a single point of failure. Twitter's practical decision was Snowflake: a 64-bit integer built from time, worker, and a per-millisecond sequence, so IDs can be minted locally without coordination while still sorting roughly chronologically.
What a Snowflake ID is made of
Snowflake is a 64-bit integer. In the widely described layout the high bits are a millisecond timestamp offset from a custom epoch, followed by a worker or machine identifier, and low bits are a sequence counter.
Epoch means a fixed start point for the clock. The timestamp is not Unix time; it is milliseconds since that custom epoch. That makes numeric comparison meaningful only within the same epoch configuration.
Worker ID lets the system scale horizontally across machines and data centers. Each generator is assigned a unique worker ID. The sequence counter provides up to 4096 IDs per millisecond per worker, handling bursts without blocking.
The rough time ordering comes from the timestamp occupying the most significant bits. Within the same millisecond, ordering is by worker ID then sequence. This avoids an extra index for timelines and range scans.
How the parts are extracted
Decoding is bit manipulation: shift right and mask. The exact masks depend on the bit allocation used by the deployment.
# Conceptual decode, run locally with no permissions needed
# Replace EXAMPLE_ID with a real 64-bit tweet ID you are inspecting
EXAMPLE_ID = 0
TIMESTAMP_SHIFT = 22
WORKER_SHIFT = 12
SEQUENCE_MASK = (1 << 12) - 1
WORKER_MASK = (1 << 10) - 1
sequence = EXAMPLE_ID & SEQUENCE_MASK
worker_id = (EXAMPLE_ID >> WORKER_SHIFT) & WORKER_MASK
timestamp_ms = (EXAMPLE_ID >> TIMESTAMP_SHIFT) & ((1 << 41) - 1)
This shows the structure without claiming a specific decoded value. Risks: using the wrong shifts or epoch will produce nonsense. Do not use decoded timestamps for security or billing decisions; they are approximate.
A practical check is to compare public tweet IDs over time. Sequential posts from the same account typically show monotonic increase and millisecond spacing that grows with activity. That is a sanity check, not proof of internal layout.
Operational trade-offs and limits
Clock skew or backward jumps are dangerous. If a worker's clock moves back, the generator must stall until the clock catches up, otherwise duplicate IDs can appear. Monotonic clocks and safeguards are required.
Worker ID space is finite. With 10 bits there are 1024 workers per allocation scheme. Allocation needs to be stable across restarts and rebalancing to avoid collisions.
The 41-bit timestamp gives a long lifespan relative to the custom epoch, but it is finite. Once the epoch window is exhausted, IDs stop being safe. That is a design horizon to plan for.
Ordering is only rough. Different workers can generate IDs out of true wall-clock order if their clocks differ slightly. For strict total order you still need an external sequencer.
Takeaway for your own design
If you need distributed unique IDs with best-effort time ordering, a Snowflake-style scheme is a proven pattern. Keep the epoch explicit, enforce monotonic clocks per generator, and treat worker IDs as durable infrastructure state.
Verify behavior in your environment by logging generated IDs, checking monotonic increase per worker, and simulating clock skew in a test harness before relying on ordering for user-visible timelines.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.