Guidance for AI coding agents working in this repository. Human-oriented documentation lives at getbent.io (docs/ in this repo).
Keep changes short and actionable. Preserve shell-script-first orchestration and database-first data flow unless the task explicitly asks otherwise.
- Shell orchestration —
benchwarmer,runset,webreport,rates_webreport, andlimited_webreportcallpgbench,psql, and OS measurement helpers. - Results database —
init/resultdb.sqldefines the schema (tests,testset,timing,test_metrics_data,metrics_info, …). Reporting and graphing read from here; do not invent columns. Tests are points in a five-dimensional parameter space (client, scale, script, read/write blend, locality); see documentation.md § Benchmark parameter space. - Reporting — SQL in
reports/; legacy graphs via gnuplot inplots/. New work uses Python/Matplotlib/Pandas (metview.py,reports/*.py). See docs/plans/plotting.md. - Workloads — under
wl/andtests/; executed byrunset/benchwarmer.
createdb results && psql -f init/resultdb.sql -d results # once
./newset 'description' # new test set
./runset # run grid
./benchwarmer <clients> # single run
./webreport | ./limited_webreport 1,6,7 | ./rates_webreport 2,8,9
python3 metview.py <server> <test> # per-run metric graphs
Streamlit explorer: explorer/submission-explore.py (st.connection example).
- Shell scripts use
$RESULTPSQLfor results-DB access; follow patterns inbenchwarmer. - Register new metrics in
metrics_info; store samples intest_metrics_data. tests.scriptholds pgbench script names (select, …) or workload names (osm2pgsql%).- Many scripts expect GNU coreutils (
nproc) and optionally gnuplot. Feature-detect where needed (webreport,rates_webreport).
| Task | Start here |
|---|---|
| Schema / data shape | init/resultdb.sql |
| Run orchestration | benchwarmer, runset |
| SQL reports | reports/*.sql, views test_stats, test_metrics_decode, test_metrics |
| Metric usage | test_metrics_data, metrics_info, then reports/ |
| Programmatic DB access | explorer/submission-explore.py |
| Per-run metric graphs | metview.py, docs/plans/metview.md |
| Plotting migration | docs/plans/plotting.md |
| Graph label layout | .cursor/skills/scatter-label-layout/SKILL.md — scatter points (reports/label_layout.py) and horizontal bar value labels (reports/osm-relation-power.py) |
When tuning Matplotlib snapshot graphs, read scatter-label-layout/SKILL.md.
Scatter charts — one label per dot, inside the plot grid; use
place_point_labels() plus per-CPU overrides for crowded markers.
Horizontal bar value labels — measure whether the descriptive string fits
inside the bar. Long bars (the ones that extend farthest right) are usually
wide enough for inside placement with contrast-colored text (white on dark
bars). Short bars keep outside-right labels; set xlim from measured label
width so nothing leaves the plot area. See plot_relation_efficiency() in
reports/osm-relation-power.py.
Plans live under docs/plans/ in two categories:
Implementation — code to build or migrate:
- plotting.md — gnuplot → Python (project-wide)
- metview.md — per-run metrics grapher
Documentation — topics to write for getbent.io when time allows:
- documentation.md — documentation backlog
Long-term goals — directional ambitions; do not treat as active work unless asked:
- goals.md — multi-year project direction
Prioritize Python/Matplotlib for new graphing work unless the task is explicitly fixing legacy gnuplot output.
- Do not rewrite shell orchestration in Python unless requested.
- Do not guess schema; read
init/resultdb.sqlor query the DB. - Do not expand
metview.pyto graph every metric by default without checking the metview plan (minimal vs verbose is planned).
- Solaris:
benchwarmermay need/usr/xpg4/bin/tailinstead oftail. - Crashed benchmarks can leave zombie OS stats processes (see plotting.md backlog).