uuid.lol

Snowflake Generator

Press c to copy or r for a new one

Settings

The epoch decides what the timestamp bits count from. Worker and process are five bits each, so they run from 0 to 31.

epoch 1288834974657

Generate in bulk

What is a snowflake?

A snowflake is a 63-bit integer, almost always printed as a decimal string. Twitter built the scheme in 2010 to replace auto-increment keys across a sharded database, and Discord and X still hand them out today.

The bits are laid out as 41 for milliseconds since a custom epoch, 5 for a worker number, 5 for a process number, and 12 for a sequence that counts IDs within a millisecond. The top bit stays clear so the value fits in a signed 64-bit integer.

Twelve sequence bits means 4,096 IDs per worker per millisecond before it wraps, which was plenty for the workload it was designed around.

Why they always travel as strings

63 bits does not fit in a JavaScript number, which carries 53 bits of integer precision. Run JSON.parse over a payload holding a raw snowflake and you get back a number that is near the right value and silently not equal to it. Nothing errors. The last few digits just change.

This is why every API that serves snowflakes serialises them as strings, Discord and X included. Keep them as strings all the way through your code and only reach for BigInt when you actually need to pull the fields apart.

The epoch is not in the ID

Nothing inside a snowflake says what its timestamp counts from. Discord counts from 2015, X counts from November 2010, and Instagram chose its own. Decoding one means already knowing which system minted it, or the answer is off by years.

The decoder handles this by showing the timestamp under every well-known epoch at once. Paste in a Discord message ID or an X post ID and pick the row that belongs to it.

Uniqueness here is coordinated, not lucky

A UUID v4 is unique because a collision is astronomically improbable. A snowflake is unique because you promised it would be.

Two machines both configured as worker 1, process 1 will produce the same ID the moment they mint in the same millisecond at the same sequence number. There is no randomness anywhere in the value to save you. Handing out distinct worker numbers is a real operational job, usually done by a coordinator such as ZooKeeper or by whatever assigns your pod ordinals.

Generate one in code

TypeScript

import { Snowflake } from "@sapphire/snowflake";

const epoch = new Date("2015-01-01T00:00:00.000Z");
new Snowflake(epoch).generate().toString();

Go

import "github.com/bwmarrin/snowflake"

node, err := snowflake.NewNode(1)
id := node.Generate().String()

SQL (Postgres)

create sequence if not exists snowflake_seq;

select (((extract(epoch from now()) * 1000)::bigint - 1288834974657) << 22)
     | (1::bigint << 17)
     | (1::bigint << 12)
     | (nextval('snowflake_seq') % 4096);