#Best way to add a ratelimit net/http server (by IP)

16 messages · Page 1 of 1 (latest)

prisma notch
#

there's a rate limiter package $[x/time/rate]. you can combine it's usage with a map per IP. don't forget to clean them up too.

lone cryptBOT
prisma notch
#

why do you need redis

humble pond
#

Depends, if you want to run multiple instances of your server in a form of horizontal scaling then no, redis will be the best option. However if you plan on running only one instance, then keeping them all in a map is both faster and easier

#

The way I did it was making a struct called visitor:

type visitor struct {
    *sync.RWMutex
    lastAccess time.Time
    requests   int
}

Which I then made a map of, where the IP was linked to a pointer to a visitor like this, as well as a mutex to make it goroutine safe:

var visitors = make(map[string]*visitor)
var mtx sync.Mutex

Then, I was simply receiving the ip, locking the mtx mutex, incrementing the counter, and if the request was exceeding the max number of requests, i would return a 429

queen sonnet
#

Do you need the map to be shared across multiple instances of the webserver? If so, something like redis makes sense otherwise, just setup a map with a RW lock on it.

#

okay reading helps, basically what others said above.

flint moth
#

The real question, is can you rate limit on something that's not the IP address

#

If it's an unauthenticated end point, you're going to struggle with any rate limiting.

native canyon
#

Simplest algo is to use a sliding window. Keep two numbers per each actor: THIS second and PREV second. The rate for the actor is then THIS + the prorated part of PREV. So for example, if you're at second 1.3, the rate is THIS + 0.7 * PREV. You need to shift THIS to PREV when the second changes. You can of course use a different time window.

#

I would say you most likely don't need a centralized store such as Redis because you are trying to protect each individual server from overload anyways. So just keep a local map and restrict to M/N where M is the global limit and N is the number of servers. If your server count changes, it might be ok to allow more traffic. Depends on your use case.

#

Redis also introduces a network call so each and every request will be delayed by a roundtrip to Redis. And, Redis is basically just a single-threaded map so you're creating a bottleneck with contention issues.

native canyon
#

If your goal is to protect the server from overload, consider a single global counter rather than or in addition to on a per-IP basis.

native canyon
native canyon