# Multiple Claude Code Sessions Sharing the Same Codex Runtime Instance: Key Implications

> Explore the implications of multiple Claude Code sessions sharing a single Codex runtime instance. Learn how session IDs ensure isolated metadata while the broker process remains shared.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: deep-dive
- Published: 2026-08-04

---

**When multiple Claude Code sessions connect to the same Codex runtime instance, each session maintains isolated job metadata through unique session IDs while sharing a single underlying broker process.**

The openai/codex-plugin-cc repository implements a broker-based architecture that lets multiple Claude sessions reuse one Codex runtime per repository. While this design reduces resource overhead, it introduces specific behaviors around job isolation, resumption, and contention that developers need to understand.

## How the Shared Runtime Detection Works

The plugin determines whether to use a shared or direct runtime through `getSessionRuntimeStatus()` in `plugins/codex/scripts/lib/codex.mjs`.

This function checks for an existing broker endpoint via the `CODEX_COMPANION_BROKER_ENDPOINT` environment variable or a persisted [`broker.json`](https://github.com/openai/codex-plugin-cc/blob/main/broker.json) file. When found, it returns a **shared session** configuration:

```typescript
// plugins/codex/scripts/lib/codex.mjs
export function getSessionRuntimeStatus(env = process.env, cwd = process.cwd()) {
  const endpoint = env?.[BROKER_ENDPOINT_ENV] ?? loadBrokerSession(cwd)?.endpoint ?? null;
  if (endpoint) {
    return {
      mode: "shared",
      label: "shared session",
      detail: "This Claude session is configured to reuse one shared Codex runtime.",
      endpoint
    };
  }
  // …direct‑startup fallback
}

```

If no endpoint is available, the plugin falls back to **direct startup** mode and spawns a fresh runtime for each command.

## Session Isolation Despite Shared Infrastructure

### Job Metadata Is Bound to Session ID

Each Claude session receives a unique identifier through `CODEX_COMPANION_SESSION_ID`. The plugin records this ID with every job, ensuring that commands only operate on data from the current session.

For example, when checking status without specifying a job ID, the implementation filters by the current session's ID. This behavior is verified in `tests/status.test.mjs` at lines 6310-6328, confirming that `status` output excludes jobs from other Claude sessions even when they share the same broker.

### Cross-Session Resumption Is Explicitly Blocked

Attempting to resume a task created by a different Claude session fails intentionally. The `task --resume-last` command returns:

```

Error: No previous Codex task thread was found for this repository.

```

This safeguard appears in `tests/runtime.test.mjs` at lines 7236-7244, demonstrating that the plugin treats each Claude session's job history as strictly separate.

## Broker Lifecycle and Repository Scoping

The broker process follows **per-repository** rather than per-session semantics. Key characteristics include:

- **Lazy initialization** — The broker starts only when a review or task first requires the runtime
- **State persistence** — The [`broker.json`](https://github.com/openai/codex-plugin-cc/blob/main/broker.json) file stores the endpoint, PID, and log location in the repository's state directory
- **No session ID embedding** — The broker state does not track which Claude sessions are connected

This design means multiple Claude sessions can discover and connect to the same broker endpoint, but they each maintain independent session metadata in their environment variables.

## Request Contention and Performance Considerations

While job metadata is isolated, the underlying Codex process handles requests sequentially through the broker socket. Simultaneous heavy tasks from multiple Claude sessions queue on the same broker, potentially increasing latency.

The plugin provides mitigation through **background execution**:

```bash
$ codex task --background --json "investigate the flaky test"
{
  "status": "queued",
  "jobId": "task-12345"
}

```

This allows the broker to process jobs asynchronously while returning control to the CLI immediately.

## Graceful Degradation on Connection Failure

If a session cannot connect to the shared broker—whether due to socket conflicts, malformed endpoints, or broker shutdown—`getSessionRuntimeStatus()` automatically falls back to direct startup. This ensures that one misbehaving or disconnected session does not block others from executing commands.

## Practical Verification Examples

**Checking your current runtime mode:**

```bash
$ codex status --json
{
  "sessionRuntime": {
    "mode": "shared",
    "label": "shared session",
    "detail": "This Claude session is configured to reuse one shared Codex runtime.",
    "endpoint": "unix:/tmp/cxc-xxxx/broker.sock"
  },
  …
}

```

**Demonstrating isolation with manually set session IDs:**

```bash
$ export CODEX_COMPANION_SESSION_ID=sess-alice
$ codex task --resume-last "follow up"
Error: No previous Codex task thread was found for this repository.

```

**Monitoring a background task across the shared broker:**

```bash
$ codex status task-12345 --wait --json
{
  "job": { "id": "task-12345", "status": "completed" },
  …
}

```

## Key Source Files

| File | Purpose |
|------|---------|
| `plugins/codex/scripts/lib/codex.mjs` | Runtime mode detection and session status determination |
| `plugins/codex/scripts/lib/broker-lifecycle.mjs` | Broker creation, loading, and teardown operations |
| `tests/runtime.test.mjs` | Validation of shared session behavior and resume isolation |
| `tests/status.test.mjs` | Verification of session-scoped job filtering |
| `tests/task.test.mjs` | Cross-session resume blocking tests |

## Summary

- **Shared runtime ≠ shared jobs** — The broker process is shared per repository, but `CODEX_COMPANION_SESSION_ID` isolates each Claude session's job metadata
- **Resumption is session-bound** — `task --resume-last` and similar commands refuse to access jobs from other sessions
- **Status visibility is filtered** — Commands show only the current session's jobs unless a specific job ID is provided
- **Automatic fallback exists** — Connection failures trigger direct startup mode rather than blocking execution
- **Contention is possible** — Heavy concurrent workloads queue through the single broker socket; use `--background` to reduce blocking

## Frequently Asked Questions

### Can two Claude sessions accidentally interfere with each other's running tasks?

No. Each session's jobs are tagged with a unique `CODEX_COMPANION_SESSION_ID`, and commands like `status` and `task --resume-last` filter by this ID. Even when connected to the same broker endpoint, one session cannot list or modify another session's job state.

### What happens if the broker process crashes while multiple sessions are connected?

Sessions automatically fall back to **direct startup** mode on their next command invocation. The `getSessionRuntimeStatus()` function detects the missing or invalid endpoint and spawns a fresh runtime process instead of failing. No manual intervention is required.

### Why can't I resume a task started in a different terminal window?

Terminal windows running Claude Code typically receive different `CODEX_COMPANION_SESSION_ID` values. The plugin intentionally blocks cross-session resumption to prevent accidental continuation of work that may belong to a different user context or environment configuration.

### Does background execution bypass the shared broker queue?

No. Background tasks still route through the same broker socket. The `--background` flag changes the CLI's behavior—it returns immediately after queuing rather than waiting for completion—but the task executes through the shared runtime alongside foreground requests from all connected sessions.