Snowflake-gen 1.0 - Configurable Snowflake ID generator with thread-local global API

โš“ Rust    ๐Ÿ“… 2026-04-20    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 2      

surdeus

Hi all,

I've just published snowflake-gen 1.0.0, a configurable Snowflake ID generator for Rust.

What it does

Generates 63-bit unique IDs using the Snowflake algorithm, with the bit layout fully under your control. You decide the balance between timestamp range, throughput, and node count.

Features

  • Configurable bit layout, tune timestamp, machine ID, node ID, and sequence bit widths (must sum to 63)
  • Thread-local global API, zero-lock ID generation via init() + next_id(), with automatic per-thread node ID assignment
  • Three generation modes , generate() (clock-based, blocks on sequence wrap), real_time_generate() (always reads the clock), lazy_generate() (no clock syscall, fastest)
  • ID decomposition , decode any ID back into its timestamp, machine, node, and sequence components
  • Buffered generation , SnowflakeIdBucket pre-generates a full sequence batch
  • Custom epochs , use any SystemTime as the epoch (Discord, Twitter, or your own)

Quick start

use snowflake_gen::SnowflakeIdGenerator;

let mut idgen = SnowflakeIdGenerator::new(1, 1).unwrap();
let id = idgen.generate().unwrap();

Or with the thread-local global API:

use snowflake_gen::{BitLayout, init, next_id};

init(1, BitLayout::default()).unwrap();
let id = next_id().unwrap();

Default layout (Twitter-compatible)

Field Bits Max value
Timestamp 41 ~69 years
Machine ID 5 31
Node ID 5 31
Sequence 12 4,096/ms

Performance

~21 million IDs/sec across 32 threads with the default layout. The bottleneck is the millisecond clock, each thread exhausts its 4,096-ID sequence in microseconds then spin-waits. If you need more raw throughput, widen sequence_bits or use lazy_generate / SnowflakeIdBucket to skip the clock entirely.

Links

Feedback welcome, especially on the API design and bit layout ergonomics.

1 post - 1 participant

Read full topic

๐Ÿท๏ธ Rust_feed