Skip to main content

External Session Storage

By default, qodercli keeps session history on the machine where it runs. In a multi-instance, container, or serverless deployment, the next request may reach another machine that cannot access the earlier session. External session storage copies session history into storage shared by your application. Any host can then continue the session by using its session ID. Use external storage when:
  • requests can move between service instances
  • local disks are temporary or unreliable
  • your application must control access, encryption, backups, or retention
For an application that always runs on one machine, local session storage is usually sufficient.

How it works

first request
  query()
    -> qodercli saves the session locally
    -> the SDK sends new session history to your store

later request
  query(..., resume=session_id)
    -> the SDK reads session history from your store
    -> qodercli continues the session
The external store is an additional copy; qodercli continues to record the session locally. Your application does not need to understand or manage qodercli's local file format.

Quick start

Use InMemorySessionStore to verify the flow before connecting real storage. It keeps data only in the current process and loses it when the process exits.
from qoder_agent_sdk import (
    InMemorySessionStore,
    QoderAgentOptions,
    ResultMessage,
    qodercli_auth,
    query,
)

store = InMemorySessionStore()
session_id = None

options = QoderAgentOptions(
    auth=qodercli_auth(),
    cwd="/path/to/project",
    session_store=store,
)
async for message in query(prompt="Inspect this project.", options=options):
    if isinstance(message, ResultMessage):
        session_id = message.session_id
To continue later, pass the recorded session_id as resume and provide the same store again:
resume_options = QoderAgentOptions(
    auth=qodercli_auth(),
    cwd="/path/to/project",
    session_store=store,
    resume=session_id,
)
Every host must use the same cwd so the SDK identifies requests as belonging to the same project.

Connect your storage

The SDK does not ship a production-ready external store. Your application implements the SessionStore protocol against shared storage of its choice. A minimal implementation needs two async methods:
MethodWhat your application must do
append(key, entries)Store the new session data in the supplied order
load(key)Return all session data for the key, or None when it does not exist
Implement the following methods only when their features are needed:
MethodFeature enabled
list_sessions(project_key)Resume the latest session with continue_conversation=True and list stored sessions
delete(key)Delete a session from external storage
list_subkeys(key)Fully restore and inspect session data created by subagents
Treat key and entries as opaque SDK data. Store and return them without interpreting the message content.

Storage implementation checklist

Only developers implementing a SessionStore need to handle these requirements:
  • Preserve append order for each key, and return the complete history from load.
  • Keep data for different keys isolated.
  • The SDK may retry a failed append; production implementations must account for repeated delivery.
  • Return Unix epoch milliseconds in list_sessions().mtime, and list main sessions only.
  • Deleting a main session must also delete its child data.
  • Return relative identifiers from list_subkeys; never return absolute paths or paths containing . or ...
  • If multiple processes can write one session, serialize those writes in the storage layer.
Use run_session_store_conformance from qoder_agent_sdk.testing to check common behavior, and add backend-specific concurrency and retry tests. Connection management, access control, encryption, backup, migrations, and retention remain the application's responsibility.

Use it in your application

Pass the store in QoderAgentOptions.session_store for every query that should save or restore an external session.
  • Known session ID: use resume
  • Most recent session for the project: use continue_conversation=True and implement list_sessions
  • Session management: use list_sessions_from_store, get_session_messages_from_store, rename_session_via_store, tag_session_via_store, fork_session_via_store, or delete_session_via_store
  • Import an existing local session: use import_session_to_store

Limitations and operations

  • An external write failure does not stop the current conversation. The SDK emits SDKMirrorErrorMessage after the final failure; monitor this message when completeness matters.
  • External reads wait up to 60 seconds by default. Configure this with load_timeout_ms.
  • session_store_flush defaults to "batched"; "eager" writes sooner but makes more storage requests.
  • If an explicitly resumed session is absent from the store, the SDK can still try a local session with the same ID.
  • Python session storage cannot be combined with file checkpointing, a custom transport, or the experimental Cloud Agent runtime. It requires the built-in subprocess transport.
  • SessionStore saves session history only. It does not save authentication state, application configuration, file checkpoints, or retention policy.