CI runner profile
CI runner profile
CI runner profile
Baseline resource profile for the shared-VPS CI path — Phase 0 of
.agents/plans/2026-10-08-ci-performance.md
(BRI-449). These numbers are indicators, not gates; per-run values come from
the resource-report steps and scripts/ci-step-timings.ts.
Baseline (measured 2026-10-08, last 3 green build-artifact runs on PRs)
| Job | Wall time | Step breakdown |
|---|---|---|
build |
~1m40s | mise-action 22-26s · bun install ~5s · “Build apps/web” 56-60s · compile activate ~1s · dbtools bundle 0-4s · pack ~11s · release publish ~0s |
boot-smoke |
~70s | mise ~22s · artifact download 6-14s · netns boot smoke 20-29s |
smoke-test-artifact |
~65s | artifact download ~8s · activate-subcommands drill ~29s |
deploy-pyinfra (push) |
~5m total | build + drift-gate + deploy serially |
Reading the memory numbers
memory.peak (cgroup) counts page cache, so it overstates real usage —
that is why the report prints the memory.stat split. Treat anon +
shmem as the process footprint; file is mostly reclaimable page cache
(source files, .output trees, the bun cache) and only matters when PSI
says the kernel is stalling on reclaim.
Top consumers per axis
- Time: the
apps/webvite/rolldown build (the single biggest step),
the mise tool restore (paid once per job, and the smoke jobs serialize
afterbuild), and the serialized smoke jobs themselves (each
re-downloads the artifact and re-does tool setup). - Memory: the vite/oxc build and the bun install/cache population.
- Disk: docker writable layers on the runner containers,
.output
trees, android/dotnet leftovers on hosted images. - Network:
bun install, the ffmpeg tool install, and apt fetches.
Soft thresholds
| Signal | Warn | Hard max |
|---|---|---|
memory.stat anon + shmem |
::warning:: above 4.5 GB |
6 GB (target for MemoryMax in Phase 2) |
memory PSI some avg60 |
::warning:: above 10 |
— |
How the scripts are invoked
In workflows (after jdx/mise-action, which is what provides bun):
- name: Resource report (start) # add --sample for the 2s sampler
if: always()
run: bun scripts/ci-resource-report.ts start
# ...job steps...
- name: Resource report (end)
if: always()
run: bun scripts/ci-resource-report.ts end
Per-step timings for before/after tables (read-only, needs gh auth):
bun scripts/ci-step-timings.ts --workflow build-artifact.yml --runs 10
bun scripts/ci-step-timings.ts --workflow build-artifact.yml --job build