Skip to main content

Flexible 64-bit Snowflake-style unique ID generation for Python

Reason this release was yanked:

incorrect metadata, wrong author/URLs

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 build tools
pip install 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flakeid-0.1.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flakeid-0.1.0-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file flakeid-0.1.0.tar.gz.

File metadata

  • Download URL: flakeid-0.1.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.8

File hashes

Hashes for flakeid-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5ec18dfddb6f07b263deed2ff44de63765f3ec0044db08bc1b95109ead97297a
MD5 12eb75cfa4aeaeba1cd6df1707596add
BLAKE2b-256 85c46bde4fe1d4c0bfa80eae226675140c70b244ea856f8786d3ddc7d65bbbcf

See more details on using hashes here.

File details

Details for the file flakeid-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: flakeid-0.1.0-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

Hashes for flakeid-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b8508c2b7c4865200d3ef5251e83d010138e42b0eabf7227a8e9bc69990a08f7
MD5 d72a75a51bba05d9e93dcf170c689502
BLAKE2b-256 06a460e93cb72f6cbd6d655ca0c026895231734da97245268ef4fdcf6556cf44

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page