RepoNVIDIANVIDIApublished Oct 14, 2025seen Jun 26

NVIDIA/go-ratelimit

Go

Open original ↗

Captured source

source ↗
published Oct 14, 2025seen Jun 26captured Aug 30http 200method plain

NVIDIA/go-ratelimit

Description: High-performance distributed rate limiting library for Go with Redis backend, sliding window algorithm, and dynamic configuration support

Language: Go

License: Apache-2.0

Stars: 30

Forks: 4

Open issues: 1

Created: 2025-10-14T04:41:09Z

Pushed: 2025-11-13T05:29:01Z

Default branch: main

Fork: no

Archived: no

README:

go-ratelimit - Redis-based Rate Limiting for Go

NVIDIA® go-ratelimit is a comprehensive, Redis-based rate limiting library for Go HTTP services. It provides high-performance, distributed rate limiting with support for both request count and bandwidth (bytes served) limits, making it ideal for protecting APIs and managing resource consumption in cloud-native applications.

For the latest stable version ensure you are on the main branch.

Features

  • Dual Rate Limiting: Limits both request count and response size (bytes served)
  • Sliding Window Algorithm: More accurate than fixed windows, prevents traffic spikes at window boundaries
  • Redis-Based: Works across multiple server instances in a distributed environment
  • Resilient Fallback: Maintains rate limits in memory if Redis becomes unavailable
  • Dynamic Per-Client Configuration: Customize rate limits for each client at runtime
  • RFC Compliant Headers: Returns standard rate limit headers for client awareness
  • Customizable Key Generation: Limit by client ID, IP address, route, or any combination
  • Header-Based Rate Limiting: Rate limit by any HTTP header (API key, tenant ID, custom fields, etc.)
  • Advanced Header Options: Sanitizers, prefixes, fallbacks, and composite keys from multiple headers

Installation

go get github.com/NVIDIA/go-ratelimit/pkg/ratelimit

Quick Start

import (
"github.com/NVIDIA/go-ratelimit/pkg/ratelimit"
"github.com/redis/go-redis/v9"
)

func main() {
// Create Redis client
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})

// Create rate limiter with default options
options := ratelimit.DefaultOptions(rdb)
service := ratelimit.New(options)

// Create your HTTP handler
mux := http.NewServeMux()
mux.HandleFunc("/api/resource", handleResource)

// Apply rate limiting middleware
handler := service.Middleware()(mux)

// Start server
http.ListenAndServe(":8080", handler)
}

Configuration Options

// Create with custom options
options := ratelimit.Options{
Redis: redisClient,
Prefix: "myapp",
RequestLimit: 100, // 100 requests per window
ByteLimit: 5 * 1024 * 1024, // 5MB per window
Window: time.Minute, // 1 minute window
KeyFunc: ratelimit.KeyByClientIDAndRoute("client123"),
Logger: myCustomLogger, // Optional: custom logger for rate limit events
}

service := ratelimit.New(options)

Logger Interface

You can provide a custom logger that implements the middleware.Logger interface:

type Logger interface {
Info(msg string, keysAndValues ...interface{})
Error(msg string, keysAndValues ...interface{})
}

If no logger is provided, the service uses a no-op logger by default.

Key Functions

The library provides several built-in key functions:

// Limit by client ID
ratelimit.KeyByClientID("client123")

// Limit by client ID and route
ratelimit.KeyByClientIDAndRoute("client123")

// Limit by IP address only
ratelimit.KeyByIP

// Limit by HTTP header (NEW)
ratelimit.KeyByHeader("X-API-Key")
ratelimit.KeyByHeader("X-Tenant-ID")
ratelimit.KeyByHeader("X-Custom-Field")

// Advanced header options (NEW)
ratelimit.KeyByHeaderWithOptions(utils.HeaderKeyOptions{
HeaderName: "X-Tenant-ID",
Prefix: "tenant",
Sanitizer: utils.AlphanumericSanitizer,
DefaultValue: "default-tenant",
CaseSensitive: false,
})

// Multiple headers composite key (NEW)
ratelimit.KeyByMultipleHeaders([]string{"X-Tenant-ID", "X-Region"}, ":")

// Header with fallback chain (NEW)
ratelimit.KeyByHeaderWithFallback([]string{"X-API-Key", "Authorization"})

// Custom key function
myKeyFunc := func(r *http.Request) string {
return "custom:" + r.URL.Path
}

Built-in Sanitizers

The library provides several sanitizer functions for cleaning header values:

// Removes non-alphanumeric characters
utils.AlphanumericSanitizer

// Validates and normalizes UUIDs
utils.UUIDSanitizer

// Truncates strings to a maximum length
utils.MaxLengthSanitizer(100)

📖 [Detailed Header-Based Rate Limiting Guide](docs/HEADER_BASED_RATE_LIMITING.md)

Selective Rate Limiting

You can apply rate limiting only to specific endpoints:

// Create a matcher for specific paths
matcher := ratelimit.MatchAny(
ratelimit.MatchPathExact("/api/expensive"),
ratelimit.MatchPathPrefix("/api/users/"),
ratelimit.MatchPathRegex("^/api/.*\\.json$"),
)

// Apply rate limiting only to paths matching the criteria
handler := service.SelectiveMiddleware(matcher)(mux)

Available matchers:

  • MatchPathExact(path) - Matches exact path
  • MatchPathPrefix(prefix) - Matches paths with a specific prefix
  • MatchPathRegex(pattern) - Matches paths using a regular expression
  • MatchAny(matchers...) - Matches if any matcher matches
  • MatchNone(matchers...) - Matches if no matcher matches

Service API

The Service struct provides the following methods:

// Middleware application
service.Middleware() // Apply rate limiting to all requests
service.SelectiveMiddleware(matcher) // Apply rate limiting to specific paths

// Configuration management
service.SetClientConfig(clientID, reqLimit, byteLimit, windowSecs) // Set client-specific limits
service.ResetClientConfig(clientID) // Reset to defaults
service.RegisterConfigAPI(mux) // Register config endpoints

// Access internals
service.GetLimiter() // Get underlying DynamicLimiter

Dynamic Client Configuration

Programmatic Configuration

// Set custom limits for a specific client
service.SetClientConfig("premium-client",
1000, // 1000 requests
10 * 1024 * 1024, // 10MB
60) // per minute

// Reset client to default configuration
service.ResetClientConfig("client-id")

REST API Configuration

Register the configuration API endpoints:

// Register the configuration API
service.RegisterConfigAPI(mux)

This adds the following endpoints:

  • GET /admin/config/{clientID} - Get client's configuration
  • PUT /admin/config/{clientID} - Update client's configuration
  • DELETE /admin/config/{clientID} - Reset client to default configuration

Example API usage:

# Get a client's configuration
curl -H...

Excerpt shown — open the source for the full document.