Agent Guide: Benchmark Decision Matrix & Tool-Calling Protocol
[!NOTE] Companion specification to Evolving
pgbenchinto a Universal Database Benchmark Engine.
- 1. Intent-to-Workload Dispatch Matrix
- 2. Invariant State Machine for Database Initialization
- 3. Tool-Calling CLI Flag Invariants & Exclusions
- 4. Deterministic Triage & Error Mitigation Tree
Target Consumer: Autonomous Tool-Calling Agents (ReAct, CodeAct, Function-Calling Agents)
Purpose: Deterministic translation of natural language benchmark requests into valid pgbench CLI invocations, strict state-machine transitions, and error mitigation trees.
1. Intent-to-Workload Dispatch Matrix
Use this lookup table to map user requests directly to the correct workload suite, required scale factors, script weights, and mandatory SLA constraints:
| User Intent / Workload Request | Target Suite | Workload Path (workloads/) |
Mandatory Options | Default Script Allocation | SLA Template |
|---|---|---|---|---|---|
| Banking / Accounts OLTP | pgbench-b |
pgbench-b/ |
-D scale=<N> |
pgbench_b_tx.sql@100 |
--sla="total:p95<=100ms" |
| Order Entry / TPC-C-like OLTP | pgbench-c |
pgbench-c/ |
-D scale=<warehouses> |
pgbench_c_new_order.sql@45pgbench_c_payment.sql@43pgbench_c_order_status.sql@4pgbench_c_delivery.sql@4pgbench_c_stock_level.sql@4 |
--sla="total:p95<=5000ms" |
| Financial Brokerage / Trades | pgbench-e |
pgbench-e/ |
-D scale=<N> |
pgbench_e_trade_status.sql@44pgbench_e_market_watch.sql@18pgbench_e_customer_position.sql@13pgbench_e_trade_order.sql@10pgbench_e_trade_result.sql@10pgbench_e_broker_volume.sql@5 |
--sla="total:p95<=3000ms" |
| Decision Support / Ad-Hoc OLAP | pgbench-h |
pgbench-h/ |
-D scale=<N> |
--group="name=queries,clients=4,sequential=true,file=pgbench_h_queries.sql"--group="name=refresh,clients=1,rate=2,file=pgbench_h_refresh.sql" |
--sla="queries:p95<=30000ms" |
| Star-Schema Retail Analytics | pgbench-ds |
pgbench-ds/ |
-D scale=<N> |
--group="name=reporting,clients=4,file=pgbench_ds_q_store_sales.sql@25,..."--group="name=maint,clients=1,rate=2,file=pgbench_ds_maintenance.sql" |
--sla="reporting:p95<=45000ms" |
| Mixed OLTP + Analytics (HTAP) | pgbench-htap |
pgbench-htap/ |
-D scale=<warehouses> |
--group="name=oltp,clients=8,file=pgbench_htap_oltp.sql"--group="name=olap,clients=2,file=pgbench_htap_olap_q1.sql@20,..." |
--sla="oltp:p95<=5000ms"--sla="olap:p95<=15000ms" |
| Graph: Subgraph Patterns (LSQB) | pgbench-graph |
pgbench-graph/ |
-s 1 |
pgbench_ldbc_lsqb.sql@100 |
--sla="validation_failures<=0" |
| Graph: SNB Interactive Readers/Writers | pgbench-graph |
pgbench-graph/ |
--reservoir=persons:4096--reservoir=messages:8192 |
--group="name=snb_readers,clients=4,file=pgbench_ldbc_snb_ic.sql@30,file=pgbench_ldbc_snb_is.sql@70"--group="name=snb_writers,clients=2,file=pgbench_ldbc_snb_iu.sql@75,file=pgbench_ldbc_snb_id.sql@25" |
--sla="validation_failures<=0" |
| Graph: SNB BI Phased Workload | pgbench-graph |
pgbench-graph/ |
-s 1 |
pgbench_ldbc_snb_bi.sql@100 |
--sla="validation_failures<=0" |
| Graph: FinBench Fraud & Graphalytics | pgbench-graph |
pgbench-graph/ |
-s 1 |
pgbench_ldbc_finbench.sql@100pgbench_ldbc_graphalytics.sql@100 |
--sla="validation_failures<=0" |
Graph (SQL/PGQ GRAPH_TABLE): LSQB, SNB, FinBench, Graphalytics |
pgbench-graph-pgq |
pgbench-graph-pgq/ |
-s 1 |
pgbench_ldbc_pgq_lsqb.sql, pgbench_ldbc_pgq_snb_*.sql, pgbench_ldbc_pgq_finbench.sql, pgbench_ldbc_pgq_graphalytics.sql |
--sla="validation_failures<=0" |
| Vector: Hybrid Filtered & Multi-Vector | pgbench-vec |
pgbench-vec/ |
--reservoir=vec_ids:1024 |
pgbench_vec_search.sql@30pgbench_vec_filtered.sql@25pgbench_vec_postfiltered.sql@20pgbench_vec_multivec.sql@15pgbench_vec_insert.sql@10 |
--sla="total:r_unfiltered:recall>=0.95"--sla="total:r_prefilter:recall>=0.90"--sla="total:r_postfilter:recall>=0.40"--sla="total:r_multivec:recall>=0.85" |
| Vector: Continuous Aging & Degradation | pgbench-vec |
pgbench-vec/ |
--reservoir=vec_ids:1024 |
pgbench_vec_aging.sql@100 |
--sla="total:r_aging:recall>=0.80"--sla="total:p95<=150ms" |
2. Invariant State Machine for Database Initialization
Agents MUST execute database initialization sequentially. Never skip states:
Invariant Execution Templates
# STATE 1: Schema creation (Single transaction, single client)
pgbench -n -d $DB_NAME -t 1 -f workloads/$SUITE/${SUITE}_schema.sql
# STATE 2: Parallel data population (N workers, partitioned by :client_id)
pgbench -n -d $DB_NAME -c $WORKERS -j $WORKERS -t 1 \
-D scale=$SCALE -D num_workers=$WORKERS \
-f workloads/$SUITE/${SUITE}_init.sql
# STATE 3: Constraint, foreign key, secondary index, and ANALYZE
pgbench -n -d $DB_NAME -t 1 -f workloads/$SUITE/${SUITE}_constraints.sql
# STATE 3b (MANDATORY FOR pgbench-vec ONLY): In-database ground truth generation
pgbench -n -d $DB_NAME -t 1 -f workloads/pgbench-vec/pgbench_vec_gt_gen.sql
3. Tool-Calling CLI Flag Invariants & Exclusions
When generating pgbench command lines, enforce these boolean and relational constraints:
-i(Builtin Init) vs-f(Custom Workload Script):- ⚠️ MUTUALLY EXCLUSIVE: Never pass
-iwhen executing custom workload suites. Always use-n -f <path>.
- ⚠️ MUTUALLY EXCLUSIVE: Never pass
--groupvs Top-Level-f/-c:- ⚠️ MUTUALLY EXCLUSIVE: If
--groupis present, do NOT pass top-level-f,-c, or-t. All client counts and script files must reside inside--group="name=...,clients=...,file=...".
- ⚠️ MUTUALLY EXCLUSIVE: If
--reservoirDependency:- ⚠️ MANDATORY: Any script invoking
\reservoir_push <name>or\reservoir_pop <name>(such aspgbench_graph_add_edge.sql,pgbench_ldbc_snb_iu.sql,pgbench_vec_insert.sql,pgbench_vec_aging.sql) MUST have--reservoir=<name>:<capacity>defined in the CLI flags.
- ⚠️ MANDATORY: Any script invoking
- SLA Gating & Exit Code Guarantee:
- When
--slais passed,pgbenchreturnsexit code 2if any SLA contract is breached. - Always pass
--json-report=<path>to preserve machine-parseable details on SLA pass/fail status.
- When
4. Deterministic Triage & Error Mitigation Tree
When a subshell or tool invocation returns non-zero, parse stderr and apply this decision logic:
| Exit Code | stderr / Output Pattern |
Root Cause | Automated Remediation Action |
|---|---|---|---|
2 |
SLA ... [FAIL] |
Performance target or quality gate missed | Read --json-report. If p95 exceeded, reduce client concurrency -c or increase duration. If recall failed on postfilter, increase k_oversample. |
1 |
reservoir "..." does not exist |
Script used \reservoir_push without CLI allocation |
Append --reservoir=<name>:2048 to CLI options. |
1 |
relation "..." does not exist |
Invariant state skipped; schema or tables not created | Re-run State 1 (schema.sql) and State 2 (init.sql). |
1 |
One or more client groups failed to synchronize |
Barrier mismatch in phased run | Ensure all clients execute the same number of \phase_barrier calls; do not mix phased and unphased scripts in the same client group. |
1 |
database "..." does not exist |
Target database not created | Execute createdb <dbname> via psql before running benchmark. |