# plottypus self-cost measurements (perf-smoke, M5 Pro, macOS 27)

What plottypus costs to leave open in a terminal, measured the same way at every step of
its 1.0 development, next to btop 1.4.7 and macmon 0.8.2 on the same machine. One row is one
metric of one tool at one interval: the median of three 20 s windows, with the range
across the three runs where it was recorded.

Page: https://plottypus.com/data/plottypus-self-cost · License: CC BY 4.0

## The figures the site prints

From set `perf-pass`, build `c1ed16d6e0f21e8b` (the pre-tag build after the 1.0 performance
pass), 2026-09-23 22:09 to 22:14 IST, light load:

| | 500 ms (default) | 1 s |
|---|---:|---:|
| `cpu_pct`, % of one core, median (range) | 1.48 (1.41 to 1.59) | 1.01 (1.01 to 1.07) |
| `energy_w` | 0.007 | 0.006 |
| `wakeups_per_s` | 4.7 | 2.5 |

Idle redraws are 0 per second in `after-wave-1` and `saturated-session`. The `baseline` set
shows the 82 to 106 per second they replaced.

## Load: read this before comparing rows

The test machine was never idle. Every row carries the 1-minute load average range and a
`load_class`:

| `load_class` | Sets | 1-minute load (18 logical CPUs) | What was running |
|---|---|---|---|
| `light` | `baseline`, `competitors`, `after-wave-1`, `perf-pass` (2026-09-23) | 1.2 to 3.8 | other agents building in parallel worktrees |
| `saturated` | `saturated-session` (2026-09-24, 00:29 to 00:36) | 56.26 to 142.87 | load generators (`yes`) and a cargo build |

The saturated rows came out lower for plottypus (0.862% at 500 ms, 0.691% at 1 s, on the
shipped 1.0.0 binary) than the light rows. That does not make them better data, so the site
prints the light-load figures. A quiet, back-to-back re-run of plottypus, btop and macmon is
still to do.

Within one set the tools ran back to back, minutes apart. Compare tools within a set, not
across sets.

## Machine

MacBook Pro Mac17,8, Apple M5 Pro (6 Super + 12 Performance cores, 20-core GPU, 24 GB),
macOS 27.0, AC power, no sudo. About 820 to 900 processes on the machine.

## Method (perf-smoke)

`perf-smoke.py` (in the plottypus repository) starts the binary under a pseudo-terminal at
160×45 with a fresh temporary `XDG_CONFIG_HOME`, `TERM=xterm-256color`, `COLORTERM=truecolor`,
and answers the terminal queries a real emulator would (cursor position, DA1, DECRQM, OSC 10/11),
so a query never stalls startup. It waits 5 s, samples every counter, reads the pty for 20 s,
samples again, then quits the program. `--runs 3` repeats this with three fresh processes and
reports the median of each metric. No keys are sent unless the `condition` column says so.

| `metric` | Unit | Source |
|---|---|---|
| `cpu_pct` | % of one core | `proc_pid_rusage(RUSAGE_INFO_V6)`: `ri_user_time + ri_system_time` over the window |
| `energy_w` | W | `ri_energy_nj` delta over wall time: the kernel's per-task energy estimate |
| `wakeups_per_s` | per second | `ri_interrupt_wkups + ri_pkg_idle_wkups` |
| `draws_per_s` | per second | `ESC[?2026h` synchronized-update markers in the output (not measurable for macmon, which does not use them) |
| `content_draws_per_s`, `idle_draws_per_s` | per second | draws that did / did not paint anything once escape sequences are stripped |
| `bytes_per_s` | bytes/s | bytes read from the pty |
| `read_chunks_per_s` | per second | `read(2)` calls on the pty that returned data |
| `syscalls_per_s`, `csw_per_s` | per second | `PROC_PIDTASKINFO`: Unix + Mach syscalls, context switches |
| `rss_mb`, `footprint_mb` | MB | `ri_resident_size`, `ri_phys_footprint` at the end of the window |
| `first_frame_ms` | ms | spawn to the first synchronized-update marker |
| `snapshot_period_ms_mean`, `_p50`, `_p99`, `_max` | ms | gaps between content frames: a proxy for the real sampling period |

## File

| File | Rows | One row is |
|---|---:|---|
| `self-cost.csv` | 240 | one metric for one set, tool, interval and condition |

### Columns

| Column | Meaning |
|---|---|
| `set_id` | `baseline`, `after-wave-1`, `perf-pass`, `competitors`, `saturated-session` |
| `date`, `time_window_local`, `timezone` | when the set ran (IST, +05:30). For `saturated-session` the time is the result file's write time |
| `load_class`, `loadavg_1m_min`, `loadavg_1m_max` | see Load above |
| `tool`, `tool_version` | `plottypus` (a named pre-release build, or `1.0.0 (release tarball binary)`), `btop` 1.4.7, `macmon` 0.8.2 |
| `binary_sha256_prefix` | first 16 hex digits of the plottypus binary's SHA-256 |
| `interval_ms` | the tool's sampling interval |
| `condition` | `default`, `update_ms = 1000` (btop at 1 s), `pointer moving at 50 Hz`, `frozen (f), one 10 s window` |
| `runs` | windows behind the median (3, or 1 for the single-run conditions) |
| `metric`, `unit` | see Method |
| `median`, `range_min`, `range_max` | the value; the range across runs where it was recorded (empty otherwise) |
| `source`, `source_section` | where the number was published first |

The light-load rows are transcribed by a script from the tables in the plottypus research note
`docs/research/12-self-cost.md` (every cell with a median, parsed, not retyped). The saturated
rows come straight from the perf-smoke JSON files of that session.

## What is not here

- Per-thread CPU breakdowns (they are ranges across runs, not medians).
- Measurements of unreleased 1.1 builds.
- The two runs that opened the saturated session (00:26 to 00:29, load 22 to 47), which used a
  local build of the 1.0.0 source rather than the release-tarball binary measured here.
- mactop, bottom and zenith: not measured with this method.
- The per-run screen captures in the perf-smoke JSON, which include process names.

## License and citation

CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Use it for anything, with credit.
This license covers the data files in this folder only, not the plottypus software.

> Sheth, L. (2026). plottypus self-cost measurements (perf-smoke, M5 Pro, macOS 27)
> (Version 1.0) [Data set]. plottypus.com. https://plottypus.com/data/plottypus-self-cost

Contact: Lay Sheth, hello@plottypus.com.

## Checksums (SHA-256)

```text
f91a2e65c67586cc71e5eefd4eab260353bbf329d06bf3910559ebd14bf6ad62  self-cost.csv
```

Verify with `shasum -a 256 -c` against these lines, or against https://plottypus.com/data/SHA256SUMS.
