Snowflake is a distributed unique ID generation algorithm originally created by Twitter. It produces 64-bit IDs that are:
- Time-ordered - IDs sort roughly by creation time (lexicographically).
- Unique across nodes - Each node gets a
machineId(0-1023), preventing collisions.
- ~800,000 IDs/sec - Single-threaded generation performance.
- Universal runtime - Works in Deno, Node.js, Bun, and browsers.
- Decomposition - Parse any Snowflake ID back into timestamp, machineId, and sequence.
Deno (JSR):
deno add jsr:@neabyte/snowflakenpm:
npm install @neabyte/snowflakeCDN (jsDelivr/esm.sh):
<script type="module">
import Snowflake from 'https://cdn.jsdelivr.net/npm/@neabyte/snowflake/dist/index.mjs'
</script>Or via esm.sh:
<script type="module">
import Snowflake from 'https://esm.sh/@neabyte/snowflake'
</script>import Snowflake from '@neabyte/snowflake'
// Choose an epoch - decade or century
const epoch = Snowflake.getDecadeEpoch()
// Create a generator with a unique machineId (0-1023)
const sf = new Snowflake({ machineId: 1, epochOffset: epoch })
// Generate an ID
const id = sf.generate()
// '851050322686153018'const components = Snowflake.decompose(id, epoch)
console.log(components)
// {
// id: '851050322686153018',
// timestamp: 202906208678,
// absoluteTime: 1749206408678,
// machineId: 1,
// sequence: 0
// }
console.log(new Date(components.absoluteTime).toISOString())
// '2026-06-06T10:50:08.678Z'Each server or process gets a unique machineId:
// Server A
const sfA = new Snowflake({ machineId: 1, epochOffset: epoch })
// Server B
const sfB = new Snowflake({ machineId: 2, epochOffset: epoch })
// Zero collision guaranteed as long as machineId is unique per node// Start of current decade (e.g., 2020-01-01)
Snowflake.getDecadeEpoch()
// Start of current century (e.g., 2000-01-01)
Snowflake.getCenturyEpoch()
// Custom epoch - any past timestamp in milliseconds
const customEpoch = new Date('2024-01-01').getTime()| Parameter | Type | Description |
|---|---|---|
options.machineId |
number |
Unique node identifier (0-1023) |
options.epochOffset |
number |
Epoch start time in milliseconds |
Validation:
machineIdmust be between 0 and 1023epochOffsetmust be a finite, non-negative number not in the future
Generates a new Snowflake ID as a decimal string.
- Sequence counter resets every millisecond
- Up to 4096 IDs per millisecond per node
- Built-in spin-wait when sequence exceeds 4096
Parses a Snowflake ID into its components.
| Parameter | Type | Description |
|---|---|---|
id |
string | bigint |
The Snowflake ID to parse |
epochOffset |
number |
Optional epoch to add to timestamp (default: 0) |
Returns: SnowflakeComponents
type SnowflakeComponents = {
id: string
timestamp: number // Milliseconds since epochOffset
absoluteTime: number // timestamp + epochOffset
machineId: number // Node identifier (0-1023)
sequence: number // Sequence within the millisecond (0-4095)
}Returns the start of the current decade (e.g., 2020-01-01) in milliseconds.
Returns the start of the current century (e.g., 2000-01-01) in milliseconds.
Benchmarked on Apple M3 Pro:
| Operation | Time | Rate |
|---|---|---|
| Generate single ID | 1.3 µs | ~800,000/sec |
| Generate 1000 IDs | 1.3 ms | ~760,000/sec |
| Decompose string ID | 290 ns | ~3,450,000/sec |
| Decompose bigint ID | 254 ns | ~3,930,000/sec |
64-bit layout:
| 42 bits timestamp | 10 bits machineId | 12 bits sequence |
- Timestamp: Milliseconds since
epochOffset(42 bits = ~139 years range) - Machine ID: Node identifier (10 bits = 0-1023)
- Sequence: Per-millisecond counter (12 bits = 0-4095)
# Format, lint, and typecheck
deno task check
# Run unit tests
deno task test
# Run benchmarks
deno bench benchmark/This project is licensed under the MIT license. See the LICENSE file for details.