snowflake-gen
A configurable Snowflake ID generator for Rust.
Features
- Configurable bit layout -- tune the balance between timestamp range, throughput, and node count
- Thread-local global API -- zero-lock, zero-contention ID generation across threads
- ID decomposition -- decode any generated ID back into its timestamp, machine, node, and sequence parts
- Buffered generation --
SnowflakeIdBucketpre-generates a full sequence batch for maximum throughput - Custom epochs -- use Discord-style, Twitter-style, or your own epoch
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 |
Quick start
use SnowflakeIdGenerator;
let mut idgen= new.unwrap;
let id = idgen.generate.unwrap;
println!;
Custom bit layout
use ;
// 10 sequence bits (1,023 IDs/ms), 8 machine + 7 node bits
let layout = new.unwrap;
let mut idgen= with_layout.unwrap;
let id = idgen.generate.unwrap;
Thread-local global API
Initialize once, then call next_id() from any thread with no locking:
use ;
Each thread gets its own generator with a unique node_id assigned automatically.
ID decomposition
use SnowflakeIdGenerator;
let mut idgen= new.unwrap;
let id = idgen.generate.unwrap;
let parts = idgen.decompose;
assert_eq!;
assert_eq!;
Buffered generation
SnowflakeIdBucket pre-generates a full sequence cycle and serves IDs from a buffer:
use SnowflakeIdBucket;
let mut bucket = new.unwrap;
let id = bucket.get_id;
Caveats
- Thread count is limited by
node_id_bits. Each thread that callsnext_id()is assigned a unique node ID. With the default 5node_id_bits, at most 32 threads can generate IDs. Exceeding this returnsSnowflakeError::NodeIdExhausted. If your application needs more threads, increasenode_id_bits(and reducemachine_id_bitsortimestamp_bitsto compensate) when constructing yourBitLayout. init()can only be called once per process. A second call returnsSnowflakeError::AlreadyInitialized. Thread-local generators created by earlier threads retain the original configuration and cannot be updated in-place. To change the configuration, restart the process so all thread-local state is cleared and recreated.- Do not mix
lazy_generatewith clock-based methods (generate/real_time_generate) on the same generator instance.lazy_generateadvances the internal timestamp synthetically, so a later clock-based call may reuse a timestamp thatlazy_generatealready claimed, producing duplicate IDs.SnowflakeIdBucketuseslazy_generateinternally on a dedicated generator and is safe to use alongside separate clock-based generators.
License
MIT