---
title: Adaptive Memory Paging for Sessions
---

# Adaptive Memory Paging for Sessions

## What it is

**What:** An opt-in, Windows-only feature that, under host physical-RAM
pressure, caps the resident working set of every Claude CLI session (and the
test processes they spawn) so Windows pages the overflow to the disk pagefile.
Frees physical RAM; sessions keep running, just slower. Off by default.

**Setting:** `sessionAdaptiveMemoryPaging` (boolean, default false) — Settings →
Performance, "Ease RAM pressure by paging busy sessions to disk".

## Where to find it

It is a setting rather than a screen of its own. Open Settings and go to the Performance section, where the row reads "Ease RAM pressure by paging busy sessions to disk" — switch it on there. It is off by default, and it is Windows-only: on macOS and Linux the toggle has no effect.

Nothing else in the app changes when you turn it on. No new panel, badge or menu appears; the trimming happens quietly in the background, and only while the machine is actually short on memory.

## How it behaves

### Why a working-set cap, not a memory cap

The Job Object also exposes `JobMemoryLimit` / `ProcessMemoryLimit` (commit
caps). We deliberately do **not** use them: exceeding a commit cap makes an
allocation _fail_, crashing the session mid-task. A working-set MAXIMUM is soft —
it only forces paging, so the process slows but survives. The user's requirement
was "page to disk, don't kill, keep spawning".

### Scope

Only the session Job Object. Test workers a session spawns are children inside
that job (no breakaway), so they inherit the cap. Omniscio's own Electron processes
are not in the job and are never trimmed.

### Tuning

`PER_PROCESS_MAX_BYTES` (~1 GB) is the one knob. Too low → pagefile thrash; too
high → frees too little. Tuned empirically; only engages above 85% load.
Assumes an SSD with pagefile headroom.

### Failure / no-op paths

- Non-Windows → `applyAdaptiveWorkingSet` returns false; sampler never starts.
- Job Object init failed at startup → `applyJobWorkingSetLimit` is a no-op.
- `GlobalMemoryStatusEx` / kernel32 load failure → the tick skips (logs, never throws).

### Source

- [src/main/process/adaptive-working-set.ts](../../src/main/process/adaptive-working-set.ts) — sampler + hysteresis + memory read.
- [src/main/process/job-object-win32.ts](../../src/main/process/job-object-win32.ts) — `setJobWorkingSetLimit` koffi wrapper.
- [src/main/process/job-object.ts](../../src/main/process/job-object.ts) — `applyJobWorkingSetLimit` cross-platform shim.
- [src/main/index.ts](../../src/main/index.ts) — applies at startup when enabled.
- [src/main/services/settings-apply.ts](../../src/main/services/settings-apply.ts) — re-applies live on toggle flip.
- [src/renderer/src/features/settings/PerformanceSettings.tsx](../../src/renderer/src/features/settings/sections/performance/PerformanceSettings.tsx) — the toggle.

### Tests

- [tests/unit/process/adaptive-working-set.test.ts](../../tests/unit/process/adaptive-working-set.test.ts) — hysteresis + injected ticks + non-Windows no-op.
- [tests/unit/process/job-object-noop.test.ts](../../tests/unit/process/job-object-noop.test.ts) — `applyJobWorkingSetLimit` false off-Windows.
- [tests/unit/services/settings-apply.test.ts](../../tests/unit/services/settings-apply.test.ts) — live start/stop wiring.

## For agents

### How it works

A 5-second sampler ([src/main/process/adaptive-working-set.ts](../../src/main/process/adaptive-working-set.ts))
reads host RAM-in-use via `GlobalMemoryStatusEx.dwMemoryLoad` (0–100).
Hysteresis:

- load **> 85%** → apply a per-process working-set MAXIMUM (~1 GB) to the
  singleton session Job Object (`JOB_OBJECT_LIMIT_WORKINGSET`).
- load **< 70%** → clear it.

The 15-point band prevents flapping. The limit is written through the Job
Object's shared `writeBasicLimits()` path, so it composes with — never stomps —
the CPU-rate cap, below-normal priority, and adaptive E-core affinity that may
also be active on the same job.

## Related

- [session-cpu-cap.md](session-cpu-cap.md) — the soft CPU-rate cap (sibling lever on the same Job Object).
- [amc-priority-boost.md](amc-priority-boost.md) — Omniscio priority boost + adaptive E-core delegation.
