---
title: memhtml session prune
description: "Remove session state nothing reads again, older than a cutoff: index files, `refs/memhtml/sessions/` refs, stale lock directories, and logs with zero ops. A log that still holds ops is never removed; it is listed under `unlanded`."
---

## 1. Synopsis

Remove session state nothing reads again, older than a cutoff: index files, `refs/memhtml/sessions/` refs, stale lock directories, and logs with zero ops. A log that still holds ops is never removed; it is listed under `unlanded`.

```sh
memhtml session prune --older-than <string> [options]
```

## 2. Arguments

This command takes no positional arguments.

## 3. Flags

| Flag | Type | Default | Values | Description |
| --- | --- | --- | --- | --- |
| `--older-than` | string | *no default* | *no fixed set* | The cutoff, as a duration with a unit: `7d`, `48h`, `90m`, `1.5h`, or `2 weeks`. A file counts by its last write, a ref by its commit's committer time; a lock directory also has to be stale (no refresh for 30 s), so a live writer's is never touched. Session state under `.memhtml/sessions/`: `<id>.idx` index files (a whole git index each, which no commit of this build reads or writes), `<id>.lock` directories a killed writer left (reclaimed otherwise only by the next writer of the same id, and a run's id is never written again), and `<id>.json` logs with zero ops (a session whose commit landed, or that never wrote). Every id is handled under its session lock, so a writer of it is never pruned from under; an id whose lock is held is listed under `busy`. A log that still holds ops is a run whose writes have not landed: it is kept and listed under `unlanded` with its `id`, `ops`, `pending`, `modifiedAt`, and `age`, so it can be landed with `session commit --id <id> --message <summary> --drop-refused`. A log that does not decode is kept and listed under `unreadable`. `<id>.dropped.jsonl` trails are kept. **Required.** |
| `--dry-run` | flag | `false` | *no fixed set* | Report what a run would remove, with the same counts and lists, and remove nothing. Takes no lock. |

Every command also accepts the [global flags](/reference/global-flags/).

## 4. Response

On success the command writes one JSON envelope to stdout, and its `type` is `session.pruned`.

On failure it writes the failure envelope, whose `code` comes from [error codes](/reference/error-codes/).

[The JSON envelope](/reference/envelope/) gives the fields both shapes carry. [Response types](/reference/response-types/) lists every value `type` takes across the binary.

## 5. Further reading

No guide block names this command. The [guide](/reference/guide/) is the workflow prose the CLI ships beside the command table: which command to reach for, and in what order.

## 6. Provenance

A loader generates this page from `apps/cli/src/commands.ts` while the site builds, so no file in the repository holds it: the `COMMANDS` array there is the one source of argument parsing, of `memhtml manifest`, and of `AGENTS.md`. Change the registry and this page changes with it.