vectordotdev / vectordotdev/vector

Drop unnecessary round-trip in ClickHouse Arrow encoding

Open
#25,772 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
22.6k
Forks
2.3k
Avg merge
1d 7h
Merged PRs (30d)
146

Description

A note for the community
  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment
Use Cases

The clickhouse sink's arrow_stream encoding is used for high-volume ingestion, so its encode path runs on every flushed batch. Cutting per-event CPU there directly lowers the cores needed to sustain a given throughput.

Attempted Solutions

Today the encoder makes two passes over every event:

  1. Convert each event into a serde_json::Value tree.
  2. Feed those trees to Arrow's JSON decoder to build the columnar batch.

Step 1 isn't needed, since Arrow's decoder accepts anything that implements Serialize, and LogEvent already implements it, meaning that the intermediate JSON tree is unnecessary.

Proposal

Serialize events straight into the Arrow decoder, skipping the serde_json::Value tree. This drops one allocation and one serialization pass per event.

  • No config, schema, or API changes.
  • Behavior-preserving: all type coercion still runs through the same, unchanged Arrow decoder.

On a local bench, ~10 MB batch of 8,000 wide/nested events:

Path Before After Change
Build record batch ~27.8 ms ~19.3 ms −31%
End-to-end IPC encode ~29.3 ms ~20.4 ms −30%

Wider and more deeply nested events see the largest improvement, since they are the most expensive to convert into intermediate JSON.

This should also have the benefit of reducing some LOC / complexity that was added via the initial implementation in #24373

References
  • ClickHouse sink ArrowStream support: #24074 (request)
  • Partially addresses #25734, which removes the first step where every event is first materialized as an intermediate JSON value.
Version

0.57.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the ClickHouse sink's arrow_stream encoding path and inspect how LogEvent values reach Arrow's decoder. Replace the intermediate serde_json::Value step while preserving the existing decoder and type coercion behavior; compare the local benchmark for an approximately 10 MB batch of 8,000 wide or nested events to confirm the round-trip is removed and performance improves.

Written by the indexing model from the issue text.

Assessment

Tech stack
clickhouse, rust
Domain
performance, stream-processing
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.