Skip to main content

Fast, time-sortable, 22-char Base58 unique ID generator

Project description

sparkid

Fast, monotonic, time-sortable, 22-char Base58 unique ID generator. Zero dependencies.

1ocmpHE1bFnygEBAPTzMK4
1ocmpHE1bFnygFv4Wp4dL2
1ocmpHE1bFnygGoUXUL7Xo

Install

pip install sparkid

Usage

from sparkid import generate_id

id = generate_id()
# => "1ocmpHE1bFnygEBAPTzMK4"

Properties

Property Value
Length 22 characters, fixed
Alphabet Base58 (no 0, O, I, l)
Sortable Lexicographically, by creation time
Monotonic Strictly increasing within each thread
URL-safe Yes
Collision resistance ~58^14 (~1.8 x 10^24) combinations per millisecond
Randomness Cryptographically secure (os.urandom)
Thread-safe Yes (via threading.local)

How it works

Each ID is composed of two parts:

[8-char timestamp][14-char suffix]
  • Timestamp (8 chars): Current time in milliseconds, Base58-encoded. IDs generated in a later millisecond always sort after earlier ones.
  • Suffix (14 chars): Seeded from os.urandom (rejection-sampled, no modulo bias) at the start of each millisecond, then monotonically incremented for each subsequent ID within that millisecond. This guarantees strict ordering even when multiple IDs share a timestamp.

Ordering guarantees

IDs from a single IdGenerator instance (or a single thread using generate_id()) are strictly monotonically increasing — every ID is lexicographically greater than the one before it.

Across threads, IDs are unique but not ordered relative to each other. Each thread gets its own generator via threading.local, so there is no cross-thread coordination. This is the same guarantee provided by most UUID v7 libraries.

If you need process-wide monotonic ordering across threads, wrap a single IdGenerator in a lock:

import threading
from sparkid import IdGenerator

_lock = threading.Lock()
_gen = IdGenerator()

def generate_id_monotonic():
    with _lock:
        return _gen()

Advanced usage

For manual control, use the IdGenerator class directly:

from sparkid import IdGenerator

gen = IdGenerator()
id = gen()

Each IdGenerator instance maintains its own internal state. The module-level generate_id() function uses threading.local to automatically create one instance per thread.

Performance

~3 million IDs/sec on Python 3.14 (~0.33 µs/call):

python bench/benchmark.py

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

sparkid-1.2.0.tar.gz (24.6 kB view details)

Uploaded Source

Built Distribution

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

sparkid-1.2.0-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

File details

Details for the file sparkid-1.2.0.tar.gz.

File metadata

  • Download URL: sparkid-1.2.0.tar.gz
  • Upload date:
  • Size: 24.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for sparkid-1.2.0.tar.gz
Algorithm Hash digest
SHA256 0e8edf75a98c34d7a9fd45cf33b54087f584210f65a086b59121a4eefdbb13bf
MD5 b80b2e13feb6ec142922b8040926d267
BLAKE2b-256 d7ac4f8b49390607a57b6e2d6d7f4e952ba3564bb2a81aeff82d7a5f46b8d497

See more details on using hashes here.

File details

Details for the file sparkid-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: sparkid-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 6.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for sparkid-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f23ca999099c198349bccadc644048c417ebdd4b891ac72b6ec872d815e59e80
MD5 7e7bf18692e11c16993537cae7bf3298
BLAKE2b-256 685691924390b0018ad5d1733a140ec0fae4f0996775e892f18eefc4da066a0c

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