Profiling Kenn Forge Performance
Core Rule
Measure the user-visible phase first, then use backend profiles to explain it. Keep the before/after workload, data, renderer, iteration count, and tracing configuration identical.
REQUIRED SUB-SKILL: Use kenn-forge-ephemeral-dev for copied-state stacks.
Choose the Lane
| Question |
Primary tool |
| Why is workspace switching or first paint slow? |
make profile-workspace-switch |
| Why is a real-data API slow or allocation-heavy? |
copied-state dev-ephemeral plus pprof and repeated curl |
| Which browser request matches which Go operation? |
User Timing wall-clock correlation with Go trace |
| Which distributed span owns the delay? |
opt-in OTel/Tempo diagnostic run after primary timing |
Read references/workflows.md for exact commands and artifacts.
Workflow
- Record provenance before measuring: commit SHA, dirty diff state, browser, renderer, platform, and command.
timings.json identifies HEAD, not uncommitted changes; commit first or preserve the tested patch explicitly.
- Capture a baseline before changing code. Use at least ten warm iterations; treat the harness's single cold sample as descriptive unless running multiple independent captures.
- Locate the phase:
- request end slow: API/database/backend;
- construction slow: Svelte/xterm/main thread;
- socket-open to first-bytes slow: WebSocket/tmux attach or replay;
- first-bytes to first-paint slow: terminal parsing/rendering/paint.
- Change one hypothesis at a time. Rerun the same lane and preserve raw artifacts, including outliers.
- For pprof deltas, separate request-path nodes from unrelated background observers. If background work dominates, report the process delta only as an upper bound; do not divide it by request count and label it request allocation.
A per-request allocation claim requires an isolated handler/benchmark lane with background observers absent.
- Reject changes whose measured benefit is smaller than run-to-run variance or disproportionate to memory, GPU, correctness, or maintenance cost.
- Report sample count, median, p95 convention, absolute delta, percentage delta, correctness checks, and artifact paths.
Evidence Contract
Keep:
summary.txt, timings.json, trace.chrome.json, and go-trace.out for switch runs;
- before/after pprof files and
go tool pprof -top output for backend runs;
- an adjacent equal-duration idle-control profile when background work is material;
- the copied status JSON and exact pprof address;
- a table separating ordinary-shell and alternate-screen results;
- accepted improvements and audited no-change decisions.
Common Mistakes
- Benchmarking a dirty tree while reporting only
HEAD.
- Using three iterations or presenting one cold sample as a distribution.
- Comparing different databases, browser versions, renderers, or trace settings.
- Discarding outliers without trace evidence.
- Treating
first-paint as LCP; it is Kenn Forge's second-animation-frame terminal marker.
- Profiling through a browser request; the pprof listener expects loopback tooling such as
curl.
- Stopping a stack or tmux session not created for the profiling run.
1---2name: profiling-kenn-forge-performance3description: Use when diagnosing Kenn Forge workspace-switch, terminal-rendering, browser-main-thread, API latency, allocation, CPU, tmux replay, or frontend/backend trace regressions with pprof, Playwright, User Timing, Go trace, or OpenTelemetry.4---56# Profiling Kenn Forge Performance78## Core Rule910Measure the user-visible phase first, then use backend profiles to explain it. Keep the before/after workload, data, renderer, iteration count, and tracing configuration identical.1112**REQUIRED SUB-SKILL:** Use kenn-forge-ephemeral-dev for copied-state stacks.1314## Choose the Lane1516| Question | Primary tool |17| --- | --- |18| Why is workspace switching or first paint slow? | `make profile-workspace-switch` |19| Why is a real-data API slow or allocation-heavy? | copied-state `dev-ephemeral` plus pprof and repeated `curl` |20| Which browser request matches which Go operation? | User Timing wall-clock correlation with Go trace |21| Which distributed span owns the delay? | opt-in OTel/Tempo diagnostic run after primary timing |2223Read [references/workflows.md](references/workflows.md) for exact commands and artifacts.2425## Workflow26271. Record provenance before measuring: commit SHA, dirty diff state, browser, renderer, platform, and command. `timings.json` identifies `HEAD`, not uncommitted changes; commit first or preserve the tested patch explicitly.282. Capture a baseline before changing code. Use at least ten warm iterations; treat the harness's single cold sample as descriptive unless running multiple independent captures.293. Locate the phase:30 - request end slow: API/database/backend;31 - construction slow: Svelte/xterm/main thread;32 - socket-open to first-bytes slow: WebSocket/tmux attach or replay;33 - first-bytes to first-paint slow: terminal parsing/rendering/paint.344. Change one hypothesis at a time. Rerun the same lane and preserve raw artifacts, including outliers.355. For pprof deltas, separate request-path nodes from unrelated background observers. If background work dominates, report the process delta only as an upper bound; do not divide it by request count and label it request allocation.36 A per-request allocation claim requires an isolated handler/benchmark lane with background observers absent.376. Reject changes whose measured benefit is smaller than run-to-run variance or disproportionate to memory, GPU, correctness, or maintenance cost.387. Report sample count, median, p95 convention, absolute delta, percentage delta, correctness checks, and artifact paths.3940## Evidence Contract4142Keep:4344- `summary.txt`, `timings.json`, `trace.chrome.json`, and `go-trace.out` for switch runs;45- before/after pprof files and `go tool pprof -top` output for backend runs;46- an adjacent equal-duration idle-control profile when background work is material;47- the copied status JSON and exact pprof address;48- a table separating ordinary-shell and alternate-screen results;49- accepted improvements and audited no-change decisions.5051## Common Mistakes5253- Benchmarking a dirty tree while reporting only `HEAD`.54- Using three iterations or presenting one cold sample as a distribution.55- Comparing different databases, browser versions, renderers, or trace settings.56- Discarding outliers without trace evidence.57- Treating `first-paint` as LCP; it is Kenn Forge's second-animation-frame terminal marker.58- Profiling through a browser request; the pprof listener expects loopback tooling such as `curl`.59- Stopping a stack or tmux session not created for the profiling run.