Watch
1
0
Fork
You've already forked snof
0
❄️ unique id generator https://docs.rs/snof/
  • Rust 98.8%
  • Just 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-28 23:07:33 +02:00
src revise: change Snowflake's field to private, make Snowflake::sequence() take &self 2026-08-28 22:15:15 +02:00
.gitignore [add] initialize repository 2026-02-02 22:06:05 +01:00
Cargo.lock revise: change Snowflake's field to private, make Snowflake::sequence() take &self 2026-08-28 22:15:15 +02:00
Cargo.toml revise: change Snowflake's field to private, make Snowflake::sequence() take &self 2026-08-28 22:15:15 +02:00
justfile build: justfile 2026-08-02 00:40:57 +02:00
license [add] initialize repository 2026-02-02 22:06:05 +01:00
readme.md docs: fixed weird wording in readme 2026-08-28 23:07:33 +02:00
rustfmt.toml style: changed rustfmt.toml 2026-07-23 16:54:05 +02:00

❄️ snof

snof is a unique ID generator. Loosely based on Snowflake IDs, snof generates 64-bit identifiers composed of a 42-bit millisecond-precision timestamp and a 22-bit sequence that distinguishes identifiers generated within the same millisecond. Timestamps are measured from a fixed epoch of Jan 01 2026, giving the timestamp field a range of roughly 139 years.

 63                    22 21          0
+------------------------+-------------+
|   timestamp (42 bits)  | seq (22)    |
+------------------------+-------------+

The generator tracks its entire state in a single atomic word, making ID generation thread-safe and lock-free. When the per-millisecond sequence is exhausted, or the system clock moves backwards, the generator spins until validity is restored.

Note

snof is under development, breaking changes could be made to the API before 1.0.0. Please pin the version if you intend to use snof in a production environment.

Usage

For more details on usage, please refer to the documentation.

use std::sync::Arc;
use std::thread;

use snof::SnowflakeGenerator;

let generator = Arc::new(SnowflakeGenerator::new());

let threads: Vec<_> = (0..4)
    .map(|_| {
        let g = Arc::clone(&generator);
        thread::spawn(move || println!("{}", g.generate()))
    })
    .collect();

for t in threads {
    t.join().unwrap();
}