Remove per-command AOF staging copy
perfloop/redis · AVOIDABLE COPY
https://perfloop.ai/t/oss/case_e0s7svxtb7
Verdict
REFUTED · settled 2026-07-18
What happened: The source does contain the final sdscatlen copy, but controlled product-boundary calibration shows it is not a material performance mechanism. I added exactly one additional active-gate, record-sized sdscatlen(server.aof_buf, buf, sdslen(buf)) and immediately restored the SDS length and terminator, leaving durable AOF bytes unchanged; the byte-order check passed, and the calibrated disassembly contained two sdscatlen calls in feedAppendOnlyFile versus one in the baseline. On AOF-enabled native 256 KiB SET and Lua-driven 2,048-SET workloads (the latter verified cmdstat_set=2048 and produced a 536,938,548-byte AOF), that one-copy calibration did not consistently increase throughput wall time or Redis main-thread CPU. The controller likewise observed a 14.5% spread over four CPU baseline samples, so even a 1% goal was below the measurement floor. The explicit copy exists, but its contribution is below the repeatable workload noise floor; a direct-construction patch cannot support the hypothesized material CPU/throughput claim.
Hypothesis
A static source/data-flow check found that src.feedAppendOnlyFile (src/aof.c:1409-1448) creates a temporary SDS buf, passes it to catAppendOnlyGenericCommand, then—only under the AOF_ON/AOF_WAIT_REWRITE gate—calls sdscatlen(server.aof_buf, buf, sdslen(buf)) and frees buf. The assigned function (src/aof.c:1357-1380) has already serialized the RESP array framing and every argument framing/payload into that destination. The sdscatlen body check (src/sds.c:534-542) shows the append performs an explicit memcpy. Thus, on the gated path, the complete encoded record crosses two distinct mutable SDS backing buffers: it is first materialized in buf and then copied by the final append before buf is freed. The incoming-call index check for src.catAppendOnlyGenericCommand returned src.feedAppendOnlyFile at line 1436 as its sole direct indexed caller, and the local trace shows the temporary's post-construction consumer is that final append, supporting a direct-final-buffer construction while preserving ordering and state semantics. This is static evidence of a real copy, not a runtime measurement; its share of write CPU is still hypothesized. Confirm with a reproducible AOF-enabled mutation benchmark sweeping aggregate argv bytes and argc, checking byte-identical AOF output and CPU/throughput or latency profiles. The confirming signal is one fewer sdslen(encoded-record)-byte copy per qualifying mutation and reduced memcpy/sdscatlen CPU that increases with payload size.
Change to test: Under the existing AOF append-state gate, construct the timestamp, SELECT prefix, and RESP command directly in server.aof_buf instead of a temporary buf, while preserving current timestamp/DB state updates and byte ordering; retain a staging path only if inactive-state behavior needs it.
Where it lives
perfloop/redis · src/aof.c
Evidence
Timeline
2026-07-18· Case opened2026-07-18· Case closed