What a Snowflake ID is
A Snowflake ID is a 64-bit integer that packs a millisecond timestamp, a machine (or shard/worker) identifier, and a per-millisecond sequence number into one value — invented at Twitter to generate unique IDs across many machines without a central coordinator, and now used the same way by Discord, Instagram, and plenty of other large-scale systems. Because the timestamp occupies the high-order bits, Snowflake IDs sort chronologically as plain integers — no separate created_at column needed to order rows by creation time.
The bit layout
Both the classic Twitter scheme and Discord's variant use the same 64-bit shape:
bit 63 bits 62-22 (41 bits) bits 21-12 (10 bits) bits 11-0 (12 bits)
unused timestamp since epoch machine ID sequence
(sign bit) in milliseconds (0-1023) (0-4095, resets each ms)- 41-bit timestamp — milliseconds since a custom epoch, not Unix time directly. That ceiling gives roughly 69 years of range from whatever epoch is chosen.
- 10-bit machine ID — up to 1,024 distinct generators (machines, processes, or shards) can mint IDs independently without colliding. Discord splits this into 5 worker bits + 5 process bits, which is a cosmetic relabeling — the packing math is identical.
- 12-bit sequence — up to 4,096 IDs per machine per millisecond. A real generator that exhausts the sequence within a millisecond waits for the next tick; the generator below advances its internal clock by one millisecond instead of literally blocking, so the demo stays instant.
Epochs
The timestamp field only needs to hold an offset from a chosen epoch, not a full Unix timestamp — that's what gives it 69 usable years instead of running out in 2038. Twitter's original epoch is 1288834974657 ms (2010-11-04T01:42:54.657Z, the day Snowflake was announced). Discord uses 1420070400000 ms (2015-01-01T00:00:00.000Z), its own founding year. Pick either preset below, or set a custom epoch for your own system.
Snowflake vs UUID
A UUID v4 is 128 bits of randomness — effectively zero collision risk with no coordination required, but random UUIDs don't sort by creation time and make poor database index keys because inserts land at random points in the index rather than at the end. A Snowflake ID is smaller (64 bits fits in a signed BIGINT), sorts chronologically by construction, and embeds a decodable creation timestamp for free — the tradeoff is that generating one requires a coordinated machine ID, so two misconfigured generators sharing the same machine ID in the same millisecond can collide. UUID v7 closes part of this gap by putting a timestamp in the high bits of an otherwise-random UUID, trading pure randomness for sortability without needing a machine ID at all.
What this tool does
Generate mode mints IDs using the timestamp/machine/sequence scheme above, entirely in your browser — nothing is sent anywhere, so generated IDs are for testing and demonstration, not guaranteed-unique production values. Use Generate 5 rapidly to see the sequence field increment: five calls fired back-to-back typically land in the same millisecond, which is exactly when the sequence counter (rather than the timestamp) is what keeps the IDs distinct. Decode mode reverses the process — paste in any Snowflake ID and an epoch to recover its embedded timestamp, machine ID, and sequence number.
What this doesn't model
- Clock synchronization. Real distributed generators run on machines whose clocks can drift or jump backward (e.g. an NTP correction). This demo protects against timestamp regression by holding the last-seen millisecond and still advancing the sequence, but it can't simulate multiple machines with genuinely different clocks.
- Machine ID coordination. In production, assigning unique machine IDs (via config, a coordination service like ZooKeeper, or a Kubernetes pod ordinal) is the actual hard part of running a Snowflake generator — this tool lets you type any value from 0–1023 with no such coordination.
FAQ
Are Snowflake IDs safe to use as public-facing identifiers?
They leak creation-time ordering and, over time, roughly how many IDs a system issues per millisecond — information a random UUID doesn't reveal. That's a real consideration for anything where hiding creation order or volume matters (e.g. object IDs that shouldn't reveal how many objects exist).
Why 1 unused bit at the top?
It keeps the value non-negative when interpreted as a signed 64-bit integer, which is what most databases and languages use for a native BIGINT/long type — sidestepping sign-related bugs entirely rather than working around them later.
Is anything I enter here sent anywhere?
No — generation and decoding both run entirely in your browser. Nothing is ever sent to a server.