Skip to content

fix: decompress streaming responses incrementally - #2993

Open
CodePrometheus wants to merge 1 commit into
theagentrouter:mainfrom
CodePrometheus:fix/stream-decode-once
Open

CodePrometheus wants to merge 1 commit into
theagentrouter:mainfrom
CodePrometheus:fix/stream-decode-once

Conversation

@CodePrometheus

Copy link
Copy Markdown
Contributor

Description

Goal

Decode each byte of a compressed streaming response once, so the cost grows linearly with the response length.

Before

decodeStreamingContent appends every chunk to a buffer and decompresses the whole buffer again, so CPU and allocations grow with the square of the response length. A few hundred KB of brotli SSE costs seconds of ext_proc CPU per request.

After

One decompressor per response is fed one chunk at a time through an iter.Pull coroutine. If the stream ends before the last chunk, the router processor releases the decoder when the ext_proc stream closes. Error handling is unchanged: running out of input mid-stream is fine, and a stream truncated at end of stream or corrupt data still fails the request.

ProcessResponseBody benchmark, one chunk per SSE event:

stream before after
gzip, 110 KB 133 ms / 352 MB allocated 0.72 ms / 0.96 MB
gzip, 444 KB 1.88 s / 4.55 GB 2.64 ms / 3.6 MB
br, 110 KB 1.19 s / 889 MB 1.75 ms / 1.4 MB
br, 444 KB 18.8 s / 12.4 GB 6.6 ms / 5.3 MB

Signed-off-by: Zixin Zhou <zhouzixin@apache.org>
@CodePrometheus
CodePrometheus requested a review from a team as a code owner November 7, 2026 07:50
@netlify

netlify Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for theagentrouter canceled.

Name Link
🔨 Latest commit 06016f3
🔍 Latest deploy log https://app.netlify.com/projects/theagentrouter/deploys/6aeed832be8338b7bef3b573

@codecov

codecov Bot commented Nov 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.55556% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/extproc/processor_impl.go 85.71% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant