SysDesignPrep.com
Interactive concepts

Snowflake IDs: an interactive unique ID generator

A Snowflake ID is a 64-bit unique ID that any machine can generate on its own, with no database round trip and no coordination: a timestamp in milliseconds, then the machine’s number, then a counter for IDs made in the same millisecond. The IDs fit in a BIGINT, sort roughly by creation time, and each machine can make 4,096 of them every millisecond. Twitter introduced the scheme in 2010; Discord, Instagram and many others use variants of it.

The playground has three machines generating IDs for ten milliseconds. Click any ID to see its bits, then try a burst bigger than the sequence allows and a clock that jumps backwards.

Three machines make IDs every millisecond. Each puts its own machine number in its IDs, so they never collide and never need to talk to each other. Sorting the IDs sorts them by time, roughly: machine B’s clock is 2 ms ahead of the others, so its IDs sort as if they were made 2 ms later. IDs are ordered within one machine and only approximately across machines.

371945845576175616as a 64-bit number
0 00001010010100101101010110001101010000101timestamp, 41 bits0000000001machine, 10 bits000000000000sequence, 12 bits
time 09:00:00.005 UTC, 88,678,800,005 ms since the epochmachine 1 (A)sequence 0
ID, in sorted orderMachineMade atTimestamp in the IDSequence
371945845567787008A3 ms3 ms0
371945845567795200C3 ms3 ms0
371945845571981312A4 ms4 ms0
371945845571989504C4 ms4 ms0
371945845576175616A5 ms5 ms0
371945845576179712B3 ms5 ms0
371945845576183808C5 ms5 ms0
371945845580369920A6 ms6 ms0
371945845580374016B4 ms6 ms0
371945845580378112C6 ms6 ms0
371945845584564224A7 ms7 ms0
371945845584568320B5 ms7 ms0
371945845584572416C7 ms7 ms0
371945845588762624B6 ms8 ms0
371945845592956928B7 ms9 ms0
IDs made90in 10 ms, by 3 machines
Duplicates0every ID unique
Per machine, per ms4,096at most, from 12 sequence bits
Timestamps last69 years41 bits of milliseconds from the epoch

Epoch 1 January 2024; the playground’s clock starts at 09:00:00.000 UTC on 23 October 2026. Click a row to see its bits.

How a Snowflake ID is built

BitsFieldWhat it gives
1SignAlways 0, so the ID is positive in signed 64-bit types
41Milliseconds since a custom epochAbout 69 years of IDs, and sorting by time
10MachineUp to 1,024 generators that never collide
12Sequence4,096 IDs per machine per millisecond, about 4 million a second

Choosing a recent epoch rather than 1970 matters: 41 bits of milliseconds from 1970 would run out in 2039. The split can be tuned. Instagram’s version, generated inside PostgreSQL, uses 41 bits of time, 13 bits of logical shard and 10 bits of sequence.

Unique without coordination

Two machines can never produce the same ID, because their machine bits differ, and one machine never repeats itself, because within a millisecond the sequence increases and across milliseconds the timestamp does. The only thing that needs coordinating is handing out machine numbers once, at startup: from configuration, or from a lease in ZooKeeper or etcd so a number is never used by two live processes at once.

The trouble with clocks

The scheme trusts each machine’s clock, and clocks misbehave. If a clock is stepped backwards, a generator that trusts it reuses timestamps and, starting the sequence again, repeats IDs it has already given out: 9 duplicates in the last preset. A generator must remember the last timestamp it used and wait, or refuse, until the clock passes it. Clocks on different machines also drift apart, so IDs are ordered exactly within one machine but only roughly across machines: with one clock 2 ms fast, its IDs sort as if they were made 2 ms later. That is enough for “newest first” feeds, and not enough to decide which of two events on different machines happened first.

Snowflake IDs vs UUIDs vs auto-increment

SnowflakeUUIDv4UUIDv7Auto-increment
Size64 bits128 bits128 bits32 or 64 bits
Sorts by timeRoughlyNoRoughlyYes, on one server
CoordinationMachine numbers, onceNoneNoneOne database hands them all out
Index insertsMostly at the endRandom, all over the indexMostly at the endAt the end
RevealsCreation time, machineNothingCreation timeHow many rows exist

