Skip to content

Repository files navigation

Relay

Relay is a high-performance, distributed rate limiter built with Java 21 and Spring Boot 3. It uses Redis as a centralized state store to manage request counters across multiple application instances, making it suitable for microservices and distributed architectures.

Features

  • Distributed Design: Stateless service instances share state via Redis.
  • Policy-Based Configuration: Define rate limits based on URL patterns or keys.
  • Rate Limiting Algorithm: Fixed window counter using Redis atomic operations (sliding-window–like behavior).
  • High Performance: Minimal overhead using Redis atomic increment and TTL operations.
  • Easy Deployment: Docker Compose support for instant setup.

Tech Stack

  • Java 21
  • Spring Boot 3.5 (Web, Data Redis)
  • Redis 7
  • Docker & Docker Compose
  • Maven

Prerequisites

Developing with Nix (Recommended)

This project uses Nix Flakes to provide a reproducible development environment with Java 21, Maven, and Redis pre-configured.

  1. Install Nix: Download Nix
    • Windows Users: You must use WSL2 to run Nix. It does not work in PowerShell/CMD directly.
  2. Enable Flakes: Ensure experimental-features = nix-command flakes is in your nix.conf.
  3. Enter Environment:
    nix develop
    # Or if you use direnv:
    direnv allow
    You now have java, mvn, and redis-server available in your shell, exactly matching the project version.

Getting Started

Option 1: Run with Docker Compose (Recommended)

This is the fastest way to get everything running (Relay Service + Redis).

  1. Build the application:

    ./mvnw clean package -DskipTests

    (Note: The Dockerfile expects the jar to be in target/)

  2. Start the services:

    docker-compose up --build
  3. The application will start on port 8080 and Redis on port 6379.

Option 2: Run Locally

  1. Start Redis: You need a running Redis instance on localhost:6379.

    docker run -p 6379:6379 redis:7
  2. Run the Application:

    ./mvnw spring-boot:run

Configuration

Rate limiting policies are configured in src/main/resources/application.yml.

The system matches requests using a simple substring match on the "key" (usually a URL path or user ID).

ratelimiter:
  policies:
    # Allow 5 requests every 3 minutes for login
    - pattern: "/login"
      limit: 5
      windowSeconds: 180

    # Allow 100 requests every minute for search
    - pattern: "/search"
      limit: 100
      windowSeconds: 60

  # Default policy if no pattern matches
  default:
    limit: 50
    windowSeconds: 60

API Reference

Check Rate Limit

Endpoint: POST /check

Check if a specific key is allowed.

Request Body:

{
  "key": "/search/user/123"
}

Response:

{
  "allowed": true,
  "remaining": 99
}

Example Usage

curl -X POST http://localhost:8080/check \
     -H "Content-Type: application/json" \
     -d '{"key": "/search"}'

If the limit is exceeded:

{
  "allowed": false,
  "remaining": 0
}

Testing

Run unit and integration tests with Maven:

./mvnw test

About

A high performance distributed rate limiter

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages