# How to Configure Kubernetes Deployments with Persistent Session Storage for Copilot SDK

> Learn how to configure Kubernetes deployments for Copilot SDK with persistent session storage by mounting a PersistentVolumeClaim. Ensure state persistence across restarts and scaling.

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

---

**Mount a shared PersistentVolumeClaim at `/root/.copilot/session-state` and use explicit `sessionId` values when creating sessions to enable state persistence across pod restarts and horizontal scaling.**

The Copilot SDK persists session state on the local filesystem under `~/.copilot/session-state/` according to the official documentation in [`docs/features/session-persistence.md`](https://github.com/github/copilot-sdk/blob/main/docs/features/session-persistence.md). In Kubernetes environments, this data is ephemeral by default and disappears when pods restart or migrate. Configuring persistent session storage ensures that long-running AI coding sessions survive container crashes, node drains, and scaling events.

## Understanding Session Persistence Requirements

The SDK only persists sessions that have an explicit `sessionId` defined. Without a custom ID, the CLI treats sessions as transient and does not write checkpoint data to disk. Additionally, when running multiple CLI replicas behind a load balancer, the storage backend must support concurrent access from multiple pods to allow any replica to resume any session.

Key configuration requirements include:
- **Shared storage**: Use a `ReadWriteMany` PersistentVolume for horizontal scaling scenarios
- **Explicit session IDs**: Required for the SDK to trigger persistence logic
- **Mount path**: Must align with the SDK default at `/root/.copilot/session-state`
- **Cleanup policies**: Optional idle timeout configuration via `CopilotClientOptions`

## Step 1: Create a Shared PersistentVolumeClaim

For multi-pod deployments, define a PersistentVolumeClaim that supports concurrent access. According to [`docs/setup/scaling.md`](https://github.com/github/copilot-sdk/blob/main/docs/setup/scaling.md), this enables the horizontal scaling pattern where any pod can serve any session.

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: copilot-sessions-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

```

Use `ReadWriteMany` access mode when running multiple CLI replicas. For single-pod deployments, `ReadWriteOnce` is sufficient, but prevents horizontal scaling.

## Step 2: Mount the Volume in Your Deployment

Configure the Deployment to mount the PVC at the SDK's default session state location. The Copilot CLI requires write access to `/root/.copilot/session-state` to create checkpoint files.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: copilot-cli
spec:
  replicas: 3
  selector:
    matchLabels:
      app: copilot-cli
  template:
    metadata:
      labels:
        app: copilot-cli
    spec:
      containers:
        - name: copilot-cli
          image: your-registry/copilot-cli:latest
          args: ["--headless", "--host", "0.0.0.0", "--port", "4321"]
          env:
            - name: COPILOT_GITHUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: copilot-secrets
                  key: github-token
          ports:
            - containerPort: 4321
          volumeMounts:
            - name: session-state
              mountPath: /root/.copilot/session-state
      volumes:
        - name: session-state
          persistentVolumeClaim:
            claimName: copilot-sessions-pvc

```

Expose the CLI via a Kubernetes Service to enable internal cluster communication:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: copilot-cli
spec:
  selector:
    app: copilot-cli
  ports:
    - port: 4321
      targetPort: 4321

```

## Step 3: Implement Explicit Session IDs

As documented in [`docs/features/session-persistence.md`](https://github.com/github/copilot-sdk/blob/main/docs/features/session-persistence.md), you must provide a custom `sessionId` when calling `createSession()`. The SDK only writes state to disk for sessions with explicit identifiers.

```typescript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient({
  cliUrl: "http://copilot-cli:4321",
});

// Create a resumable session with a deterministic ID
const session = await client.createSession({
  sessionId: `user-${userId}-task-${Date.now()}`,
  model: "gpt-5.2-codex",
});

// Perform work
await session.sendAndWait({ prompt: "Analyze repository files" });

// Disconnect keeps state on disk
await session.disconnect();

```

## Step 4: Configure Automatic Cleanup (Optional)

Prevent storage exhaustion by configuring idle timeouts via `CopilotClientOptions.sessionIdleTimeoutSeconds`. This setting triggers automatic cleanup of inactive session files as described in the *Automatic cleanup* section of [`docs/features/session-persistence.md`](https://github.com/github/copilot-sdk/blob/main/docs/features/session-persistence.md).

```typescript
const client = new CopilotClient({
  cliUrl: "http://copilot-cli:4321",
  sessionIdleTimeoutSeconds: 30 * 60, // 30 minutes
});

```

## Resuming Sessions Across Pod Restarts

With persistent storage mounted, any pod in the deployment can resume sessions created by previous instances. Use the `resumeSession()` method with the original session ID:

```typescript
// Resume from any pod in the cluster
const resumed = await client.resumeSession("user-42-task-1706932800");
await resumed.sendAndWait({ prompt: "Continue where we left off" });

```

This capability fulfills the horizontal scaling requirements outlined in [`docs/setup/scaling.md`](https://github.com/github/copilot-sdk/blob/main/docs/setup/scaling.md), allowing load balancers to route follow-up requests to any available replica.

## Key Source Files Reference

- **[`docs/features/session-persistence.md`](https://github.com/github/copilot-sdk/blob/main/docs/features/session-persistence.md)**: Defines session persistence semantics, required `sessionId` usage, and cleanup policies
- **[`docs/setup/scaling.md`](https://github.com/github/copilot-sdk/blob/main/docs/setup/scaling.md)**: Documents horizontal scaling patterns and shared storage requirements for multi-pod deployments
- **[`docs/setup/backend-services.md`](https://github.com/github/copilot-sdk/blob/main/docs/setup/backend-services.md)**: Provides configuration details for running the CLI as a backend service, including `cliUrl` setup

## Summary

- **Mount location**: Configure PVCs at `/root/.copilot/session-state` to match the SDK default
- **Access mode**: Use `ReadWriteMany` for horizontal scaling; `ReadWriteOnce` works only for single-pod deployments
- **Session IDs**: Always provide explicit `sessionId` values to `createSession()`—the SDK only persists named sessions
- **Resumption**: Use `resumeSession()` with the original ID to restore state after pod restarts
- **Cleanup**: Configure `sessionIdleTimeoutSeconds` to automatically remove stale session files

## Frequently Asked Questions

### Why does the Copilot SDK require explicit session IDs for persistence?

The SDK treats sessions without custom IDs as transient to prevent disk pollution from temporary connections. According to [`docs/features/session-persistence.md`](https://github.com/github/copilot-sdk/blob/main/docs/features/session-persistence.md), only sessions created with an explicit `sessionId` parameter trigger the persistence mechanism that writes checkpoint data to `~/.copilot/session-state/`.

### What storage access mode should I use for multi-pod deployments?

Use `ReadWriteMany` (RWX) access mode for the PersistentVolumeClaim. As documented in [`docs/setup/scaling.md`](https://github.com/github/copilot-sdk/blob/main/docs/setup/scaling.md), this allows multiple pods to simultaneously read and write session data, enabling any replica to resume any session. `ReadWriteOnce` restricts access to a single node and prevents horizontal scaling.

### Can I run the Copilot CLI in Kubernetes without persistent storage?

Yes, but sessions will be lost when pods restart or migrate. Without a mounted PVC at `/root/.copilot/session-state`, the SDK stores checkpoints on the container's ephemeral filesystem, which is destroyed when containers stop. Use persistent storage for production workloads requiring session continuity.

### How do I configure session timeouts to prevent storage exhaustion?

Set the `sessionIdleTimeoutSeconds` option in `CopilotClientOptions` when initializing the client. This parameter defines how long the SDK retains inactive session files before automatic deletion, as implemented in the automatic cleanup logic described in [`docs/features/session-persistence.md`](https://github.com/github/copilot-sdk/blob/main/docs/features/session-persistence.md).