How do I build a rate limiter in Go?

Learn how to build a simple rate limiter in Go to control the rate at which your requests are processed. This is essential for protecting your services from abuse and ensuring fair usage of resources.

rate limiter, Go, Golang, API rate limiting, concurrency control


package main

import (
    "fmt"
    "time"
)

type RateLimiter struct {
    tokens      chan struct{}
    requestRate time.Duration
}

func NewRateLimiter(rate int, burst int) *RateLimiter {
    rl := &RateLimiter{
        tokens:      make(chan struct{}, burst),
        requestRate: time.Second / time.Duration(rate),
    }

    // Fill the token bucket
    go func() {
        ticker := time.NewTicker(rl.requestRate)
        defer ticker.Stop()
        for {
            <-ticker.C
            select {
            case rl.tokens <- struct{}{}: // Add a token to the bucket
            default: // Bucket is full, ignore
            }
        }
    }()
    return rl
}

func (rl *RateLimiter) Allow() bool {
    select {
    case <-rl.tokens: // Take a token from the bucket
        return true
    default: // No token available
        return false
    }
}

func main() {
    rl := NewRateLimiter(2, 5) // 2 requests per second, with a burst of 5 requests

    for i := 0; i < 10; i++ {
        if rl.Allow() {
            fmt.Println("Request allowed")
        } else {
            fmt.Println("Request denied")
        }
        time.Sleep(200 * time.Millisecond) // Simulating request interval
    }
}
    

rate limiter Go Golang API rate limiting concurrency control