Package provides methods to rate limit any type of requests (not only http). Use builtin Bottlenecks or write your own for custom bottle neck logic.
go.uber.org/ratelimit
does not supportburst
optiongo.uber.org/ratelimit
cannot cancel request or shrink queue
x/time/rate
cannot cancel request or shrink queue
github.com/reugn/equalizer
does not supportburst
option
Overhead of each Take()/Wait() request with infinity rate:
$ # RegularBottleneck lies on memory usage because uses slice of int64 with length of required RPS
$ go test -bench=. -benchmem -benchtime=10000000x
warning: GOPATH set to GOROOT (/home/user/go) has no effect
goos: linux
goarch: amd64
pkg: github.com/alexdyukov/ratelimiter/v2
cpu: AMD Ryzen 7 8845H w/ Radeon 780M Graphics
BenchmarkRegularBottleneck-16 10000000 228.6 ns/op 0 B/op 0 allocs/op
BenchmarkValveBottleneck-16 10000000 163.0 ns/op 0 B/op 0 allocs/op
BenchmarkEqualizerBottleneck-16 10000000 229.3 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/alexdyukov/ratelimiter/v2 11.662s
package main
import (
"io/ioutil"
"net/http"
"github.com/alexdyukov/ratelimiter/v2"
"github.com/alexdyukov/ratelimiter/v2/bottleneck"
)
func main() {
rps := 100
burst := 25
bn := bottleneck.NewRegular(rps, burst)
rl := ratelimiter.New(bn)
echo := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !rl.Take(r.Context()) {
w.Header().Add("Retry-After", "60")
http.Error(w, "Try again later", http.StatusServiceUnavailable)
return
}
data, _ := ioutil.ReadAll(r.Body)
w.Write(data)
})
http.ListenAndServe(":8080", echo)
}
MIT licensed. See the included LICENSE file for details.