package module
v0.0.0-...-d2b424e Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2017 License: MIT Imports: 4 Imported by: 0


Go Report Card Build Status


Simple go ratelimiter library with redis backend. Supports simple burst prevention algorythm. Requires Redis version >= 3.2.0


go get github.com/3hedgehogs/inredis-ratelimiter


package main

import (


var maxConnections = 10
var redisServer = "localhost:6379"
var redisAuth = ""
var redisDB = 0

func NewPool(server string, password string, db int) *redis.Pool {
    return &redis.Pool{
	MaxIdle:     maxConnections,
	IdleTimeout: 20 * time.Second,
	Dial: func() (redis.Conn, error) {
	    c, err := redis.Dial("tcp", server)
	    if err != nil {
		fmt.Println("Could not connect to redis server:", server, err.Error())
		return nil, err
	    if password != "" {
		if _, err := c.Do("AUTH", password); err != nil {
		    fmt.Printf("Could not connect to redis server: %s using AUTH command, error: %s\n", server, err.Error())
		    return nil, err
	    if _, err := c.Do("select", db); err != nil {
		fmt.Printf("Could not select DB: %d, redis server: %s, error: %s\n", db, server, err.Error())
		return nil, err
	    return c, err
	TestOnBorrow: func(c redis.Conn, t time.Time) error {
	    if time.Since(t) < time.Minute {
		return nil
	    _, err := c.Do("PING")
	    return err

func main() {

    var p = NewPool(redisServer, redisAuth, redisDB)
    var c = p.Get()
    defer c.Close()
    defer p.Close()

    // New RateLimiter: it allows max 10 events per 2 seconds
    l, err := ratelimiter.New("testkey", 10, 2, "", p)

    _ = l.TryAcquire()
    _ = l.CheckLimit()
    fmt.Printf("Current usage: %d\n", l.Usage);



The original idea is from here: https://engineering.classdojo.com/blog/2015/02/06/rolling-rate-limiter/

But moved to use Redis lua scripting due to possible "time" resynchronisations. If clients are not synced with ntp servers well ratelimiting will not work correctly. I still hope the code is small and easy understandable. Used a sliding window is based on Redis sorted set and all used "current slots" are stored there as timestamps. Used in lua script command "redis.replicate_commands()" requires Redis version >=3.2.0.






Package ratelimiter provides a fast and simlpe library to set and check limits using redis backend.



This section is empty.


This section is empty.


This section is empty.


type Limiter

type Limiter struct {
	Usage int // Last seen Counter/Usage

	StopBurst bool // Switch of the burst part (default is off/false)
	// contains filtered or unexported fields

Limiter structure

func New

func New(key string, limit int, period int, rediskey string, pool *redis.Pool, debug ...bool) (*Limiter, error)

New Limiter creation 'rediskey' can be empty, 'debug' parameter is optional

func (*Limiter) AllowBurst

func (l *Limiter) AllowBurst()

AllowBurst sets the flag to swith off anti.burst algorythm

func (*Limiter) CheckLimit

func (l *Limiter) CheckLimit() bool

CheckLimit only checks if the limit was reached or not without slot reservation

func (*Limiter) NoBurst

func (l *Limiter) NoBurst()

NoBurst sets the flag to use anti.burst algorythm

func (*Limiter) Reset

func (l *Limiter) Reset() error

Reset cleans in Redis used data and resets Limiter

func (*Limiter) TryAcquire

func (l *Limiter) TryAcquire() bool

TryAcquire is checking the existing limit and reserves one slot if it possible. return false in cases the limit is reached or some internal errors.

func (*Limiter) UpdatePeriod

func (l *Limiter) UpdatePeriod(newPeriod int) error

UpdatePeriod updates/sets used perPeriod value to the new one.


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL