Skip to main content
By default, the SDK writes session transcripts to JSONL files under ~/.claude/projects/ on the local filesystem. A SessionStore adapter lets you mirror those transcripts to your own backend, such as S3, Redis, or a database, so a session created on one host can be resumed on another host running from a matching working directory. Common reasons to use a session store:
  • Multi-host deployments. Serverless functions, autoscaled workers, and CI runners don’t share a filesystem. A shared store lets replicas resume each other’s sessions.
  • Durability. Local containers are ephemeral. A store backed by S3 or a database survives restarts and redeploys.
  • Compliance and audit. Keep transcripts in storage you already govern, with your own retention rules, encryption, and access controls.

The SessionStore interface

A SessionStore is an object with two required methods, append and load, and four optional methods. The SDK calls append to write transcript entries during a query and load to read them back for resume.
SessionKey addresses one transcript. projectKey is a stable, filesystem-safe encoding of the working directory, sessionId is the session UUID, and subpath is set when the entry belongs to a subagent transcript or sidecar file rather than the main conversation. Because projectKey encodes the working directory, resume or continue from the store from a working directory matching the original run’s. In TypeScript, if you set CLAUDE_CODE_PROJECT_DIR_NAME beside CLAUDE_CONFIG_DIR in a query’s env option, the SDK keys that query’s entries, and its resume and continue lookups, by that name instead. Because standalone helpers such as listSessions and deleteSession take no env and read the process environment, set CLAUDE_CONFIG_DIR and the same name in the host process environment too. Requires Agent SDK v0.3.234 or later. Treat subpath as an opaque key suffix; it follows the on-disk layout, for example subagents/agent-<id>. When subpath is undefined the key refers to the main transcript. In a SessionSummaryEntry, mtime is the sidecar’s storage write time and must share a clock source with the mtime values listSessions returns. data is opaque SDK-owned state; persist it verbatim without interpreting it. Build the entries by calling the exported foldSessionSummary helper, fold_session_summary in Python, on each batch inside append. Skip batches whose key has a subpath; subagent transcripts must not contribute to the main session’s summary. The fold never sets mtime: stamp it at persist time, through the options.mtime argument in TypeScript or by overwriting the field on the returned entry in Python. Concurrent append calls for the same session can race on the sidecar, so serialize the read-fold-write with a transaction, a compare-and-swap, or a per-session lock; the fold itself is pure. For what the SDK does with the transcript load returns, see Resume from the store.

Quick start

The SDK ships an InMemorySessionStore for development and testing. The example below runs a query with the store attached, captures the session ID from the result message, then resumes from the store in a second query() call. The second call passes the same store instance plus resume, so the SDK loads the transcript from the store instead of the local filesystem: