Reuse sigv4 chunk buffer - #7219
Open
RanVaknin wants to merge 4 commits into
Open
Conversation
RanVaknin
marked this pull request as ready for review
August 3, 2026 22:31
|
This pull request has been closed and the conversation has been locked. Comments on closed PRs are hard for our team to see. If you need more assistance, please open a new issue that references this one. |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Background
Synchronous S3 aws-chunked uploads process payloads in 128 KiB chunks so they can be signed and checksummed without loading the entire request into memory. However, ChunkedEncodedInputStream allocated a new 128 KiB array for every chunk even though only one chunk is consumed at a time, creating unnecessary allocation and CPU overhead that grows with payload size.
Changes
Sigv4ChunkedSigningBenchmarksigns and fully consumes an in memory S3PUTpayload (excluding network so that SDK signing and encoding costs remain narrow and accurate). It covers 64 KiB, 1 MiB, and 16 MiB payloads across signed payload, signed checksum trailer, and unsigned checksum trailer modes.Capturing JFRs from the benchmark showed that
ChunkedEncodedInputStream.getChunkaccounted for 51%-74% of self CPU and 88%-100% of sampled allocation weight in the profiles. The existing code allocated a new 128 KiB array for every chunk and another array when probing for EOF, so a 16 MiB request allocated 16 MiB of temporary chunk arrays even though only one chunk is consumed at a time.ChunkedEncodedInputStreamto lazily allocates one chunk array per stream, refills it only after the previous chunk is exhausted, and releases it at EOF, read failure, or close.From a customer perspective there is no new API or behavior. Synchronous S3 customers using
aws-chunkeduploads benefit through less allocations and consequently less CPU spent allocating and zeroing arrays, with the largest effect on large payloads and unsigned checksum trailer uploads (where crpyto work doesn't dominate).Results
Before (64KiB unsigned trailer case)
Memory:

After (64KiB unsigned trailer case)
Memory:
Canary
30min canary runtime showed improvements across the main resource metrics. The optimization branch used ~50% less host CPU, 12.8% less JVM CPU, 9.4% less host memory, and completed 15.9% more operations per CPU second.
HeapAfterGC was the one result that looked worse. Further investigation showed that this metric retains the value from the most recent garbage collection. Because the PR performed far fewer garbage collections, the two values represented different points in the garbage collection cycle and were not directly comparable. Forced GC measurements showed that the PR’s retained heap remained stable rather than growing over time, so there was no evidence of a memory leak.