UUIDv7, standardised in RFC 9562 in 2024, puts a 48-bit millisecond timestamp in front of random bits, so it sorts by time like a Snowflake ID without needing machine numbers, at twice the size. Random UUIDv4 keys scatter inserts across a B-tree index, which hurts write performance and caching on large tables.

A Snowflake generator in code

import threading, time

EPOCH_MS = 1_704_067_200_000            # 1 January 2024

class Snowflake:
    def __init__(self, machine_id: int):
        assert 0 <= machine_id < 1024    # 10 bits, assigned so no two machines share one
        self.machine, self.last, self.seq = machine_id, -1, 0
        self.lock = threading.Lock()

    def next_id(self) -> int:
        with self.lock:
            now = int(time.time() * 1000)
            if now < self.last:          # the clock went backwards: wait rather than repeat
                time.sleep((self.last - now) / 1000)
                now = self.last
            if now == self.last:
                self.seq = (self.seq + 1) & 4095
                if self.seq == 0:        # 4,096 used this millisecond: wait for the next
                    while now <= self.last:
                        now = int(time.time() * 1000)
            else:
                self.seq = 0
            self.last = now
            return ((now - EPOCH_MS) << 22) | (self.machine << 12) | self.seq

In a system design interview

When a design needs IDs for posts, messages or orders across many servers, say how they are made: “Each service instance generates 64-bit Snowflake IDs locally, with a machine number leased from etcd at startup. They fit a BIGINT column, need no database round trip, and sort by time, so ‘newest first’ is an index scan on the primary key.” Expect the follow-ups: what happens when a clock goes backwards, how machine numbers are reused safely, and whether exposing creation time in the ID matters.

Read the guide to unique IDs and time, see composite indexes for why time-ordered keys index well, or watch a strong candidate design a unique ID generator.

Questions people ask

What is a Snowflake ID?

A 64-bit unique ID made of a timestamp in milliseconds since a chosen epoch (41 bits), the number of the machine that generated it (10 bits) and a sequence number for IDs made in the same millisecond (12 bits). Twitter introduced the format in 2010 so that any server could generate IDs without coordinating.

How many IDs can a Snowflake generator produce?

With 12 sequence bits, 4,096 per machine per millisecond, about 4 million a second per machine, and with 10 machine bits up to 1,024 machines. When a machine uses up its sequence within a millisecond, it waits for the next millisecond before issuing more.

How long do Snowflake IDs last?

41 bits of milliseconds cover about 69.7 years from the chosen epoch. That is why implementations use a recent custom epoch rather than 1970: counting from 1970, the timestamp field would overflow in 2039.

Are Snowflake IDs sortable by time?

Roughly. IDs from one machine sort exactly in the order they were made, and IDs from different machines sort by their timestamps, which are only as accurate as each machine’s clock. Clocks a few milliseconds apart make the order across machines approximate, which is fine for newest-first lists but not for deciding which event happened first.

What happens to Snowflake IDs when the clock goes backwards?

A generator that trusts its clock would reuse timestamps, restart its sequence and issue duplicate IDs. Correct implementations remember the last timestamp they used and, if the clock reads earlier, wait until it catches up or refuse to issue IDs, and production systems keep clocks synchronised with gradual adjustments rather than jumps.

Should I use Snowflake IDs or UUIDs?

Snowflake IDs are half the size and sort by time, which keeps database index inserts at the end of the index, but need a unique machine number per generator. UUIDv4 needs no coordination but is random, so inserts scatter across the index. UUIDv7 combines a time prefix with randomness, sorting like Snowflake at 128 bits without machine numbers.

How are machine IDs assigned in a Snowflake system?

Each generator needs a number no other live generator is using. Small fleets set it in configuration; larger ones take a lease on a number from a coordination service such as ZooKeeper or etcd at startup and give it up on shutdown, so a number is never shared even as instances come and go.