Change the ID strategy

In shortHow to control the format of thread IDs and run IDs generated by the framework using BaseIDGenerator.

  • 2 min read
  • 7 sections
  • Updated
  • v0.9.2
  • Markdown

By default, 10xGraph generates UUID v4 strings for thread IDs and run IDs. If your storage backend requires integer primary keys, short human-readable codes, or timestamp-sortable IDs, you can swap in a different generator.

Prerequisites

You have a working graph. No extra packages required.

Quick start: switch to timestamp-based integers

Python
from tenxgraph.core import StateGraph
from tenxgraph.utils.id_generator import BigIntIDGenerator

graph = StateGraph(
    id_generator=BigIntIDGenerator(),
)
app = graph.compile()

Every thread and run created by this graph will now have a 19-digit integer ID based on the current nanosecond timestamp.

Available generators

Class id_type Example output Use when
DefaultIDGenerator STRING "" (falls back to framework UUID) Default - framework picks UUID if empty.
UUIDGenerator STRING "550e8400-e29b-41d4-a716-446655440000" Maximum collision resistance; stateless.
BigIntIDGenerator BIGINT 1712576400000000000 PostgreSQL bigint primary keys; sortable by time.
TimestampIDGenerator INTEGER 1712576400123456 16-digit microsecond integer; sortable.
IntIDGenerator INTEGER 2147483647 32-bit random integer; small storage footprint.
HexIDGenerator STRING "1a2b3c4d5e6f7890abcdef1234567890" 32-char hex; no hyphens.
ShortIDGenerator STRING "Ab3XyZ9k" Human-readable 8-char codes; URL-safe.

All classes are importable from tenxgraph.utils.id_generator or the top-level tenxgraph.utils.

Write a custom generator

Python
from tenxgraph.utils.id_generator import BaseIDGenerator, IDType
import uuid

class PrefixedUUIDGenerator(BaseIDGenerator):
    """Generates IDs like 'sess_550e8400-e29b-...' for easy prefix filtering."""

    def __init__(self, prefix: str = "sess"):
        self.prefix = prefix

    @property
    def id_type(self) -> IDType:
        return IDType.STRING

    def generate(self) -> str:
        return f"{self.prefix}_{uuid.uuid4()}"

graph = StateGraph(id_generator=PrefixedUUIDGenerator("run"))

Async generators

If your ID generation requires I/O (for example, fetching a sequence from a database), implement AsyncIDGenerator:

Python
from tenxgraph.utils.id_generator import AsyncIDGenerator, IDType

class DatabaseSequenceGenerator(AsyncIDGenerator):
    """Fetch the next integer sequence from PG."""

    def __init__(self, pool):
        self.pool = pool

    @property
    def id_type(self) -> IDType:
        return IDType.BIGINT

    async def generate(self) -> int:
        async with self.pool.acquire() as conn:
            return await conn.fetchval("SELECT nextval('agentflow_id_seq')")

Access the generated ID inside a node

The current run’s generated ID is available via dependency injection:

Python
from injectq import Inject

async def my_node(
    state,
    config: dict,
    generated_id: str = Inject["generated_id"],
) -> ...:
    print(f"This run ID: {generated_id}")
    return state

Common errors

Error Cause Fix
IDs collide in BigIntIDGenerator at very high throughput Two calls land in the same nanosecond. Switch to UUIDGenerator or add a random suffix.
IntIDGenerator causes UNIQUE constraint failures 32-bit space is too small for your dataset. Use BigIntIDGenerator or UUIDGenerator.
ShortIDGenerator collisions in production 62^8 ≈ 218 trillion possibilities but not cryptographically guaranteed unique. Only use for low-volume, human-facing IDs; don’t use as a DB primary key.
Last updated for v0.9.2Edit this page on GitHubReport an issue