Breakpoint Testing PRO#
Breakpoint testing finds the point at which your database starts to degrade under load. edg starts with a single worker and adds one more every interval, monitoring latency, throughput, and errors. When performance degrades past a threshold, it warns you. When absolute limits are hit, it stops.
How it works#
1 worker -> 2 workers -> 3 workers -> ... -> stop
^ ^ ^
baseline compare to compare to
captured baseline baseline- Start with 1 worker running the workload defined in
--config - After
--ramp-interval(default 30s), capture baseline metrics (p99 latency, per-worker QPS, error count) - Add another worker
- Each subsequent interval, compare current metrics against the baseline
- If any metric degrades by
--thresholdpercent (default 50%), log a warning - If an absolute stop condition is met (
--stop-p99,--stop-qps,--stop-errors), the test stops - Print a final summary with the number of workers reached
Usage#
edg perf breakpoint \
--driver pgx \
--config workload.edg \
--url ${DATABASE_URL} \
--ramp-interval 30s \
--threshold 50 \
--stop-p99 500ms \
--stop-errors 100Flags#
| Flag | Type | Default | Description |
|---|---|---|---|
--ramp-interval | duration | 30s | Time between adding each new worker |
--threshold | float | 50 | Percentage change that triggers a degradation warning |
--stop-p99 | duration | 0 (disabled) | Stop when p99 latency exceeds this value |
--stop-qps | float | 0 (disabled) | Stop when total QPS drops below this value |
--stop-errors | int | 0 (disabled) | Stop when total error count exceeds this value |
--duration | duration | 0 (no limit) | Maximum test duration (safety net) |
--print-interval | duration | 1s | How often to print progress stats |
All standard connection flags (--url, --driver, --config, --pool-size, etc.) are inherited from the root command, including --tui for the interactive terminal interface (see TUI).
Degradation warnings#
After the first ramp interval, edg captures a baseline:
- Baseline p99 - p99 latency with 1 worker
- Baseline per-worker QPS - total QPS divided by worker count
- Baseline errors - total error count
Each subsequent interval, edg compares the current values against the baseline. If any metric has changed by more than --threshold percent, a warning is logged:
WARN p99 degraded baseline=2ms current=4ms change=100.0%
WARN per-worker QPS degraded baseline=500.0 current=200.0 change=60.0%
WARN errors increased baseline=0 current=15 change=inf%Warnings repeat each interval as long as the degradation persists. They do not stop the test – only --stop-* flags cause the test to stop.
Stop conditions#
Stop conditions are absolute thresholds, not relative to the baseline:
--stop-p99 500msstops if p99 exceeds 500ms at any point--stop-qps 100stops if total QPS falls below 100--stop-errors 50stops if total errors exceed 50
When a stop condition is met, edg logs the reason and the final worker count:
INFO breakpoint reached reason="p99 12ms exceeds --stop-p99 10ms" workers=47If no stop condition is set, the test runs indefinitely (or until --duration or Ctrl+C).
Example: find max workers before latency spikes#
edg perf breakpoint \
--driver pgx \
--config kv.yaml \
--url ${DATABASE_URL} \
--ramp-interval 10s \
--threshold 30 \
--stop-p99 100msThis adds a worker every 10 seconds and warns when any metric degrades by 30%. The test stops when p99 exceeds 100ms. The final log line tells you how many workers your database handled before latency became unacceptable.
Example: find error threshold#
edg perf breakpoint \
--driver pgx \
--config workload.edg \
--url ${DATABASE_URL} \
--ramp-interval 30s \
--stop-errors 10 \
--duration 10mRamp workers until 10 errors have occurred or 10 minutes have elapsed, whichever comes first.
Workload configuration#
Breakpoint testing reuses the same --config YAML as edg run and edg all. Any config with a run section works. The up, seed, deseed, and down sections are not executed – set up your schema and data separately, or use edg all first.
Tips#
- Set
--pool-sizeto match your production connection limit. This ensures you find the breakpoint under realistic connection constraints rather than unlimited pooling. - Use
--durationas a safety net. Without it and without stop conditions, the test runs forever. - Start with a longer
--ramp-interval. Give each worker count enough time to stabilise before adding more. Too short and the metrics will be noisy. - Combine with
--metrics-addr. Export Prometheus metrics during the run to get detailed histograms and per-query breakdowns alongside the breakpoint detection.