Skip to main content

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

Project description

sparkid

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

1ocmpHE1bFnygEBAPTzMK
1ocmpHE1bFnygFv4Wp4dL
1ocmpHE1bFnygGoUXUL7X

Install

pip install sparkid

Usage

from sparkid import generate_id

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

Properties

Property Value
Length 21 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^13 (~8.4 x 10^22) 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][13-char suffix]
  • Timestamp (8 chars): Current time in milliseconds, Base58-encoded. IDs generated in a later millisecond always sort after earlier ones.
  • Suffix (13 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

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.3.1.tar.gz (24.5 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.3.1-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for sparkid-1.3.1.tar.gz
Algorithm Hash digest
SHA256 a8dc8ef2f87d95a2de814d7e3f63b5176c07230f61d95c58ce666d994a654438
MD5 206b977bc11c8c543bf365ebec7620ea
BLAKE2b-256 5b750a6013d1f37bf5f92f1aec46f7d7649462fb4860483bc4d21f227291fb26

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sparkid-1.3.1-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.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7c0c45845a1b402042bdfd6ba2934481974a913a456b6e6c9df81cbcded1ff57
MD5 daf05b92b4b8a04301881e4b1cd4fadb
BLAKE2b-256 41737b6515f50695e4180a082d38c6e39d92c949a2303eb7a1d563303374a903

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