Crates.io | snowid |
lib.rs | snowid |
version | 0.2.0 |
created_at | 2025-02-23 01:24:17.552127+00 |
updated_at | 2025-08-19 13:27:04.946519+00 |
description | A Rust library for generating SnowID - a Snowflake-like timestamp-based distributed unique identifier |
homepage | https://github.com/qeeqez/snowid-rust |
repository | https://github.com/qeeqez/snowid-rust |
max_upload_size | |
id | 1565971 |
size | 103,317 |
A Rust implementation of a Snowflake-like ID generator with 42-bit timestamp.
Generate 64-bit unique identifiers that are:
thiserror
, base62
for encoding)Example ID: 151819733950271234
Default configuration:
|------------------------------------------|------------|------------|
| TIMESTAMP (42 bits) | NODE (10) | SEQ (12) |
|------------------------------------------|------------|------------|
[dependencies]
snowid = "0.2.0"
use snowid::SnowID;
fn main() {
let gen = SnowID::new(1).unwrap();
let id = gen.generate();
println!("Generated ID: {}", id);
}
Generate base62 encoded IDs (using characters 0-9, a-z, A-Z) for more compact and URL-friendly identifiers:
use snowid::SnowID;
fn main() {
// Create a generator
let gen = SnowID::new(1).unwrap();
// Generate a base62 encoded ID
let encoded_id = gen.generate_base62();
println!("Base62 ID: {}", encoded_id); // Example: "2qPfVQh7Jw9"
// Generate with raw value
let (encoded_id, raw_id) = gen.generate_base62_with_raw();
println!("Base62: {}, Raw: {}", encoded_id, raw_id);
// Decode a base62 ID back to u64
let decoded = gen.decode_base62(&encoded_id).unwrap();
assert_eq!(decoded, raw_id);
// Extract components from a base62 ID
let (timestamp, node, sequence) = gen.decompose_base62(&encoded_id).unwrap();
println!("Timestamp: {}, Node: {}, Sequence: {}", timestamp, node, sequence);
}
use snowid::{SnowID, SnowIDConfig};
fn main() {
// Create custom configuration
let config = SnowIDConfig::builder()
.epoch(1577836800000) // 2020-01-01 00:00:00 UTC
.node_bits(8).unwrap() // Supports 255 nodes
.build();
// Create generator with custom config
let gen = SnowID::with_config(1, config).unwrap();
}
use snowid::SnowID;
fn main() {
let gen = SnowID::new(1).unwrap();
// Generate numeric IDs
let id = gen.generate();
// Generate Base62 encoded IDs
let base62_id = gen.generate_base62();
let (base62_id, raw_id) = gen.generate_base62_with_raw();
// Decode Base62 IDs
let decoded = gen.decode_base62(&base62_id).unwrap();
let (ts, node, seq) = gen.decompose_base62(&base62_id).unwrap();
// Extract individual components from numeric IDs
let timestamp = gen.extract.timestamp(id); // Get timestamp from ID
let node = gen.extract.node(id); // Get node ID from ID
let sequence = gen.extract.sequence(id); // Get sequence from ID
// Extract all components at once
let (ts, node, seq) = gen.extract.decompose(id);
// Configuration information
let max_node = gen.config.max_node_id(); // Get maximum allowed node ID
let node_bits = gen.config.node_bits(); // Get number of bits used for node ID
let max_seq = gen.config.max_sequence_id(); // Get maximum sequence per millisecond
let timestamp_bits = SnowID::TIMESTAMP_BITS; // Get number of bits used for timestamp (42)
}
When the per-millisecond sequence is exhausted, SnowID waits for the next millisecond. You can tune the short busy-wait (spin) before sleeping:
use snowid::{SnowID, SnowIDConfig};
fn main() {
let config = SnowIDConfig::builder()
.node_bits(10).unwrap()
.enable_spin(true) // default: true
.spin_loops(64) // default: 64 spin iterations before sleeping
.spin_yield_every(16) // default: yield every 16 iterations (0 disables yielding)
.build();
let gen = SnowID::with_config(1, config).unwrap();
}
Notes:
enable_spin(false)
or spin_loops(0)
to disable spinning entirely.spin_loops
can reduce CPU usage; higher values may reduce tail latency under overflow.Platform | Timestamp | Node Bits | Sequence Bits | Max Nodes | IDs/ms/node | Time/ID |
---|---|---|---|---|---|---|
41 | 10 | 12 | 1,024 | 4,096 | ~242ns | |
41 | 13 | 10 | 8,192 | 1,024 | ~1.94ยตs | |
Discord | 42 | 10 | 12 | 1,024 | 4,096 | ~245ns |
Node Bits | Max Nodes | IDs/ms/node | Time/ID |
---|---|---|---|
6 | 64 | 65,536 | ~20ns |
8 | 256 | 16,384 | ~60ns |
10 | 1,024 | 4,096 | ~243ns |
12 | 4,096 | 1,024 | ~968ns |
14 | 16,384 | 256 | ~3.86ยตs |
16 | 65,536 | 64 | ~15.4ยตs |
Choose configuration based on your needs:
Variant | Time/ID | Size | Notes |
---|---|---|---|
Int64 | ~290 ns | 18-20 digits | Fastest option |
Base62 | ~295 ns | 10-11 chars | ~2% slower, more compact |
Base62 encoding provides more compact, URL-friendly IDs with a small performance trade-off.
Check out examples for:
MIT - See LICENSE for details