# How the Job Pruning Mechanism Works in the Codex Plugin: MAX_JOBS Explained

> Understand the Codex plugin's MAX_JOBS limit and job pruning. Learn how it prevents memory growth by keeping only the 50 newest job records.

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

---

**The Codex plugin enforces a hard limit of 50 concurrent job records by slicing the internal array to retain only the newest entries whenever the job history is accessed, preventing unbounded memory growth during long sessions.**

The openai/codex-plugin-cc repository implements a defensive **job pruning mechanism** to manage memory usage during extended coding sessions. This system relies on the `MAX_JOBS` constant to cap the number of retained job objects, ensuring the plugin remains lightweight even when hundreds of tasks are submitted. Understanding this limit is essential for developers building tools on top of the Codex plugin API.

## Where MAX_JOBS Is Defined

In `plugins/codex/scripts/lib/state.mjs`, the constant is declared at line 13:

```typescript
// plugins/codex/scripts/lib/state.mjs
const MAX_JOBS = 50;               // ← maximum number of jobs to retain

```

This hardcoded value establishes the **maximum number of jobs to retain** in memory during a session, guaranteeing predictable resource usage regardless of session length.

## The Pruning Logic Implementation

The actual pruning occurs whenever the plugin exposes the recent job history. At line 83 of `state.mjs`, the code returns a sliced array containing only the first `MAX_JOBS` elements:

```typescript
// plugins/codex/scripts/lib/state.mjs
return recentJobs
  .slice(0, MAX_JOBS);            // ← prune to the limit

```

By calling `slice(0, MAX_JOBS)`, the plugin creates a shallow copy of the array containing only indices 0 through 49, effectively dropping any older entries without modifying the original data structure until the next tracking operation.

## How Tracked Jobs Interact with State

The `recentJobs` array is maintained by the **tracked-jobs** module located at `plugins/codex/scripts/lib/tracked-jobs.mjs`. This module records each job as it is created and, when asked for the list of jobs, delegates to the state module which applies the slice operation.

### Adding New Jobs to the Queue

New jobs are always added to the front of the internal list. The array grows temporarily as submissions accumulate, but the pruning logic only executes when the list is retrieved, not on every insertion.

### Retrieving the Pruned List

When `getRecentJobs()` is invoked from `tracked-jobs.mjs`, the state module applies the slice operation, silently dropping the oldest entries if the total exceeds 50. The most recent 50 jobs remain accessible via the public API, while earlier entries are discarded from the returned result.

## Practical Usage Example

The following example demonstrates the pruning behavior by simulating 60 job submissions:

```typescript
import { trackJob, getRecentJobs } from './plugins/codex/scripts/lib/tracked-jobs.mjs';

// Simulate submitting 60 jobs
for (let i = 1; i <= 60; i++) {
  trackJob({ id: i, command: `run-${i}` });
}

// Retrieve the pruned list – only the latest 50 jobs are kept
const jobs = getRecentJobs();
console.log(jobs.length);          // → 50
console.log(jobs[0].id);           // → 60 (most recent)
console.log(jobs[49].id);          // → 11 (oldest retained)

```

In this scenario, jobs 1 through 10 are automatically removed from the accessible history, while jobs 11 through 60 remain available for downstream processing such as result handling or session resumption.

## Summary

- **`MAX_JOBS` is defined as 50** in `plugins/codex/scripts/lib/state.mjs` at line 13
- **Pruning uses `Array.prototype.slice(0, MAX_JOBS)`** at line 83 to retain only the newest entries
- The **`tracked-jobs.mjs`** module provides `trackJob()` and `getRecentJobs()` for interaction with the job list
- **Oldest jobs are silently discarded** when the limit is exceeded, keeping only the 50 most recent
- This mechanism guarantees **predictable memory usage** during long sessions without manual intervention

## Frequently Asked Questions

### What is the default MAX_JOBS limit in the Codex plugin?

The default limit is **50 jobs**, defined as the constant `MAX_JOBS` at line 13 of `plugins/codex/scripts/lib/state.mjs`. This value determines the maximum number of job objects retained in memory during any given session.

### What happens when more than 50 jobs are submitted?

When the job count exceeds `MAX_JOBS`, the oldest entries are automatically removed via the slicing mechanism at line 83. Only the most recent 50 jobs remain accessible through the `getRecentJobs()` API, while earlier submissions are silently dropped from the returned array.

### Can the MAX_JOBS limit be configured at runtime?

No, `MAX_JOBS` is a hardcoded constant in the source code. To change the limit, you must modify the value in `plugins/codex/scripts/lib/state.mjs` and restart the plugin; there is no runtime configuration option exposed in the current implementation.

### Which files handle job pruning in the Codex plugin?

The pruning logic resides in `plugins/codex/scripts/lib/state.mjs`, which declares the constant and performs the slice operation. The companion file `plugins/codex/scripts/lib/tracked-jobs.mjs` maintains the `recentJobs` array and exposes the public `trackJob()` and `getRecentJobs()` functions that interact with the state module.