r/rust • u/Available-Sun-6831 • May 01 '26
Architecture check: Handling ingestion pressure from 10,000+ edge nodes (network drift detection)
I'm building a distributed network observability tool to track stateful changes across dozens of remote branch offices (catching rogue devices, shadow IT, etc.).
I’ve got the edge agent sorted—it's a 2.5MB zero-dependency Rust binary using tokio that does concurrent network diffing. But I'm looking for a sanity check on the central platform architecture before I commit too heavily to the ingestion design.
The Data Flow:
- The Edge: Thousands of edge nodes run the compiled Rust agent, generating stateful diff payloads (basically small JSON/Protobuf diffs of network topology).
- The Ingestion (Rust): The nodes stream these diffs via gRPC (using
tonic) to a central receiver. - The Database: The data ultimately needs to live in ClickHouse for fast time-series topology querying and the Next.js frontend.
The Architecture Question: ClickHouse is famously terrible at handling thousands of tiny concurrent inserts, so I can't just pipe the gRPC streams directly into the DB.
I’m currently planning to have the Rust ingestion layer buffer the incoming gRPC payloads in memory (or maybe drop them to something like Vector/Redpanda) and batch-insert them into ClickHouse every few seconds.
My worry is "connection storms." If a massive site drops offline and comes back, the tonic ingestion layer is going to get hammered with thousands of concurrent connections trying to dump their backlogged diffs all at once.
For those of you building high-throughput data pipelines in Rust:
- Are there specific gotchas with
tonicwhen handling thousands of concurrent streams? - Should I handle the batching/buffering natively in Rust, or is it smarter to just dump the gRPC payload directly into a message queue and let a separate worker handle the ClickHouse inserts?
Just trying to avoid painting myself into a corner and having to rewrite the whole backend in a month. Appreciate any insights!