Skip to content

NeaByteLab/Snowflake

Repository files navigation

@neabyte/snowflake

Fast distributed snowflake ID generator for all JavaScript runtimes

Deno Node Bun Browser

Module type: Deno/ESM npm version JSR License

What is Snowflake?

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.

Features

  • ~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.

Installation

Deno (JSR):

deno add jsr:@neabyte/snowflake

npm:

npm install @neabyte/snowflake

CDN (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>

Usage

Basic generation

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'

Decompose an ID

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'

Multi-node setup

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

Epoch helpers

// 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()

API

new Snowflake(options)

Parameter Type Description
options.machineId number Unique node identifier (0-1023)
options.epochOffset number Epoch start time in milliseconds

Validation:

  • machineId must be between 0 and 1023
  • epochOffset must be a finite, non-negative number not in the future

sf.generate(): string

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

Snowflake.decompose(id, epochOffset?): SnowflakeComponents

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)
}

Snowflake.getDecadeEpoch(date?): number

Returns the start of the current decade (e.g., 2020-01-01) in milliseconds.

Snowflake.getCenturyEpoch(date?): number

Returns the start of the current century (e.g., 2000-01-01) in milliseconds.

Performance

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

ID Structure

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)

Testing

# Format, lint, and typecheck
deno task check

# Run unit tests
deno task test

# Run benchmarks
deno bench benchmark/

License

This project is licensed under the MIT license. See the LICENSE file for details.