Threads: Isolation, Lifecycle & Cleanup
A LangGraph thread is an isolated state timeline keyed by a string. One compiled graph serves thousands of users simultaneously, each with their own checkpoint chain. This article covers ID design for multi-tenant apps, the full thread lifecycle from create to TTL expiry, concurrency gotchas, and production cleanup strategies.
Quick Reference
- →Thread ID: a string in config={'configurable': {'thread_id': '...'}} — required when a checkpointer is enabled
- →Each thread has its own independent checkpoint chain — no state leakage between threads
- →Same compiled graph serves all threads — no per-user compilation or graph cloning
- →Multi-tenant ID pattern: tenant_id:user_id:session_id — always prefix; no built-in namespace enforcement
- →Delete a thread: checkpointer.delete_thread(thread_id) or await checkpointer.adelete_thread(thread_id)
- →TTL cleanup: configure default_ttl and sweep_interval_minutes in langgraph.json for automatic expiry
- →Concurrent writes to the same thread: last-write-wins — use checkpoint_id branching for explicit versioning
- →Platform threads API: client.threads.create(), .search(), .get() for managed lifecycle operations
What Threads Are (and Aren't)
A thread is a persistence abstraction, not a concurrency primitive. It's an isolated state timeline identified by a string — every invoke() and stream() call that passes the same thread_id continues the same conversation. The compiled graph is shared across all threads; only the checkpoint data is partitioned per thread_id.
One compiled graph · each thread has its own isolated checkpoint chain
The diagram above shows what this means in practice. One compiled graph instance fans out to three independent threads, each accumulating its own checkpoint chain. Thread A can't see Thread B's state; Thread B can't see Thread C's. The isolation boundary is enforced entirely by the checkpointer — which stores and retrieves state keyed by thread_id.
LangGraph threads are a persistence concept, not OS threads. You can have millions of LangGraph threads served by a single Python process. The word 'thread' here means 'a thread of conversation' — a named slot in the checkpointer.