# Copilot SDK Session Persistence and Resumption Strategies: A Technical Deep Dive

> Explore Copilot SDK session persistence and resumption strategies. Learn how state is stored via SessionFsProvider for exact restarts by reloading state.json and SQLite databases.

- Repository: [GitHub/copilot-sdk](https://github.com/github/copilot-sdk)
- Tags: deep-dive
- Published: 2026-08-02

---

**The Copilot SDK persists sessions by storing state in a developer-configured directory through a pluggable `SessionFsProvider` interface, enabling exact resumption after restarts by reloading [`state.json`](https://github.com/github/copilot-sdk/blob/main/state.json) and SQLite databases from the persistence path.**

The GitHub Copilot SDK enables long-running conversational agents to survive process restarts and crashes through a robust persistence layer. According to the `github/copilot-sdk` source code, the SDK delegates all storage operations to an abstract file-system provider, allowing developers to choose between local disk, remote storage, or in-memory implementations while maintaining exact session state across lifecycles.

## How the Copilot SDK Persists Session State

### The SessionFsProvider Interface and Adapter

In [`sessionFsProvider.ts`](https://github.com/github/copilot-sdk/blob/main/sessionFsProvider.ts), the SDK defines the **`SessionFsProvider`** interface that abstracts all storage operations. The `createSessionFsAdapter` function wraps this provider, translating thrown errors into the JSON-RPC-compatible **`SessionFsError`** format. This adapter exposes methods for file operations and SQLite queries, forwarding them directly to the underlying provider implementation without imposing filesystem-specific logic.

### Directory Structure and Incremental Updates

When a `Session` is instantiated via [`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts), the SDK creates a unique directory under the configured persistence root. The path follows the pattern `<sessionPersistencePath>/<session-id>/`, containing:

- [`state.json`](https://github.com/github/copilot-sdk/blob/main/state.json) – Stores serialized session state and conversation history
- `tool-outputs/` – Directory for tool execution artifacts
- `*.sqlite` files – Optional SQLite databases for structured conversational data

During normal operation, the SDK writes incremental updates to these locations through the adapter, treating the persisted files as the single source of truth for session recovery.

## Resuming Sessions After Process Restarts

### Detecting and Loading Existing Sessions

The [`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts) implementation checks for existing session directories when `startSession` is called with a `sessionId` parameter. If the directory exists, the SDK:

1. Loads [`state.json`](https://github.com/github/copilot-sdk/blob/main/state.json) through `SessionFsProvider.readFile`
2. Reopens SQLite databases via `sqliteQuery` or `sqliteTransaction` methods
3. Reconstructs the internal `Session` object with the restored context

This process enables exact session resumption even after host process crashes, container restarts, or application upgrades.

### Pluggable Storage Backends

Because the persistence layer relies on the abstract `SessionFsProvider` interface, developers can substitute the default Node.js file system with custom implementations. The SDK treats the provider's responses as authoritative, enabling resumption from in-memory mocks, cloud object storage, or distributed file systems without modifying core session logic in [`client.ts`](https://github.com/github/copilot-sdk/blob/main/client.ts).

## Practical Implementation Example

```typescript
import { createCopilotClient } from '@github/copilot-sdk';

// --------------------------------------------------------------------
// 1️⃣  Create a client that persists sessions to a local directory.
// --------------------------------------------------------------------
const client = createCopilotClient({
  // The SDK will create `<persistRoot>/<sessionId>/` for each session.
  sessionPersistencePath: '/tmp/copilot-sessions',
});

// --------------------------------------------------------------------
// 2️⃣  Start a new session (or resume an existing one by ID).
// --------------------------------------------------------------------
async function startOrResume(sessionId?: string) {
  const session = await client.startSession({ sessionId });
  console.log('Session ID:', session.id);

  // ----------------------------------------------------------------
  // 3️⃣  Use the session – file writes, SQLite queries, etc.
  // ----------------------------------------------------------------
  await session.fs.writeFile('notes.txt', 'Initial note');
  const content = await session.fs.readFile('notes.txt');
  console.log('File content:', content);

  // If the provider implements SQLite:
  await session.fs.sqliteQuery({
    queryType: 'run',
    query: 'CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, text TEXT);',
  });
  await session.fs.sqliteQuery({
    queryType: 'run',
    query: 'INSERT INTO notes (text) VALUES (?);',
    params: { 1: 'Persisted note' },
  });

  // ----------------------------------------------------------------
  // 4️⃣  The session state is automatically persisted to the directory.
  //    Restart the process and call `startOrResume(session.id)` to
  //    continue where you left off.
  // ----------------------------------------------------------------
}

// Example usage:
startOrResume();               // Starts a fresh session
// startOrResume('abc123');    // Resumes an existing session

```

## Summary

- The Copilot SDK uses a `SessionFsAdapter` in [`sessionFsProvider.ts`](https://github.com/github/copilot-sdk/blob/main/sessionFsProvider.ts) to abstract storage operations into a JSON-RPC-compatible interface that handles errors via `SessionFsError`.
- Session data persists to `<sessionPersistencePath>/<session-id>/`, including [`state.json`](https://github.com/github/copilot-sdk/blob/main/state.json) and optional SQLite databases, with incremental updates written during normal operation.
- Developers resume sessions by providing the same `sessionPersistencePath` and `sessionId` to `createCopilotClient`, which reloads state from existing directories through the `Session` class in [`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts).
- The pluggable `SessionFsProvider` interface supports custom backends, including remote storage and in-memory implementations, without requiring changes to core session logic.

## Frequently Asked Questions

### Where does the Copilot SDK store session data?

The SDK stores session data in a developer-configured directory specified by the **`sessionPersistencePath`** option passed to `createCopilotClient` in [`client.ts`](https://github.com/github/copilot-sdk/blob/main/client.ts). Each session receives a subdirectory named after its `sessionId`, containing files like [`state.json`](https://github.com/github/copilot-sdk/blob/main/state.json) and any SQLite databases used during the conversation.

### How do I resume a Copilot SDK session after a process crash?

To resume a session, instantiate a new client with the same `sessionPersistencePath` and call **`startSession`** with the previous `sessionId`. The SDK automatically detects the existing directory in [`session.ts`](https://github.com/github/copilot-sdk/blob/main/session.ts), loads the saved [`state.json`](https://github.com/github/copilot-sdk/blob/main/state.json), and reopens SQLite connections through the provider interface.

### Can I use a custom database or remote storage instead of the local file system?

Yes. The SDK exports the **`SessionFsProvider`** interface from [`sessionFsProvider.ts`](https://github.com/github/copilot-sdk/blob/main/sessionFsProvider.ts), allowing you to implement custom `readFile`, `writeFile`, and `sqliteQuery` methods. Pass your custom provider to the session configuration to redirect persistence to cloud storage, distributed databases, or in-memory mocks.

### What files are created in the persistence directory?

The SDK creates **[`state.json`](https://github.com/github/copilot-sdk/blob/main/state.json)** for serialized session state, a **`tool-outputs/`** subdirectory for artifacts, and any **`*.sqlite`** files for structured data. These files serve as the single source of truth for session resumption strategies.