[BUG](log): Cap the log client's encode size at the log server's decode limit - #7666
Merged
Conversation
…de limit The frontend's log client set only max_decoding_message_size, leaving tonic's send limit unlimited, so it would encode a PushLogsRequest larger than the log service is willing to decode. GrpcLogConfig already carried a max_encoding_message_size field defaulting to the log service's 32 MB decode limit; it was never passed to the client. Wire it through so the frontend rejects an oversized batch locally, with the size named in the error, instead of failing at decode on the far side. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
Reviewer ChecklistPlease leverage this checklist to ensure your code review is thorough before approving Testing, Bugs, Errors, Logs, Documentation
System Compatibility
Quality
|
rescrv
approved these changes
Sep 1, 2026
rescrv
left a comment
Contributor
There was a problem hiding this comment.
The PR description is longer than the code patch.
dbeglord
enabled auto-merge (squash)
September 1, 2026 00:15
Contributor
|
Found 1 test failure on Blacksmith runners: Failure
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
When a client writes records to Chroma, the frontend does not write them to storage itself. It batches the records into a single gRPC message and forwards that message to a separate log service, which durably appends it. A whole conditional commit travels as one message, so a large write is one large message rather than many small ones.
Both ends of a gRPC hop set their own size ceilings. The receiver sets a decode limit — the largest message it will accept off the wire. The sender sets an encode limit — the largest message it will put on the wire. These are independent settings, and the sender's is unlimited unless you set it.
The log service sets a decode limit of 32 MB (
LogServerConfig::default_max_decoding_message_sizeinrust/log-service/src/lib.rs, applied to the server inLogServerWrapper::run). Nothing in the repo overrides it.The frontend's log client set only the decode limit, and left the encode limit unset (
rust/log/src/grpc_log.rs, buildingClientOptionsfromrust/memberlist/src/client_manager.rs). Its send ceiling was therefore unlimited.What that causes
An oversized write leaves the frontend looking healthy and dies on arrival. The frontend serializes the batch, opens a stream, sends 35 MB, and the log service rejects it during decode. The error the client gets back names a decode failure on a gRPC stream, not the write that caused it — there is no collection id, no record count, no size in it. Diagnosing one means correlating the failure back to a request by hand.
The gap is reachable in production. The frontend accepts HTTP request bodies up to 40 MB (
default_max_payload_size_bytesinrust/frontend/src/config.rs), so a write between roughly 33 and 40 MB clears the HTTP layer and then fails at the internal hop.The fix
GrpcLogConfig, the log client's configuration, already carried amax_encoding_message_sizefield defaulting to 32 MB — the same number the log service decodes at. The field was simply never passed to the client. This wires it through:Now the frontend refuses the write before sending it, and tonic's local error names the actual byte count and the limit. No new constant is introduced, and the value stays configurable through the same config key it always had.
Why match the server rather than raise it
Raising the log service's decode limit would move the failure, not remove it. Some ceiling always exists, and whatever it is, a client that will send past it produces the same undiagnosable far-side failure. Matching makes the client refuse locally, where the request that caused it is still in hand.
32 MB is also the log service's real capacity decision — it bounds a single buffered append. Raising it to admit larger writes is a capacity change to argue on its own merits, not a fix for an error-reporting problem.
Other gRPC clients
I checked every
ClientOptionsconstruction in the repo:rust/frontend/src/executor/distributed.rs) — sets both limits. This is the pattern the log client now follows.rust/s3heap-service/src/client/grpc.rs) — has the same asymmetry, and its config declares an unusedmax_encoding_message_sizedefault of 32 MB, exactly like the log client did. Left alone: the heap service has no server implementation in this repo yet and the client defaults to disabled, so there is no decode limit to match against. It is worth fixing when that server lands.rust/garbage_collector/src/helper.rs) — same asymmetry, but it is local integration-test scaffolding, not a production path.Testing
Added
log_client_encode_limit_fits_server_decode_limitto the log service's config tests. It asserts the log client's default encode ceiling is at or below the log service's effective decode ceiling, computed the same way the server computes it. The two numbers live in different crates, and this is what keeps them from drifting apart again.cargo check,cargo clippy -- -D warnings, andcargo fmt --checkpass forchroma-logandchroma-log-service. The new test passes. I did not exercise the oversized-write path against a running log service.