Skip to main content

Crate actix_web_ratelimit

Crate actix_web_ratelimit 

Source
Expand description

A simple and highly customizable rate limiting middleware for actix-web 4.

For complete documentation and examples, visit the GitHub repository.

§Features

  • actix-web 4 Compatible: Built specifically for actix-web 4
  • Simple & Easy to Use: Minimal configuration required
  • Pluggable Storage: Support for in-memory and Redis storage backends
  • High Performance: Efficient sliding window algorithm
  • Customizable: Custom client identification and rate limit exceeded handlers
  • Thread Safe: Concurrent request handling with DashMap

§Quick Start

Add this to your Cargo.toml:

[dependencies]
actix-web-ratelimit = "0.1"

# Or, for Redis support
actix-web-ratelimit = { version = "0.1", features = ["redis"] }

§Usage

§Basic Usage with In-Memory Store

    // Configure rate limiting: allow 3 requests per 10-second window
    let config = RateLimitConfig::default().max_requests(3).window_secs(10);
    // Create in-memory store for tracking request timestamps
    let store = Arc::new(MemoryStore::new());

    HttpServer::new(move || {
        App::new()
            // Create and register the rate limit middleware.
            .wrap(RateLimit::new(config.clone(), store.clone()))
            .route("/", web::get().to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await

§Advanced Configuration

    let store = Arc::new(MemoryStore::new());
    let config = RateLimitConfig::default()
        .max_requests(3)
        .window_secs(10)
        // Extract client identifier from req. It is IP (realip_remote_addr) by default.
        .id(|req| {
            req.headers()
                .get("X-Client-Id")
                .and_then(|h| h.to_str().ok())
                .unwrap_or("anonymous")
                .to_string()
        })
        // Custom handler for rate limit exceeded. It returns a 429 response by default.
        .exceeded(|id, config, _req| {
            HttpResponse::TooManyRequests().body(format!(
                "429 caused: client-id: {}, limit: {}req/{:?}",
                id, config.max_requests, config.window_secs
            ))
        });

    HttpServer::new(move || {
        App::new()
            .wrap(RateLimit::new(config.clone(), store.clone()))
            .route("/", web::get().to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await

§Redis Store

First, enable the redis feature:

[dependencies]
actix-web-ratelimit = { version = "0.1", features = ["redis"] }

Then you can use Redis as the storage backend:

    let store = Arc::new(
        RedisStore::new("redis://127.0.0.1/0")
            .expect("Failed to connect to Redis")
            // Custom prefix for Redis keys
            .with_prefix("myapp:ratelimit:"),
    );
    let config = RateLimitConfig::default().max_requests(3).window_secs(10);

    HttpServer::new(move || {
        App::new()
            .wrap(RateLimit::new(config.clone(), store.clone()))
            .route("/", web::get().to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await

§Storage Backends

This crate provides two built-in storage implementations:

For custom storage backends, implement the store::RateLimitStore trait.

§Configuration

Rate limiting behavior is controlled by config::RateLimitConfig:

  • max_requests - Maximum requests allowed within the time window
  • window_secs - Duration of the sliding time window in seconds
  • get_id - Function to extract client identifier from requests
  • on_exceed - Function called when rate limit is exceeded

Modules§

config
store

Structs§

RateLimit
RateLimitMiddleware