Skip to content

feat(server): Implement bandwidth-based rate limits - #255

Merged
lcian merged 6 commits into
mainfrom
feat/bandwidth-rate-limits
Jan 9, 2026
Merged

feat(server): Implement bandwidth-based rate limits#255
lcian merged 6 commits into
mainfrom
feat/bandwidth-rate-limits

Conversation

@lcian

@lcian lcian commented Jan 8, 2026

Copy link
Copy Markdown
Member

Introduces an implementation of bandwidth-based rate limiting and bandwidth metrics reporting.

The bandwidth is measured by wrapping our PayloadStream in GET/POST/PUT requests and counting the bytes that flow through it. This allows us to estimate the bandwidth that's being utilized at a given point in time between the server and all clients -- note that we're not concerned with the bandwidth utilization between the server and the storage backends, which should anyways be the same as the client-server one, plus an overhead for tombstone requests and responses.

The counts are summed every 50ms (this might be too frequent, we can tune it) and then contribute to an Exponentially Weighted Moving Average.

This EWMA estimate of the bandwidth is reported to Datadog (widget) and is used to enforce bandwidth-based rate limits.

Differently from throughput-based rate limits, bandwidth-based rate limits only enforce a global limit in the bandwidth that can be used by an instance of the service.
Of course, they can always be extended to support the same configuration flexibility as throughput-based rate limits. That might be unnecessary and ineffective as: - we're more concerned with global bandwidth as it's related to node limits in the infra; - getting more granular would only increase our "measurement error" due to all the approximation we're doing with wrapping the stream and using a moving average.

@lcian
lcian marked this pull request as ready for review January 8, 2026 14:25
@lcian
lcian requested a review from a team as a code owner January 8, 2026 14:25

@matt-codecov matt-codecov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

accept with nits

nice work!

Comment thread objectstore-server/src/rate_limits.rs Outdated
Comment thread objectstore-server/src/rate_limits.rs Outdated
Comment thread objectstore-server/src/rate_limits.rs Outdated
Comment thread objectstore-server/src/rate_limits.rs Outdated
Comment on lines +350 to +351
#[pin]
inner: PayloadStream,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i think PayloadStream is already pinned so this #[pin] (and the pin-project-lite) dep are unneeded?

PayloadStream is a type alias for BoxStream which is a type alias for Pin<Box<dyn Stream>>.

@lcian lcian Jan 9, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You're right.
In this case we can just use self.get_mut() to get a &mut MeteredPayloadStream which ultimately allows us to get a Pin<&mut dyn Stream<...>> that we can call poll_next on.

However, I don't understand why we're allowed to call self.get_mut in the first place. The requirement to do that is that our MeteredPayloadStream be Unpin, which in my interpretation should be false due to inner being Pin.

I will need to do some more reading about Pin because I don't understand it enough.

Comment thread objectstore-server/src/rate_limits.rs
@lcian
lcian force-pushed the feat/bandwidth-rate-limits branch 2 times, most recently from 3fb50b3 to f7cef65 Compare January 9, 2026 09:51
@lcian
lcian force-pushed the feat/throughput-rate-limits-tests branch from 360bec6 to cfc9de9 Compare January 9, 2026 09:52
Base automatically changed from feat/throughput-rate-limits-tests to main January 9, 2026 09:55
@lcian
lcian force-pushed the feat/bandwidth-rate-limits branch from f7cef65 to 0cba526 Compare January 9, 2026 09:56
@lcian
lcian enabled auto-merge (squash) January 9, 2026 09:56
@lcian
lcian merged commit 71ef635 into main Jan 9, 2026
19 checks passed
@lcian
lcian deleted the feat/bandwidth-rate-limits branch January 9, 2026 09:59
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.

2 participants