perf-results-db
import { Aside, Steps } from ‘@astrojs/starlight/components’;
perf-results-db is a self-hosted store for performance test results from JMeter, k6, and Gatling. It provides trend analysis, baseline comparison, SLA tracking, and a web dashboard.
| Tier | Projects | API Keys | Retention | Price |
|---|---|---|---|---|
| Community | 3 | 5 | 90 days | Free |
| Professional | Unlimited | Unlimited | 365 days | £149/year |
| Enterprise | Unlimited | Unlimited | Custom + SSO/RBAC | £499/year |
Requirements
Section titled “Requirements”- Docker and Docker Compose
- 1 GB RAM minimum (2 GB recommended for production)
- PostgreSQL (provided via Compose, or bring your own)
Installation
Section titled “Installation”-
Download
martkos-it.co.uk/store/perf-results-db-download — requires Community license key (free registration).
-
Extract and configure
Terminal window unzip perf-results-db.zip && cd perf-results-dbcp .env.example .envEdit
.env:Terminal window ENVIRONMENT=productionDB_USER=perfDB_PASSWORD=change-me-strong-passwordDB_NAME=perfresultsDATABASE_URL=postgres://perf:change-me-strong-password@postgres:5432/perfresults# Authentication (recommended)AUTH_ENABLED=true# Data retention in days (Community max: 90)RETENTION_DAYS=90 -
Start
Terminal window docker compose up -ddocker compose ps # wait for all services to be healthy -
Verify
Terminal window curl http://localhost:4000/api/health# → {"status":"ok","version":"1.0.0"}Dashboard:
http://localhost:4000
Projects and API Keys
Section titled “Projects and API Keys”Create a project via the dashboard (Projects → New) or API:
curl -X POST http://localhost:4000/api/projects \ -H "X-API-Key: prdb_your_key" \ -H "Content-Type: application/json" \ -d '{"name": "my-app", "description": "API load tests"}'Returns {"id": "uuid-here", ...}. Store this UUID — it’s needed for all uploads.
Create an API key: Settings → API Keys → New Key. Keys are prefixed prdb_. Store immediately; the full key is shown only once.
Uploading Results
Section titled “Uploading Results”CLI Uploader
Section titled “CLI Uploader”# k6 resultsk6 run --out json=results.json my-script.jsnpx perf-results-db-cli upload \ --url http://localhost:4000 \ --api-key prdb_your_key \ --project-id your-project-uuid \ --file results.json \ --tool k6
# JMeter resultsjmeter -n -t my-test.jmx -l results.jtlnpx perf-results-db-cli upload \ --url http://localhost:4000 \ --api-key prdb_your_key \ --project-id your-project-uuid \ --file results.jtl \ --tool jmeter
# Gatling resultsnpx perf-results-db-cli upload \ --url http://localhost:4000 \ --api-key prdb_your_key \ --project-id your-project-uuid \ --file target/gatling/MySimulation-*/simulation.log \ --tool gatlingGitHub Actions
Section titled “GitHub Actions”- uses: markslilley/perf-results-db-action@v1 with: url: ${{ secrets.PERF_RESULTS_DB_URL }} api-key: ${{ secrets.PERF_RESULTS_DB_API_KEY }} project-id: ${{ vars.PERF_RESULTS_DB_PROJECT_ID }} file: results.json tool: k6GitLab CI
Section titled “GitLab CI”upload-results: script: - npx perf-results-db-cli upload --url $PERF_RESULTS_DB_URL --api-key $PERF_RESULTS_DB_API_KEY --project-id $PERF_RESULTS_DB_PROJECT_ID --file results.json --tool k6Direct API
Section titled “Direct API”curl -X POST http://localhost:4000/api/test-runs \ -H "X-API-Key: prdb_your_key" \ -H "Content-Type: application/json" \ -d '{ "projectId": "your-uuid", "tool": "k6", "metrics": { "p50": 142, "p95": 387, "p99": 612, "avg": 158, "min": 12, "max": 2341, "errorRate": 0.2, "throughput": 312.4 }, "metadata": {"branch": "main", "commit": "abc123"} }'Trends and Regression Detection
Section titled “Trends and Regression Detection”# Check for regression vs last 10 runs (>10% degradation = regression)GET /api/trends/project/{projectId}/regression?threshold=10
# Compare two date rangesGET /api/trends/project/{projectId}/compare?currentStart=2026-03-01¤tEnd=2026-03-15&baselineStart=2026-02-01&baselineEnd=2026-02-15For statistical regression detection, use perf-compare.
Baselines
Section titled “Baselines”Tag a run as a baseline:
curl -X POST http://localhost:4000/api/test-runs/{runId}/baseline \ -H "X-API-Key: prdb_your_key" \ -d '{"name": "v2.1.0 release"}'Compare a run against the baseline:
curl -X POST http://localhost:4000/api/baselines/{baselineId}/compare \ -H "X-API-Key: prdb_your_key" \ -d '{"runId": "run-uuid"}'Returns delta and percentage difference for each metric.
SLA Tracking
Section titled “SLA Tracking”Define SLA thresholds per project:
curl -X POST http://localhost:4000/api/projects/{projectId}/sla \ -H "X-API-Key: prdb_your_key" \ -H "Content-Type: application/json" \ -d '{ "p95MaxMs": 1500, "errorRateMaxPercent": 1.0, "apdexMinScore": 0.85 }'Check SLA compliance:
GET /api/sla/summary?projectId={uuid}&days=30Webhooks
Section titled “Webhooks”Trigger external systems when a test run completes:
curl -X POST http://localhost:4000/api/webhooks \ -H "X-API-Key: prdb_your_key" \ -d '{ "url": "https://hooks.slack.com/...", "events": ["test_run_completed", "sla_breached"] }'Docker Compose Customisation
Section titled “Docker Compose Customisation”Override port or use an external database:
services: api: ports: - "8080:4000" # expose on a different host port environment: DATABASE_URL: postgres://user:pass@external-host:5432/perfresultsBackup and Restore
Section titled “Backup and Restore”# Backupdocker compose exec postgres pg_dump -U $DB_USER $DB_NAME > backup-$(date +%Y%m%d).sql
# Restoredocker compose exec -T postgres psql -U $DB_USER $DB_NAME < backup-20260301.sqlUpgrading
Section titled “Upgrading”docker compose pulldocker compose up -d# Migrations run automatically on startupdocker compose logs api | grep -i migratperf-ecosystem.yml Integration
Section titled “perf-ecosystem.yml Integration”services: perf_results_db: url: "http://localhost:4000" api_key: "${PERF_RESULTS_DB_API_KEY}" project_id: "${PERF_RESULTS_DB_PROJECT_ID}"
integrations: push_to_results_db: true compare_on_upload: true # auto-run perf-compare after each uploadAPI Reference
Section titled “API Reference”Full REST API: perf-results-db API reference
OpenAPI/Swagger: http://localhost:4000/api/docs