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"

Extract timestamp

from sparkid import extract_timestamp

id = generate_id()
dt = extract_timestamp(id)
print(dt.isoformat())
# => "2025-11-14T22:13:20+00:00"

Binary representation

Pack IDs into 16 bytes for compact storage. Sort order is preserved — byte-wise comparison on the binary form gives the same ordering as string comparison.

from sparkid import to_bytes, from_bytes

id = generate_id()

data = to_bytes(id)         # bytes, length 16
restored = from_bytes(data)
assert id == restored

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-2.0.1.tar.gz (26.9 kB view details)

Uploaded Source

Built Distribution

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

sparkid-2.0.1-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sparkid-2.0.1.tar.gz
  • Upload date:
  • Size: 26.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sparkid-2.0.1.tar.gz
Algorithm Hash digest
SHA256 66fe8d8e75c34be468db2b28bd71e4e27a451e1d0c3ed1ae27d103f682ff6b9f
MD5 90a56a698e6e5c04830751ee1455a1b4
BLAKE2b-256 2e92c051a92140f8e674eeb3b05dfeb876cc664d791fb964d11ca83b151d7ff0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sparkid-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 9.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sparkid-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 01ed8bf6aa32a9ee5ad199c8c161c8fdd7e78d2b1f74fecbb482edf27f4f33f1
MD5 087321e97003960678a7b80b16765e48
BLAKE2b-256 ef7a9fc36b98a8c1a4e1a319a2a241ce3a584c6aa1ec78695cb36172017f7511

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