Skip to content

In-memory limiter

Use this example to see a token bucket refill without running an external service.

Prerequisites

  • Go 1.24 or newer
  • repository dependencies downloaded with go mod download

Run

go run ./examples/inmemory
examples/inmemory/main.go
// Package main demonstrates the usage of the in-memory rate limiter.
package main

import (
    "context"
    "fmt"
    "time"

    "github.com/AliRizaAynaci/gorl/v2"
    "github.com/AliRizaAynaci/gorl/v2/core"
)

// main runs a simple demonstration of the rate limiter.
func main() {
    limiter, err := gorl.New(core.Config{
        Strategy: core.TokenBucket,
        Limit:    3,
        Window:   10 * time.Second,
    })
    if err != nil {
        panic(err)
    }
    defer limiter.Close()

    ctx := context.Background()
    start := time.Now()
    for i := 1; i <= 15; i++ {
        res, err := limiter.Allow(ctx, "127.0.0.1")
        elapsed := time.Since(start).Seconds()
        timestamp := time.Now().Format("15:04:05")

        fmt.Printf("[%s +%.1fs] Request #%d: allowed=%v, remaining=%d, retry_after=%v, err=%v\n",
            timestamp, elapsed, i, res.Allowed, res.Remaining, res.RetryAfter, err,
        )

        time.Sleep(1000 * time.Millisecond)
    }
}

Expected behavior

The bucket has capacity three over ten seconds and begins full. Early requests are allowed, the bucket becomes empty, and later requests become allowed as tokens refill. The program runs for about fifteen seconds and prints timing, remaining capacity, and retry delay for every decision.

Production cautions

State is not shared

Each process has an independent budget. Scaling from one process to three can expose roughly three times the intended aggregate capacity.

Reuse one limiter instead of constructing one per request, keep key cardinality bounded, and call Close so the in-memory cleanup goroutine stops.