resty icon indicating copy to clipboard operation
resty copied to clipboard

Rate limiting outgoing requests

Open janekolszak opened this issue 5 years ago • 8 comments

Hi! Thank you so much for this project, it saved me a lot of time!

Do you plan on adding a per-endpoint rate limiter, or a global rate-limiter of outgoing requests?

Thanks

janekolszak avatar Jul 18 '19 08:07 janekolszak

@janekolszak Thank you for your appreciation and suggesting a new feature in Resty as client-side rate-limiting. It will be a good addition.

Typically server-side rate-limiting is known for, it would be good to try out on client-side too. If you have a design suggestion or recommendation. Please post here on the thread.

Currently, I'm bit occupied in at my day work. I will get to it once I get time. Thanks!

jeevatkm avatar Jul 20 '19 08:07 jeevatkm

One options is to use github.com/didip/tollbooth since it 's already battle tested and simple.

Create the limiter with something like this

limiter = tollbooth.NewLimiter(ratePerSecond, &limiter.ExpirableOptions{
	DefaultExpirationTTL: ....,
	ExpireJobInterval:    ....,
})
limiter.SetBurst(int(math.Max(1, float64(burstSize))))

When making the request just use

if limiter.LimitReached(<some key>) {
// error
}

For a global, per-client limiter would be a const string. But one could also use per remote endpoint limiting.

This would be an overkill if we only need a global per-client limiter. It'd introduce a separate goroutine for caching limited keys.

janekolszak avatar Aug 03 '19 13:08 janekolszak

I think that the best option is to use https://godoc.org/golang.org/x/time/rate and just create one limiter per resty client. When making the request we'd just run limiter.Wait(ctx) this way we could achieve a useful feature - constant rate of outgoing requests.

Let me know if you want me to write it.

janekolszak avatar Aug 03 '19 13:08 janekolszak

I am also interested in having rate limiting.

However, to avoid locking into one particular interface, I suggest adding the ability to wrap executors and let users add limiters how they see fit: https://github.com/go-resty/resty/pull/477

lavoiesl avatar Oct 14 '21 18:10 lavoiesl

@lavoiesl Thanks for showing your interest, I agreed about not locking into one particular interface.

jeevatkm avatar Oct 24 '21 23:10 jeevatkm

Hi, I needed client side rate-limiting for a personal project so I did a short implementation based on golang.org/x/time/rate as mentioned by @janekolszak .

I created a pull request: https://github.com/go-resty/resty/pull/494

If you think this would be useful for Resty don't hesitate to ask for changes.

dbriemann avatar Nov 30 '21 21:11 dbriemann

Hello there

I implemented my own rate limiter with httpTransport and friends, but I wonder if the rate limiting affects the timeout of the request, because I am getting a lot of those errors on my project, where I do thousands of requests per sec.

alarbada avatar Jan 17 '22 17:01 alarbada

hey @jeevatkm, i'm also interested in client side rate limiting! any chance you'd be open to a PR for it? or could you take a look at the PR above?

morningvera avatar Jun 06 '22 14:06 morningvera

@dbriemann @SVilgelm have contributed this feature. It has been released in v2.9.0

jeevatkm avatar Oct 01 '23 04:10 jeevatkm