Persistence benchmark
The persistence benchmark creates a dedicated ephemeral PostgreSQL database, loads production-shaped synthetic rows, exercises the real store methods, and writes latency percentiles and query plans to a JSON report. It never connects to the normal development or comprehensive-test-course databases.
./scripts/benchmark-persistence.shThe default profile creates 20,000 students, 20 exercises, 60,000 documents, 400,000 assessments, 440,000 assessment memberships, 400,000 grader assignments, and 100,000 manual-grading capabilities. The database and its volume are removed when the command finishes.
The report is written to
backend/build/reports/persistence-benchmark.json. It contains p50, p95, and
maximum latency for selective and course-wide reads, one bulk write, relation
sizes, and EXPLAIN (ANALYZE, BUFFERS) output. The run fails if PostgreSQL does
not use the expected selective indexes.
Changing the scale
Section titled “Changing the scale”Set any of these variables before running the script:
| Variable | Default |
|---|---|
BENCHMARK_STUDENTS |
20,000 |
BENCHMARK_EXERCISES |
20 |
BENCHMARK_DOCUMENTS_PER_STUDENT |
3 |
BENCHMARK_DOCUMENT_BYTES |
4,096 |
BENCHMARK_MANUAL_CAPABILITIES |
100,000 |
BENCHMARK_WARMUPS |
2 |
BENCHMARK_REPETITIONS |
8 |
BENCHMARK_VERIFY_PLANS |
true |
BENCHMARK_POSTGRES_PORT |
55,433 |
BENCHMARK_REPORT |
backend/build/reports/persistence-benchmark.json |
Keep plan verification enabled for performance runs. Small smoke profiles may disable it because PostgreSQL normally prefers sequential scans for tiny tables.
For example, a million-assessment stress run is:
BENCHMARK_STUDENTS=50000 BENCHMARK_EXERCISES=20 \ ./scripts/benchmark-persistence.shSet KEEP_BENCHMARK_DB=1 to retain the isolated database after the run for
manual EXPLAIN inspection. Remove it afterward with:
docker compose -f docker-compose.benchmark.yml \ -p hanami-persistence-benchmark down -v