The repo includes a manual benchmark runner at cmd/cdcbench for exploratory CDC load testing.
- Docker running locally
temporalCLI installed and available onPATH- Go toolchain installed
The benchmark starts its own local Postgres, MySQL, ClickHouse, Temporal dev server, worker, and in-process API. It does not use your existing docker compose stack.
From the repo root:
go run ./cmd/cdcbench \
-source=postgres \
-scenario=steady \
-output=./benchmarksOther common variants:
go run ./cmd/cdcbench -source=mysql -scenario=steady -output=./benchmarks
go run ./cmd/cdcbench -source=both -scenario=ramp -output=./benchmarks
go run ./cmd/cdcbench -source=postgres -scenario=burst -output=./benchmarks
go run ./cmd/cdcbench -source=postgres -scenario=steady -duration=1m -rate=100 -poll-interval=10s -output=./benchmarks
go run ./cmd/cdcbench -source=postgres -scenario=steady -flush-interval-ms=500 -max-batch-size=5000 -output=./benchmarks-source=postgres|mysql|both-scenario=steady|ramp|burst-output=<dir>-rate=<int>overrides the scenario's base rate-duration=<Go duration>like30s,1m,8m-poll-interval=<Go duration>like5s,10s-flush-interval-ms=<int>-max-batch-size=<int>
steady: 5 minutesramp: up to 10 minutesburst: 8 minutes
Add some extra time for container startup and shutdown.
Each run writes:
<source>-<scenario>-<timestamp>.json<source>-<scenario>-<timestamp>.md
into the directory passed via -output.
The benchmark also prints a one-line summary when it completes, for example:
postgres/steady target=250.0 achieved=247.6 visible=228.0 p95=949.6ms max_backlog=115 output=./benchmarks
Treat the run as complete when you see the summary line above.
The log lines after that about the worker stopping, activity heartbeat failures, or context canceled are expected shutdown noise from terminating the long-running CDC workflow after the benchmark is done.
If you do not see the summary line, the run did not complete successfully.
target: configured write rate for the scenarioachieved: actual source write rate reached by the benchmark writervisible: destination-side visible ingest ratep50/p95/p99/max latency: destination_ingested_at - event_tsmax_backlog: largest observed gap between written sourceseqand visible destinationseqFINAL count/FINAL max seq: one-off end-of-run validation usingFINAL
- Start with
-duration=1mfor smoke checks. - Use
steadyfirst to find a sustainable rate. - Use
rampto find the point where backlog starts growing. - Use
burstto see recovery behavior after spikes.