Skip to content

feat: add per-request upload and download bandwidth limiting - #524

Merged
imroc merged 1 commit into
imroc:masterfrom
ChrisJr404:feat/bandwidth-limit
Aug 25, 2026
Merged

feat: add per-request upload and download bandwidth limiting#524
imroc merged 1 commit into
imroc:masterfrom
ChrisJr404:feat/bandwidth-limit

Conversation

@ChrisJr404

Copy link
Copy Markdown
Contributor

What

Adds Request.SetUploadLimit and Request.SetDownloadLimit, so you can cap the
upload or download speed of a request to a given number of bytes per second.
This is the feature requested in #256.

client := req.C()

// don't read the response body faster than 512 KiB/s
resp, _ := client.R().
    SetDownloadLimit(512 * 1024).
    Get("https://example.com/big-file")

// don't push the request body faster than 256 KiB/s
client.R().
    SetUploadLimit(256 * 1024).
    SetFile("file", "big-file").
    Post("https://example.com/upload")

Global wrappers req.SetUploadLimit / req.SetDownloadLimit are there too, to
match the other request options.

Behavior

Both limits wrap the underlying body in a small reader that paces itself: after
each read it sleeps for however long those bytes should have taken at the limit,
so the average throughput converges to the configured rate. A value of 0 or less
clears the limit.

  • The download limit is applied to the raw bytes coming off the wire, before
    content decoding, so it reflects real network usage. It reuses the same
    response body wrapping mechanism as SetDownloadCallback and composes with it
    when both are set.
  • The upload limit wraps the request body reader, and is reapplied through
    GetBody so a retried or redirected request stays limited.

Default behavior is unchanged when neither limit is set.

Tests

Added ratelimit_test.go covering the limiter itself (bytes come through intact
and the read is throttled), SetDownloadLimit and SetUploadLimit end to end
against a local test server, and that a zero/negative value clears the limit.
The timing assertions only check a lower bound so they don't get flaky on slow
machines. go test ./... and go vet ./... both pass.

Closes #256

@imroc imroc left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for the clean implementation. I verified locally: the upload limit is correctly reapplied through GetBody for retries/redirects, and the download limit composes with the existing wrapResponseBodyKey mechanism so it applies to raw bytes before content decoding and also works with SetDownloadCallback. go build, go vet and go test ./... all pass. Merging.

@imroc
imroc merged commit 0614b5a into imroc:master Aug 25, 2026
2 checks passed
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.

Feature bandwith limit download/upload

2 participants