perf(prom): release the remote write v1 decode buffer before writing

remote_write_v1 kept the decoded builder alive until the handler returned,
so the decompressed request payload stayed resident across the downstream
write or pipeline await. With 8 concurrent large requests that is one extra
copy of every payload held for the whole write.

Rows and pipeline values own their data, so the builder can be dropped as
soon as the conversion is done.

Sustained-write A/B, 8 runs per side, 50M samples each: jemalloc allocated
median drops 7.8% (155.0-162.7 MiB -> 141.4-158.6 MiB); samples per CPU
second is unchanged (-0.6%, fully overlapping ranges).

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
This commit is contained in:
Dennis Zhuang
2026-09-19 15:54:49 +08:00
parent 983738101a
commit 8232c5b3bb
+7 -2
View File
@@ -175,12 +175,17 @@ async fn remote_write_v1(
processor.set_pipeline(pipeline_handler, query_ctx.clone(), pipeline_def);
}
let mut req = decode_remote_write_request(is_zstd, body, prom_validation_mode, &mut processor)?;
let mut decoded =
decode_remote_write_request(is_zstd, body, prom_validation_mode, &mut processor)?;
// Rows and pipeline values own their data; the decode buffer need not span downstream awaits.
let req = if processor.use_pipeline {
drop(decoded);
processor.exec_pipeline().await?
} else {
req.as_insert_requests()
let req = decoded.as_insert_requests();
drop(decoded);
req
};
let batches = into_prom_write_batches(req, query_ctx);