How to Achieve Session Persistence Across Restarts with the Copilot SDK

To achieve session persistence across restarts with the Copilot SDK, pass a persistent SessionFsProvider adapter—such as SQLiteSessionAdapter or FileSystemSessionAdapter—to the sessionFs option when constructing CopilotClient, which automatically rehydrates the full session graph on startup.

The GitHub Copilot SDK stores all runtime state—including chat history, generated code, and pending tool calls—inside a session file system. By default, this data is written to a temporary directory that is destroyed when the process exits, so developers who need continuity must configure a durable backend. Achieving session persistence across restarts requires selecting one of the built-in storage adapters and wiring it into the CopilotClient initialization as implemented in github/copilot-sdk.

How the Copilot SDK Persists Session State

The persistence layer is built around three core abstractions in the Node.js source tree. Understanding their roles makes it clear why the SDK can survive process restarts without losing context.

Session Orchestrator (nodejs/src/session.ts)

The Session class is the high-level wrapper that drives the RPC session, routes events, and exposes the client API. It delegates every load and save operation to an injected SessionFsProvider. When the SDK starts, Session calls the provider's load routine to reconstruct the in-memory graph from disk.

SessionFsProvider and Adapters (nodejs/src/sessionFsProvider.ts)

SessionFsProvider abstracts the file-system layer. According to the Copilot SDK source code, this single file ships with two built-in adapters:

  • FileSystemSessionAdapter — Stores each session object as a separate JSON file under a directory you specify. This is a simple file-IO approach best suited for development or small-scale usage.
  • SQLiteSessionAdapter — Persists every session event in a SQLite database file. It guarantees atomic writes and scales better for larger workloads.

Both adapters implement write, read, and list methods. Every state-changing event is streamed through SessionFsProvider.write(event) and flushed immediately, so the backing store always reflects the latest state.

Client Entry Point (nodejs/src/client.ts)

client.ts exposes the developer-facing API. It accepts a sessionFs option that accepts an adapter instance. On startup, the client builds a Session object, which invokes SessionFsProvider.load() to restore any previously persisted graph and rehydrate pending tool calls.

Sample Implementation (nodejs/samples/manual-tool-resume.ts)

The repository includes manual-tool-resume.ts, a real-world sample that demonstrates how to create a client with a persistent SQLite store and resume interaction after a simulated crash.

Enable Session Persistence Across Restarts with the SQLite Adapter

The SQLiteSessionAdapter is the recommended choice for production because it provides atomic writes and keeps all session data in a single file.

In nodejs/src/sessionFsProvider.ts, the adapter constructor expects a file path. The following example shows the exact option shape used to wire it into CopilotClient:

import { CopilotClient } from '@github/copilot-sdk';
import { SQLiteSessionAdapter } from '@github/copilot-sdk/nodejs';

// 1. Choose a location for the SQLite DB (created automatically if missing)
const dbPath = '/var/tmp/copilot_sessions.db';

// 2. Build the client with the persistent adapter
const client = new CopilotClient({
  // ...other client options such as auth, model, etc.
  sessionFs: {
    adapter: new SQLiteSessionAdapter(dbPath),
  },
});

// 3. Start a chat; all generated events are persisted automatically
async function run() {
  const session = await client.startSession();
  await session.sendMessage({ role: 'user', content: 'Write a quicksort in Rust' });

  // When the process exits or crashes, the DB still holds the full session.
}

run().catch(console.error);

When the process restarts, instantiate CopilotClient with the same dbPath. The SDK runs SessionFsProvider.load(), reads the SQLite rows, rebuilds the session graph, and resumes exactly where the previous run stopped.

Enable Session Persistence Across Restarts with the File System JSON Adapter

If you prefer a directory of plain JSON files instead of a database, use FileSystemSessionAdapter. Each session object is serialized to its own session_<id>.json file under the directory you provide.

import { CopilotClient } from '@github/copilot-sdk';
import { FileSystemSessionAdapter } from '@github/copilot-sdk/nodejs';

const client = new CopilotClient({
  sessionFs: {
    adapter: new FileSystemSessionAdapter('/tmp/copilot_sessions'),
  },
});

Deleting the directory removes all persisted sessions. This adapter is ideal for local development or scenarios where human-readable session files are preferred.

Verifying Persistence Across Restarts

The Copilot SDK source includes dedicated tests that prove both adapters survive process restarts:

You can run the SQLite persistence test directly to verify your own integration:

npm run test:e2e -- nodejs/test/e2e/session_fs_sqlite.e2e.test.ts

Summary

  • The Copilot SDK defaults to a temporary directory for session state, which disappears on process exit.
  • To achieve session persistence across restarts, supply a durable adapter via the sessionFs option in CopilotClient.
  • Choose SQLiteSessionAdapter for atomic, single-file storage suited to production workloads.
  • Choose FileSystemSessionAdapter for lightweight, directory-based JSON storage during development.
  • The SDK flushes every event through SessionFsProvider.write(event), so the persisted store is always current and can be fully rehydrated on the next startup via SessionFsProvider.load().
  • Reference implementations live in nodejs/samples/manual-tool-resume.ts and test coverage is provided in nodejs/test/e2e/session_fs_sqlite.e2e.test.ts.

Frequently Asked Questions

What is the default session storage in the Copilot SDK?

By default, the SDK stores session data in a temporary directory using an ephemeral file-system adapter. Because the directory is destroyed when the process stops, all chat history, generated code, and tool-call context are lost unless you explicitly configure a persistent SessionFsProvider.

Which adapter should I use for production workloads?

Use SQLiteSessionAdapter as implemented in nodejs/src/sessionFsProvider.ts. It writes all session events to a SQLite database file, which provides atomic transactions and performs better under larger workloads than the directory-based JSON approach.

How does the SDK handle pending tool calls after a restart?

When CopilotClient starts with a persistent adapter, it invokes SessionFsProvider.load() to rebuild the in-memory session graph from the SQLite or JSON store. This process rehydrates pending tool calls and message history so the session can continue without requiring the user to replay prior steps.

Where are session event shapes defined in the source code?

The TypeScript interfaces for session events are defined in nodejs/src/generated/session-events.ts. Both the SQLiteSessionAdapter and FileSystemSessionAdapter conform to these shapes when serializing and deserializing state in nodejs/src/sessionFsProvider.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →