Overview
By default the Agent SDK writes session transcripts to local JSONL files under
~/.claude/projects/. A SessionStore adapter mirrors those transcripts to your
own backend (S3, Redis, a database) so a session created on one host can be
resumed on another. This matters for multi-host deployments, durability, and
compliance.
The SessionStore interface
A SessionStore has two required methods, append and load, plus optional
listSessions, delete, and listSubkeys:
append(key, entries) - called after each batch of transcript entries is
written locally.
load(key) - called once before the subprocess spawns when resume is set;
returns null for an unknown session.
A SessionKey is { projectKey, sessionId, subpath? }. subpath is set for
subagent transcripts or sidecar files (treat it as an opaque suffix). Implement
the optional methods to enable listSessions(), deleteSession(), and subagent
resume.
Quick start
The SDK ships InMemorySessionStore for development. Pass a store via
sessionStore and resume with the captured session id:
import { query, InMemorySessionStore } from "@anthropic-ai/claude-agent-sdk";
const store = new InMemorySessionStore();
let sessionId;
for await (const m of query({ prompt: "...", options: { sessionStore: store } })) {
if (m.type === "result") sessionId = m.session_id;
}
for await (const m of query({ prompt: "...", options: { sessionStore: store, resume: sessionId } })) {
/* full context from the first call */
}
Write your own adapter
Implement append and load against your backend; add the optional methods for
full functionality. Treat entries as opaque JSON-safe values: persist in order and
return them deep-equal from load (key reordering is fine, so Postgres jsonb
works). The TypeScript repo includes runnable S3, Redis, and Postgres reference
adapters under examples/session-stores/, and both SDKs ship a conformance suite
to validate your adapter.
Behavior notes
- Dual-write: the CLI writes locally first; the store mirrors. To make the
local copy ephemeral, point
CLAUDE_CONFIG_DIR at a temp dir.
- Best-effort mirror: a failed
append logs, emits a mirror_error system
message, and continues; failed batches are not retried.
- Compaction:
getSessionMessages returns the post-compaction chain; call
store.load(key) for raw history.
- Fork:
forkSession rewrites session ids and message UUIDs rather than doing
a byte copy.
- Retention: the SDK never deletes from your store; you own TTLs and cleanup.
Source