# How Tasks Are Spawned as Detached Processes for Background Jobs in Codex

> Learn how Codex spawns background jobs as detached processes using delivery detached. Explore how this enables the CLI to exit while the app server continues execution.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: internals
- Published: 2026-07-14

---

**Codex spawns background jobs as detached processes by setting `delivery: "detached"` in the task request, which the broker persists as `detached: true` in the job JSON file, allowing the CLI to exit immediately while the app-server continues execution in an isolated process group.**

When you need tasks spawned as detached processes for background jobs with Codex, the `openai/codex-plugin-cc` repository implements a specialized delivery mechanism that decouples the CLI lifecycle from the worker execution. The workflow spans command parsing, broker persistence, and process isolation to ensure background tasks survive terminal exits.

## Command Parsing and the Delivery Flag

When a user invokes the `task` command with the `--background` flag, the CLI translates this argument into a **delivery** configuration. In `plugins/codex/scripts/lib/codex.mjs` (lines 1020–1038), the code examines the delivery option and assigns the value `"detached"` when background execution is requested.

```javascript
// From plugins/codex/scripts/lib/codex.mjs
if (delivery === "detached") {
  // mark the thread as detached so the broker knows
  state.threadId = response.reviewThreadId;
}

```

## Thread Creation via runAppServerTask

The **runAppServerTask** function initiates the background worker by calling `startThread` on the Codex app-server. The request payload explicitly includes `delivery: "detached"` (lines 1026–1030 in *codex.mjs*), instructing the system to create an independent thread that persists after the parent shell returns.

```javascript
// Trigger a background task programmatically
await codex.runTask({ prompt, delivery: "detached" });

```

## Broker Persistence in broker-lifecycle.mjs

Once the broker receives the request in `plugins/codex/scripts/lib/broker-lifecycle.mjs`, it marks the job record with `detached: true` (lines 64–66). The broker writes this flag to the job’s JSON file on disk, creating a persistent record that survives CLI termination and enables status tracking across sessions.

```javascript
// Inside broker-lifecycle.mjs
await writeJobFile(jobPath, { ...job, detached: true });

```

## Process Isolation and Lifecycle Management

Because the job is flagged as detached, the Codex CLI **does not** wait for the app-server turn to finish. The CLI returns immediately to the shell, while the app-server continues running the task in its own process group. The **terminateProcessTree** helper can later target this entire group for cleanup if the job needs to be forcefully stopped.

## Monitoring Background Jobs with job-control.mjs

Background workers are exposed through status commands via the job-control utilities in `plugins/codex/scripts/lib/job-control.mjs`. The **enrichJob** function (lines 1550–1552) reads the `detached` flag from the job JSON and includes it in status snapshots. When running `/codex:status` or similar queries, the system identifies detached jobs with a background indicator.

```javascript
// Status command prints detached jobs
const status = buildStatusSnapshot(cwd);
status.running.forEach(j => {
  if (j.detached) console.log(`🔹 ${j.id} (background)`);
});

```

## Summary

- The `--background` flag triggers `delivery: "detached"` in the task request parsed by `codex.mjs`
- The broker stores `detached: true` in the job's JSON file at `plugins/codex/scripts/lib/broker-lifecycle.mjs`
- The CLI exits immediately while the app-server continues execution in an isolated process group
- Status queries via `enrichJob` in `plugins/codex/scripts/lib/job-control.mjs` expose detached workers for monitoring
- The `terminateProcessTree` helper can kill the entire process group when cleanup is required

## Frequently Asked Questions

### How do I spawn a background task in Codex?

Pass the `--background` flag to the `task` command. This sets `delivery: "detached"` in the request handled by `runAppServerTask`, creating a detached thread that persists after the CLI exits.

### Where does Codex store the detached status of a job?

The broker writes the `detached: true` flag to the job's JSON file on disk in `plugins/codex/scripts/lib/broker-lifecycle.mjs`. The `enrichJob` function in `plugins/codex/scripts/lib/job-control.mjs` reads this value when building status reports.

### Can I terminate a detached Codex process after the CLI exits?

Yes. Detached jobs run in their own process group, and the `terminateProcessTree` helper can target the entire group for cleanup. The job remains tracked in the Codex job store until explicitly removed or completed.

### How can I check if a background job is still running?

Query the job status using `/codex:status` or similar commands. The `buildStatusSnapshot` function checks the `detached` flag in the job JSON and displays running background jobs with a background indicator.