> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boat.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Command history

> Read the output of past commands and processes in a sandbox, also when the sandbox is stopped, and list the processes.

Boat keeps the output of the processes in a sandbox. You can read it while the sandbox is stopped. A sandbox created with [monitoring off](/data-retention/snapshots-and-monitoring-off#monitoring-off) has no history.

In the dashboard, open the **⋯** menu of a sandbox and select **History**. A background command that runs shows its output live. You can stop it there.

## What Boat keeps

| Source | Mode | Kept for |
| - | - | - |
| A command you run through `boat exec` or the commands endpoint | `sync`, `stream` or `detached` | 90 days |
| Any other process that writes output: an `ssh` session, a systemd service, a docker container, a process that an agent starts | `process` | 72 hours |

The start answer of each command holds the `commandId` of its record.

| Kept | Details |
| - | - |
| The command | Its text (first 64 KiB), working directory, mode, process id |
| The result | `status` (`running`, `exited`, `timed_out`, `failed`, `killed`, `lost`), exit code, signal, start and end time |
| The output | stdout and stderr, compressed. A waiting command keeps up to 8 MiB per stream, the same as its answer. A streamed command adds output every 2 seconds. A detached command adds output every 30 seconds, and one more time when the sandbox stops. |

## Read the history

1. List the history.
2. Read the output of one command.

<CodeGroup>
  ```bash CLI theme={null}
  boat history bx_f7k2q9hd
  # cmd_k3v9x2mq7tbw  exit 0      detached  2026-10-09 14:02:11  npm run build
  boat history bx_f7k2q9hd cmd_k3v9x2mq7tbw            # stdout
  boat history bx_f7k2q9hd cmd_k3v9x2mq7tbw --stderr
  boat history bx_f7k2q9hd cmd_k3v9x2mq7tbw --follow   # until it ends
  boat history bx_f7k2q9hd --mode commands              # only what you ran
  boat history bx_f7k2q9hd --mode process               # only the other processes
  ```

  ```bash curl theme={null}
  curl -sS "$BOAT_API_BASE/sandboxes/$BOAT_ID/command-history?limit=20&mode=commands" \
    -H "Authorization: Bearer $BOAT_API_KEY"
  # {"type":"command.list","commands":[{"commandId":"cmd_k3v9x2mq7tbw","status":"exited","exitCode":0,...}],"nextCursor":null}

  curl -sS "$BOAT_API_BASE/sandboxes/$BOAT_ID/command-history/cmd_k3v9x2mq7tbw/logs?stream=stdout&offset=0" \
    -H "Authorization: Bearer $BOAT_API_KEY"
  # {"type":"command.logs","offset":0,"nextOffset":1830,"size":1830,"data":"...","done":true}
  ```

  ```ts TypeScript theme={null}
  const { commands } = await sandbox.commandHistory({ sandboxId, limit: 20, mode: "commands" });

  let offset = 0;
  for (;;) {
    const page = await sandbox.commandLogs({ sandboxId, commandId: commands[0].commandId, stream: "stdout", offset });
    process.stdout.write(page.data);
    offset = page.nextOffset;
    if (page.done) break;
    if (!page.data) await new Promise((r) => setTimeout(r, 2000)); // still running
  }
  ```

  ```python Python theme={null}
  import sys, time

  page = sandbox.command_history(sandbox_id, limit=20, mode="commands")
  command_id = page.commands[0].command_id

  offset = 0
  while True:
      logs = sandbox.command_logs(sandbox_id, command_id, stream="stdout", offset=offset)
      sys.stdout.write(logs.data)
      offset = logs.next_offset
      if logs.done:
          break
      if not logs.data:
          time.sleep(2)  # still running
  ```
</CodeGroup>

* Each read gives at most 1 MiB.
* Read again from `nextOffset` until `done` is `true`.
* To get the exact bytes of binary output, pass `encoding=base64`.

<Note>
  An account keeps at most 10 MiB of compressed command output per hour. This is about 50 MiB of plain text. Boat drops the output past that, and the command shows `outputTruncated: true`.
</Note>

## Every process in the sandbox

Boat records what each process writes to its terminal, to a pipe, or to a socket such as the journal. You do not change your programs for this. Each process is one `process` record, with its command line, its process id and its exit code.

| Rule | Details |
| - | - |
| Rate | Up to 64 KiB/s per process, with bursts up to 1 MiB. Output past that is dropped and the record shows `outputTruncated: true`. |
| Account cap | 10 MiB of compressed process output per hour, separate from the command cap. Output past that is dropped and the record shows `outputTruncated: true`. |
| Not recorded | Writes to regular files and to `/dev/null`, binary output, and the services that Boat itself runs in the sandbox. |
| Delay | New output appears within about 30 seconds. Output still on the sandbox when it stops is saved before the stop. |

Boat records a command that you run through `boat exec` one time, as a command. Its child processes do not show again as `process` records.

<Tip>
  A busy sandbox has many short processes, such as shell prompts and login scripts. To see only what you ran, use `--mode commands` (`mode=commands` in the API). To see only the other processes, use `--mode process`.
</Tip>

## Retention and deletion

The history is account data, the same as your sandbox files.

* When you delete the sandbox, Boat deletes its history.
* With [zero data retention](/data-retention/zero-data-retention#enable-zero-data-retention), a stop queues the history for deletion with the rest of the sandbox.

## List processes

List every process in a sandbox, the busiest first.

A stopped sandbox answers with the last sample that Boat kept, and `live: false`. Boat takes the 12 busiest processes every 30 seconds and keeps them for 7 days.

<CodeGroup>
  ```bash CLI theme={null}
  boat ps bx_f7k2q9hd
  #     PID    CPU%     MEM MB  USER        HISTORY           COMMAND
  #    2210    98.0      812.4  user        cmd_k3v9x2mq7tbw  node build.js
  ```

  ```bash curl theme={null}
  curl -sS "$BOAT_API_BASE/sandboxes/$BOAT_ID/processes" \
    -H "Authorization: Bearer $BOAT_API_KEY"
  # {"type":"process.list","live":true,"total":64,"processes":[{"pid":2210,"user":"user","cpuPercent":98,"memoryMB":812.4,"command":"node build.js",...}]}
  ```

  ```ts TypeScript theme={null}
  const { live, processes } = await sandbox.processes({ sandboxId });
  ```

  ```python Python theme={null}
  listing = sandbox.processes(sandbox_id)
  ```
</CodeGroup>

On a running sandbox, each process with a history record shows its `commandId` in the HISTORY column. To read its output, run `boat history <sandbox> <commandId>`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.