Skip to content

perf: parallel range-GET S3 downloads for large objects#225

Open
joshfriend wants to merge 1 commit intomainfrom
jfriend/parallel-s3-range-get
Open

perf: parallel range-GET S3 downloads for large objects#225
joshfriend wants to merge 1 commit intomainfrom
jfriend/parallel-s3-range-get

Conversation

@joshfriend
Copy link
Contributor

@joshfriend joshfriend commented Mar 24, 2026

Replace the single GetObject stream in S3.Open with parallel range-GET requests for objects larger than 32 MiB. 8 workers download chunks concurrently and reassemble them in order via io.Pipe, multiplying S3 throughput for cold snapshot downloads (observed ~100 MB/s single-stream → 400+ MB/s with parallel connections on staging hardware).

@joshfriend joshfriend requested a review from a team as a code owner March 24, 2026 20:47
@joshfriend joshfriend requested review from worstell and removed request for a team March 24, 2026 20:47
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: afbf08ad55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@joshfriend joshfriend force-pushed the jfriend/parallel-s3-range-get branch 2 times, most recently from caf48da to 7ba1a28 Compare March 24, 2026 20:59
Replace the single GetObject stream in S3.Open with parallel range-GET
requests for objects larger than 32 MiB. 8 workers download chunks
concurrently and reassemble them in order via io.Pipe, multiplying S3
throughput for cold snapshot downloads (observed ~100 MB/s single-stream
vs 400+ MB/s with parallel connections on staging hardware).
@joshfriend joshfriend force-pushed the jfriend/parallel-s3-range-get branch from 7ba1a28 to 3294383 Compare March 24, 2026 21:00
var writeErr error
for _, ch := range results {
r := <-ch
if writeErr != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you get an error this code will still wait for all the S3 Gets to run, I think you need a new context that you can cancel on error to cancel existing gets.

Comment on lines +88 to +89
var wg sync.WaitGroup
for range numWorkers {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use errgroup.WithCancel() here instead of a sync.WaitGroup. That will cancel the entire set of workers on any error or parent context cancellation.


// Write chunks in order. Each receive blocks until that chunk's worker
// finishes, while other workers continue downloading concurrently.
var writeErr error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you switch to errgroup, run this in a separate goroutine and do a return eg.Wait() at the end.

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.

4 participants