blob: fd37d62e1bfda169559681db6b013b99500762be [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Rate Limiting
2
Sameer Ajmanida391aa2015-02-12 11:36:53 -05003To limit the rate of operations per unit time, use a [time.Ticker](http://golang.org/pkg/time/#NewTicker).
Mike Graf3573e4b2016-02-15 13:14:14 -08004This works well for rates up to tens of operations per second.
Sameer Ajmani1a0ca7c2016-04-22 08:56:07 -04005For higher rates, prefer a token bucket rate limiter such as [golang.org/x/time/rate.Limiter](https://godoc.org/golang.org/x/time/rate) (also search godoc.org for
Sameer Ajmanida391aa2015-02-12 11:36:53 -05006[rate limit](http://godoc.org/?q=rate+limit)).
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11007
jim-slattery-rs7d05df02014-12-22 09:57:57 -08008```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11009import "time"
10
Pero336019e2015-04-23 13:27:36 -070011rate := time.Second / 10
Jérôme Laforge78be9b42019-06-26 08:50:48 +020012throttle := time.Tick(rate)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110013for req := range requests {
14 <-throttle // rate limit our Service.Method RPCs
15 go client.Call("Service.Method", req, ...)
16}
17```
18
19To allow some bursts, add a buffer to the throttle:
jim-slattery-rs7d05df02014-12-22 09:57:57 -080020```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110021import "time"
22
Pero336019e2015-04-23 13:27:36 -070023rate := time.Second / 10
Sameer Ajmanida391aa2015-02-12 11:36:53 -050024burstLimit := 100
Pero336019e2015-04-23 13:27:36 -070025tick := time.NewTicker(rate)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110026defer tick.Stop()
Sameer Ajmanida391aa2015-02-12 11:36:53 -050027throttle := make(chan time.Time, burstLimit)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110028go func() {
Pero336019e2015-04-23 13:27:36 -070029 for t := range tick.C {
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110030 select {
Pero336019e2015-04-23 13:27:36 -070031 case throttle <- t:
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110032 default:
33 }
Ivan Borshukov67bbbe92017-12-14 18:01:26 +020034 } // does not exit after tick.Stop()
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110035}()
36for req := range requests {
37 <-throttle // rate limit our Service.Method RPCs
38 go client.Call("Service.Method", req, ...)
39}
40```