What kind
None of the form's kinds apply cleanly. This is a benchmark scenario, filed on the feature form because blank issues are disabled.
Which components
ClickHouse sink (spate-clickhouse)
What you are trying to do, and what stops you
Measure what compression: zstd costs the ClickHouse sink compared with the default compression: lz4, so the choice of default rests on a number. Nothing measures this today.
ClickHouse 26.9 changed its own default codec from LZ4 to ZSTD(3) for table data and network traffic (ClickHouse/ClickHouse#108786). That pull request says ZSTD(3) "gives substantially better compression ratios at a still-modest CPU cost". Its CI performance comparison does not test the claim: the harness pins both servers to LZ4. #458 keeps lz4 as the sink's default. This task decides whether it should follow the server to zstd.
The cost shows up in two places. The sink compresses every insert body on the pipeline's I/O runtime, which has pipeline.io_threads workers (default 2). ClickHouse decompresses the body on arrival. Both are measured.
Two questions:
- Does throughput under the benchmark's 32-CPU envelope change when the sink compresses with zstd?
- How much sink CPU per row and ClickHouse CPU per row does zstd add or save?
Rig. The kafka_avro_clickhouse bench in spate-etl/benchmark on c8gd-metal-24xl-ec2-docker, using the spate arm's published native variant. Only compression changes. results/c8gd-metal-24xl-ec2-docker/spate/2026-08.jsonl has the captured lz4 figures for that variant. Its rowbinary runs are infra_bound, so they cannot show a sink-side cost, and native goes first.
Arms.
| Arm |
compression |
| A |
lz4 |
| B |
zstd (level 3) |
| C |
zstd:1, optional |
Baseline. The August capture ran spate 0.2.0 against ClickHouse 26.3.22.7. A zstd run on today's spate commit or a newer server needs a fresh arm A in the same session. The capture then shows whether the lz4 figures have drifted since August. Interleave the arm order, and run at least three replicates per arm, matching the capture.
To build. The spate arm cannot set compression today. entrants/spate/README.md lists it among the framework values that no descriptor reaches. The arm needs a compression knob, recorded in the result's variant so every JSONL row names its codec.
Recorded per arm. rows_per_s, cpu_us_per_row, data_plane_cores_used, throttled_us, ch_cpu_us_per_row and ch_inserted_bytes.
Confounder. The rig runs everything on one host, so the sink reaches ClickHouse over a local bridge with bandwidth to spare. A smaller body saves nothing there. A deployment where the sink and ClickHouse sit on separate hosts would gain from it, and this rig cannot show that gain.
Semver impact, as best you can tell
Additive — nothing existing changes
Does this touch any of these?
None. The bench observes and changes no crate's behavior.
Would you want to implement it?
Yes — maintainer task, on the benchmark rig.
What kind
None of the form's kinds apply cleanly. This is a benchmark scenario, filed on the feature form because blank issues are disabled.
Which components
ClickHouse sink (spate-clickhouse)
What you are trying to do, and what stops you
Measure what
compression: zstdcosts the ClickHouse sink compared with the defaultcompression: lz4, so the choice of default rests on a number. Nothing measures this today.ClickHouse 26.9 changed its own default codec from LZ4 to ZSTD(3) for table data and network traffic (ClickHouse/ClickHouse#108786). That pull request says ZSTD(3) "gives substantially better compression ratios at a still-modest CPU cost". Its CI performance comparison does not test the claim: the harness pins both servers to LZ4. #458 keeps
lz4as the sink's default. This task decides whether it should follow the server to zstd.The cost shows up in two places. The sink compresses every insert body on the pipeline's I/O runtime, which has
pipeline.io_threadsworkers (default 2). ClickHouse decompresses the body on arrival. Both are measured.Two questions:
Rig. The
kafka_avro_clickhousebench in spate-etl/benchmark onc8gd-metal-24xl-ec2-docker, using the spate arm's publishednativevariant. Onlycompressionchanges.results/c8gd-metal-24xl-ec2-docker/spate/2026-08.jsonlhas the capturedlz4figures for that variant. Itsrowbinaryruns areinfra_bound, so they cannot show a sink-side cost, andnativegoes first.Arms.
compressionlz4zstd(level 3)zstd:1, optionalBaseline. The August capture ran spate 0.2.0 against ClickHouse 26.3.22.7. A zstd run on today's spate commit or a newer server needs a fresh arm A in the same session. The capture then shows whether the lz4 figures have drifted since August. Interleave the arm order, and run at least three replicates per arm, matching the capture.
To build. The spate arm cannot set
compressiontoday.entrants/spate/README.mdlists it among the framework values that no descriptor reaches. The arm needs acompressionknob, recorded in the result'svariantso every JSONL row names its codec.Recorded per arm.
rows_per_s,cpu_us_per_row,data_plane_cores_used,throttled_us,ch_cpu_us_per_rowandch_inserted_bytes.Confounder. The rig runs everything on one host, so the sink reaches ClickHouse over a local bridge with bandwidth to spare. A smaller body saves nothing there. A deployment where the sink and ClickHouse sit on separate hosts would gain from it, and this rig cannot show that gain.
Semver impact, as best you can tell
Additive — nothing existing changes
Does this touch any of these?
select!spate-coreNone. The bench observes and changes no crate's behavior.
Would you want to implement it?
Yes — maintainer task, on the benchmark rig.