snowflake-id-monotonic
v1.0.0
Published
A tiny module to generate monotonic time-based 64-bit unique IDs and decode them back to their creation timestamp, inspired by Twitter Snowflake.
Maintainers
Readme
❄️ Snowflake ID Generator (Monotonic)
A performancent, monotonic Snowflake ID generator for Node.js and TypeScript applications. Inspired by Twitter's original Snowflake algorithm, time-ordered, unique IDs across distributed systems with zero dependencies,
Features
- Monotonic: IDs are always increasing, even when system clock moves backward
- Async Support: Non-blocking async version for concurrent environments
- Timezone Aware: Optional for timezone-specific decoding
- ID Decoding: Extracts creation timestamp from Snowflake ID base to its offset
- Resilient: Returns "0" on errors instead of throwing
- TypeScript Native: Full type definitions included
- Flexible Configuration: Custom epochs, machine IDs
📦 Installation
npm install snowflake-id-monotonic
# or
yarn add snowflake-id-monotonic
# or
pnpm add snowflake-id-monotonicBasic Usage
import { Snowflake } from 'snowflake-id-monotonic';
// Create generator with default settings
const snowflake = new Snowflake();
// Generate ID (synchronous - fastest)
const id = snowflake.GenerateID();
console.log(id); // "130303618715750401"
// Generate ID (asynchronous - non-blocking)
const asyncId = await snowflake.GenerateIDAsync();
console.log(asyncId); // "130303618715750402"
// Decode ID back to creation timestamp
const timestamp = snowflake.decodetoTimestamp(id);
console.log(timestamp); // "1745109200000" (epoch milliseconds)
// Format timestamp as Date
console.log(new Date(Number(timestamp)));
// Output: 2025-04-19T10:33:20.000ZCustom Config
import { Snowflake } from 'snowflake-id-monotonic';
// Create generator with custom settings
const snowflake = new Snowflake({
mid: 42, // Machine ID (0-1023)
offset: "2025-01-01T00:00:00Z", // Custom epoch (ISO string)
// offset: new Date("2025-01-01"), // Or Date object
// offset: 1735689600000, // Or milliseconds
// now: () => Date.now(), // Custom time source
});
const id = snowflake.GenerateID();
console.log(id);🎯 API Reference
new Snowflake(options?) Creates a new Snowflake ID generator instance.
GenerateID(): string Generates a unique Snowflake ID synchronously. Returns "0" on error.
GenerateIDAsync(): Promise(string) Generates a unique Snowflake ID asynchronously. Returns "0" on error.
decodetoTimestamp(id: string, offset?): string Decodes a Snowflake ID back to its creation timestamp (epoch milliseconds).
Distributed System Setup
// Server 1
const server1 = new Snowflake({ mid: 1 });
// Server 2
const server2 = new Snowflake({ mid: 2 });
// Server 3
const server3 = new Snowflake({ mid: 3 });
// Each generates unique, non-overlapping IDsDatabase Integration
import { Snowflake } from 'snowflake-id-monotonic';
const snowflake = new Snowflake({ mid: process.env.MACHINE_ID || 1 });
// Create user with Snowflake ID
async function createUser(userData) {
const userId = await snowflake.GenerateIDAsync();
const createdAt = Number(snowflake.decodetoTimestamp(userId));
await db.users.insert({
id: userId,
...userData,
created_at: new Date(createdAt)
});
return userId;
}📈 Performance
Benchmarks (Node.js v24, Acer Aspire 5 WIN11 Core i5-11th Gen 16gb ram 1tb ssd)
| Method | Rate (IDs/sec) | Time per ID | Relative Speed |
|--------|----------------|-------------|----------------|
| GenerateID() | ~1.2 million | ~0.0008ms | 1.52x faster |
| GenerateIDAsync() | ~800,000 | ~0.0012ms | Baseline |
| Concurrent (100 instances) | ~340,000 | ~0.0029ms | System-wide |
Performance Characteristics
Synchronous (
GenerateID())- Best for: Bulk generation, single-threaded workloads
- Overhead: Minimal, but may block event loop briefly
- Use when: Generating IDs in loops or batches
Asynchronous (
GenerateIDAsync())- Best for: High-concurrency, I/O-bound applications
- Overhead: ~52% slower due to Promise scheduling
- Use when: In async/await contexts, web servers, real-time systems
Memory Efficiency
- Minimal memory footprint (< 1MB for 1M IDs)
- No significant GC pressure
- Suitable for serverless and memory-constrained environments
🤝 Contributing
Every snowflake matters - and so does every contribution... Whether you're fixing a typo or adding a new feature...
How You Can Help:
- 🐛 Found a bug? File an issue with the snowflake ID that caused it!
- 💡 Have an idea? Suggest features that would make your snowfall heavier
- 📚 Better docs? Help others navigate the blizzard
- 🔧 Code contribution? Check our Contributing Guide to get started
Fun fact: Why 'snowflake'?
Because a snowflake's shape evolves as it journeys through the air, no two will ever be the same. Even two flakes floating side by side will each be blown through different levels of humidity and vapour to create a shape that is truly unique. -BBC UK
First Time? No Problem!
- Look for issues tagged good-first-issue ❄️ - perfect for your first contribution to an open source snowstorm!
# Quick start for contributors
git clone https://github.com/piscode/snowflake-id-monotonic.git
cd snowflake-id-monotonic
npm install
npm test
benchmark:
- path\test> node benchmark.js
- path\test> node benchmark-batch.jsThe Originals
Twitter Engineering (2010) - For inventing the Snowflake concept that powers thousands of applications today. Their brilliant 64-bit timestamp-based design revolutionized distributed ID generation. Dustin Rouillard - For the initial JavaScript implementation that made Snowflakes accessible
Special Thanks To:
- The Open Source Community - For being the atmosphere where ideas can collide and form beautiful patterns
- Early Adopters - For braving the first snowfall and reporting the icy patches
