Flexible 64-bit Snowflake-style unique ID generation for Python
Project description
flakeid
Flexible 64-bit Snowflake-style unique ID generation for Python.
Zero dependencies. Thread-safe. Works for a solo project or a large distributed system.
pip install flakeid
How it works
Each ID is a 64-bit integer whose bits encode when and where it was generated:
63 22 21 17 16 12 11 0
┌──┬────────────┬───────┬───────┬────────────┐
│ 0│ timestamp │ DC │ node │ sequence │
│1b│ 41 bits │ 5 bits│ 5 bits│ 12 bits │
└──┴────────────┴───────┴───────┴────────────┘
- Sign bit — always
0, keeping IDs positive in every database and language. - Timestamp — milliseconds since a custom epoch (default: 2020-01-01 UTC).
- Datacenter / Machine IDs — identify the node that generated the ID.
- Sequence — a counter that resets each millisecond, preventing collisions on the same node.
All four field widths are configurable — any field can be resized or removed entirely, as long as the four values sum to 63.
Installation
pip install flakeid
Requires Python ≥ 3.9. No external dependencies.
Quickstart
Zero-config (smallest possible integration)
import flakeid
uid = flakeid.next_id() # → 123456789012345678 (one ID)
ids = flakeid.next_ids(100) # → [...] (bulk)
The default generator uses a minimal layout (no node identity) and is lazily initialised on first call.
Custom generator — Twitter layout
from flakeid import make_generator, PRESET_TWITTER
gen = make_generator(PRESET_TWITTER, datacenter_id=1, machine_id=7)
uid = gen.next_id()
# Inspect what's inside
print(gen.decode(uid))
# DecodedID(raw=..., generated_at='2025-03-15T10:22:01.123Z',
# datacenter_id=1, machine_id=7, sequence=0)
# Check the theoretical limits of this config
print(gen.capacity())
# Capacity(years=69.7, nodes=1024, ids_per_sec=4,096,000)
Built-in presets
| Preset | Layout | Use case |
|---|---|---|
PRESET_TWITTER |
41 ts · 5 DC · 5 node · 12 seq | Classic Twitter / Discord layout |
PRESET_MINIMAL |
53 ts · 10 seq | Solo projects, scripts, single box |
PRESET_SINGLE_DC |
41 ts · 10 node · 12 seq | One DC, many workers |
PRESET_LARGE_CLUSTER |
41 ts · 8 DC · 8 node · 6 seq | 256 DCs × 256 machines |
PRESET_HIGH_THROUGHPUT |
41 ts · 3 DC · 3 node · 16 seq | Max IDs/ms, few nodes |
from flakeid import make_generator, PRESET_MINIMAL, PRESET_LARGE_CLUSTER
# By dict
gen = make_generator(PRESET_MINIMAL)
# By name string
gen = make_generator("large_cluster", datacenter_id=200, machine_id=100)
Fully custom layout
Any four values that sum to 63 work:
from flakeid import SnowflakeGenerator
gen = SnowflakeGenerator(
timestamp_bits=41,
datacenter_bits=8, # up to 256 datacenters
machine_bits=8, # up to 256 machines per DC
sequence_bits=6, # 64 IDs/ms/node
datacenter_id=200,
machine_id=100,
)
uid = gen.next_id()
Container / cloud deployment — read node IDs from env vars
from flakeid import make_generator_from_env
# Reads FLAKEID_DATACENTER_ID and FLAKEID_MACHINE_ID from the environment.
# Falls back to 0 if the variables are not set.
gen = make_generator_from_env("twitter")
Set in your Dockerfile / docker-compose.yml / Kubernetes env: block:
FLAKEID_DATACENTER_ID=3
FLAKEID_MACHINE_ID=12
Custom variable names are supported:
gen = make_generator_from_env(
"twitter",
datacenter_env="MY_APP_DC",
machine_env="MY_APP_NODE",
)
Infinite ID stream
from flakeid import make_generator, PRESET_TWITTER
gen = make_generator(PRESET_TWITTER)
for uid in gen.stream():
save_to_db(uid)
Decoding an ID
dec = gen.decode(uid)
dec.timestamp_ms # Unix ms when it was generated
dec.generated_at # ISO-8601 UTC string, e.g. '2025-03-15T10:22:01.123Z'
dec.datacenter_id # 3
dec.machine_id # 12
dec.sequence # 0
Thread safety
SnowflakeGenerator is thread-safe — a single instance can be shared across any number of threads.
import threading
from flakeid import make_generator, PRESET_TWITTER
gen = make_generator(PRESET_TWITTER, machine_id=1)
def worker():
for _ in range(10_000):
uid = gen.next_id()
save(uid)
threads = [threading.Thread(target=worker) for _ in range(16)]
for t in threads: t.start()
for t in threads: t.join()
# All 160,000 IDs are guaranteed unique
Error handling
from flakeid import ClockBackwardsError, TimestampOverflowError, EpochError
try:
uid = gen.next_id()
except ClockBackwardsError:
# System clock jumped backwards by > 10 ms — check NTP
...
except TimestampOverflowError:
# timestamp bits exhausted — increase timestamp_bits or update epoch_ms
...
except EpochError:
# epoch_ms is in the future relative to current time
...
API reference
flakeid.next_id() → int
Module-level shortcut. Zero-config unique ID.
flakeid.next_ids(count) → list[int]
Module-level shortcut for bulk generation.
make_generator(preset=None, **overrides) → SnowflakeGenerator
Build a generator from a preset dict/name plus optional overrides.
make_generator_from_env(preset=None, *, datacenter_env, machine_env, epoch_env, **overrides) → SnowflakeGenerator
Build a generator whose node IDs come from environment variables.
SnowflakeGenerator
| Method | Description |
|---|---|
next_id() |
One unique ID |
next_ids(count) |
Many unique IDs, single lock |
stream() |
Infinite iterator |
decode(uid) |
Decompose an ID → DecodedID |
capacity() |
Limits of this config → Capacity |
Publishing to PyPI
# 1. Install the package + dev test deps (src/ layout) and build tools
pip install -e ".[dev]" hatch twine
# 2. Run the tests
pytest
# 3. Build distributions
hatch build # creates dist/flakeid-0.1.0.tar.gz and .whl
# 4. Upload to PyPI
twine upload dist/*
# Enter your PyPI username/password or API token when prompted.
# 5. Users can now install with:
# pip install flakeid
For a test run first, upload to TestPyPI:
twine upload --repository testpypi dist/*
pip install --index-url https://test.pypi.org/simple/ flakeid
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flakeid-0.1.1.tar.gz.
File metadata
- Download URL: flakeid-0.1.1.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ac70a7771007e5fe8c87d4c5ce1ad9965bb7d870864cabf5fcf8cafee082329
|
|
| MD5 |
ffb73e63d53ef88fd2ea3ac136b57968
|
|
| BLAKE2b-256 |
9e780d90fad8e08581b36aa89a84910ba0aed145e45e0d3a3f035732018fcc43
|
File details
Details for the file flakeid-0.1.1-py3-none-any.whl.
File metadata
- Download URL: flakeid-0.1.1-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
984d6e30ef6af5ef24f46d1f80d6b74547b992626eb4e53ca63a186a09c17372
|
|
| MD5 |
42a821751e30da281d29ce1299f8afc0
|
|
| BLAKE2b-256 |
cc27d294267c8eb5446bb9fe30a7442035bc4e8c5795b76545602157e5b170e0
|