# sujaydevx/distributed-rate-limiter-service architecture

> Architecture diagram of the GitHub repository sujaydevx/distributed-rate-limiter-service, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sujaydevx/distributed-rate-limiter-service
- Repository: https://github.com/sujaydevx/distributed-rate-limiter-service

## Overview

#### Purpose and runtime

A Spring Boot Java service implementing distributed, per-client API rate limiting. It runs as an HTTP service, uses Redis as shared mutable state across instances, and exposes Prometheus-compatible metrics. Application startup is `src/main/java/com/sujay/ratelimiter/RateLimiterApplication.java`; runtime configuration is in `src/main/resources/application.yml`.

#### HTTP interception boundary

The servlet filter is the enforcement point: `src/main/java/com/sujay/ratelimiter/filter/RateLimitFilter.java`. It executes before controllers, derives a client identifier from `X-Client-Id` (test override), `X-Forwarded-For`, or source IP, then either:
- permits the request into controller handling, or
- terminates it with HTTP 429, a `Retry-After` header, and a structured error response.

Controllers are therefore downstream consumers of an already-enforced request path: `src/main/java/com/sujay/ratelimiter/controller/RateLimitController.java` and `src/main/java/com/sujay/ratelimiter/controller/DemoController.java`.

#### Algorithm selection and contract

`src/main/java/com/sujay/ratelimiter/service/RateLimiterSelector.java` selects the configured implementation, notably token bucket or fixed window. `src/main/java/com/sujay/ratelimiter/service/RateLimiterService.java` is the common service boundary between the filter and algorithms. Decision results, remaining quota, and retry timing are carried by `src/main/java/com/sujay/ratelimiter/model/RateLimitResult.java` and related response/info models.

This separation allows algorithm replacement through configuration without changing the HTTP filter or controllers.

#### Redis-backed enforcement algorithms

`src/main/java/com/sujay/ratelimiter/service/FixedWindowRateLimiter.java` uses Redis atomic increment semantics for counters scoped by client and time window. It is simple but permits boundary bursts.

`src/main/java/com/sujay/ratelimiter/service/TokenBucketRateLimiter.java` supports burst capacity plus continuous refill. Its state transition is delegated to Redis Lua to atomically read, refill, consume, and persist bucket state:
- `src/main/resources/scripts/token_bucket.lua`
- `src/main/resources/scripts/sliding_window.lua`

`src/main/java/com/sujay/ratelimiter/service/SlidingWindowRateLimiter.java` is also present as an algorithm component, though the documented configured choices are token bucket and fixed window.

#### Failure policy and configuration

Redis connectivity and script/template setup are centralized in `src/main/java/com/sujay/ratelimiter/config/RedisConfig.java`. Rate limits and algorithm selection are bound through `src/main/java/com/sujay/ratelimiter/config/RateLimiterProperties.java`.

Algorithms handle Redis exceptions with fail-open behavior: requests proceed when Redis is unavailable, favoring API availability over strict quota enforcement. A circuit-breaker metrics configuration exists at `src/main/java/com/sujay/ratelimiter/config/CircuitBreakerMetricsConfig.java`, but the README identifies active circuit breaking as future scope.

#### Observability and local infrastructure

Each allow/deny decision is emitted as Prometheus metric `ratelimiter_decisions_total`, tagged by algorithm and decision. Local dependencies are orchestrated in `infra/docker-compose.yml`: Redis, Prometheus (`infra/prometheus.yml`), and Grafana with a provisioned Prometheus datasource (`infra/grafana/datasources/prometheus.yml`). Load generation targets the HTTP boundary via `infra/k6/load-test.js`.

Main entry points: [`src/main/java/com/sujay/ratelimiter/filter/RateLimitFilter.java`](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/filter/RateLimitFilter.java) (Rate limit filter), [`src/main/java/com/sujay/ratelimiter/service/RateLimiterService.java`](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/RateLimiterService.java) (Rate limiter contract), [`infra/docker-compose.yml`](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/docker-compose.yml) (Local stack), [`src/main/java/com/sujay/ratelimiter/service/TokenBucketRateLimiter.java`](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/TokenBucketRateLimiter.java) (Token bucket)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_http["HTTP enforcement"]
  node_app["Spring Boot application"]
  node_filter["Rate limit filter<br/>servlet filter"]
  node_controllers["Controllers"]
  node_demo_controller["Demo controller<br/>HTTP controller"]
end

subgraph group_algorithms["Rate-limit algorithms"]
  node_selector["Algorithm selector<br/>service selector"]
  node_service_contract["Rate limiter contract<br/>service interface"]
  node_result["Decision result<br/>result model"]
  node_token_bucket["Token bucket<br/>rate-limit algorithm"]
  node_fixed_window["Fixed window<br/>rate-limit algorithm"]
  node_sliding_window["Sliding window<br/>rate-limit algorithm"]
end

subgraph group_platform["State and observability"]
  node_properties["Rate-limit properties<br/>configuration binding"]
  node_redis_config["Redis configuration<br/>Redis integration<br/>[RedisConfig.java]"]
  node_redis[("Redis<br/>shared rate-limit state")]
  node_token_script["Token bucket Lua<br/>Redis Lua script<br/>[token_bucket.lua]"]
  node_sliding_script["Sliding window Lua<br/>Redis Lua script<br/>[sliding_window.lua]"]
  node_metrics["Decision metrics<br/>Prometheus metric"]
end

subgraph group_local["Local infrastructure"]
  node_prometheus[("Prometheus<br/>metrics collector<br/>[prometheus.yml]")]
  node_grafana["Grafana<br/>metrics dashboard<br/>[prometheus.yml]"]
  node_compose["Local stack<br/>Docker Compose<br/>[docker-compose.yml]"]
  node_load_test["k6 load test<br/>load generator<br/>[load-test.js]"]
end

node_app -->|"starts"| node_filter
node_filter -->|"checks quota"| node_selector
node_filter -->|"allows"| node_controllers
node_filter -->|"allows"| node_demo_controller
node_selector -->|"selects implementation"| node_service_contract
node_properties -->|"chooses algorithm"| node_selector
node_service_contract -->|"implementation"| node_token_bucket
node_service_contract -->|"implementation"| node_fixed_window
node_service_contract -.->|"implementation"| node_sliding_window
node_token_bucket -->|"returns"| node_result
node_fixed_window -->|"returns"| node_result
node_sliding_window -->|"returns"| node_result
node_token_bucket -->|"executes"| node_token_script
node_sliding_window -->|"executes"| node_sliding_script
node_token_script -->|"atomic state transition"| node_redis
node_sliding_script -->|"atomic state transition"| node_redis
node_fixed_window -->|"atomic increments"| node_redis
node_redis_config -->|"connects to"| node_redis
node_filter -->|"emits decisions"| node_metrics
node_prometheus -->|"scrapes"| node_metrics
node_grafana -->|"queries"| node_prometheus
node_compose -->|"runs"| node_redis
node_compose -->|"runs"| node_prometheus
node_compose -->|"runs"| node_grafana
node_load_test -->|"sends HTTP traffic"| node_filter

click node_app "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/RateLimiterApplication.java"
click node_filter "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/filter/RateLimitFilter.java"
click node_controllers "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/controller/RateLimitController.java"
click node_demo_controller "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/controller/DemoController.java"
click node_selector "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/RateLimiterSelector.java"
click node_service_contract "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/RateLimiterService.java"
click node_result "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/model/RateLimitResult.java"
click node_token_bucket "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/TokenBucketRateLimiter.java"
click node_fixed_window "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/FixedWindowRateLimiter.java"
click node_sliding_window "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/SlidingWindowRateLimiter.java"
click node_properties "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/config/RateLimiterProperties.java"
click node_redis_config "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/config/RedisConfig.java"
click node_token_script "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/resources/scripts/token_bucket.lua"
click node_sliding_script "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/resources/scripts/sliding_window.lua"
click node_prometheus "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/prometheus.yml"
click node_grafana "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/grafana/datasources/prometheus.yml"
click node_compose "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/docker-compose.yml"
click node_load_test "https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/k6/load-test.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_filter,node_controllers,node_demo_controller toneBlue
class node_selector,node_service_contract,node_result,node_token_bucket,node_fixed_window,node_sliding_window toneAmber
class node_properties,node_redis_config,node_redis,node_token_script,node_sliding_script,node_metrics toneMint
class node_prometheus,node_grafana,node_compose,node_load_test toneRose
```

## Components

### HTTP enforcement

- [Spring Boot application](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/RateLimiterApplication.java): application · `src/main/java/com/sujay/ratelimiter/RateLimiterApplication.java`
- [Rate limit filter](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/filter/RateLimitFilter.java): servlet filter · Derives clients and allows requests or returns 429 with Retry-After. · `src/main/java/com/sujay/ratelimiter/filter/RateLimitFilter.java`
- [Controllers](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/controller/RateLimitController.java): HTTP controllers · Receive only requests permitted by the filter. · `src/main/java/com/sujay/ratelimiter/controller/RateLimitController.java`
- [Demo controller](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/controller/DemoController.java): HTTP controller · `src/main/java/com/sujay/ratelimiter/controller/DemoController.java`

### Rate-limit algorithms

- [Algorithm selector](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/RateLimiterSelector.java): service selector · `src/main/java/com/sujay/ratelimiter/service/RateLimiterSelector.java`
- [Rate limiter contract](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/RateLimiterService.java): service interface · Common boundary between HTTP enforcement and algorithms. · `src/main/java/com/sujay/ratelimiter/service/RateLimiterService.java`
- [Decision result](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/model/RateLimitResult.java): result model · Carries allow/deny, remaining quota, and retry timing. · `src/main/java/com/sujay/ratelimiter/model/RateLimitResult.java`
- [Token bucket](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/TokenBucketRateLimiter.java): rate-limit algorithm · Supports burst capacity and continuous refill. · `src/main/java/com/sujay/ratelimiter/service/TokenBucketRateLimiter.java`
- [Fixed window](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/FixedWindowRateLimiter.java): rate-limit algorithm · Uses atomic counters; permits boundary bursts. · `src/main/java/com/sujay/ratelimiter/service/FixedWindowRateLimiter.java`
- [Sliding window](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/service/SlidingWindowRateLimiter.java): rate-limit algorithm · `src/main/java/com/sujay/ratelimiter/service/SlidingWindowRateLimiter.java`

### State and observability

- [Rate-limit properties](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/config/RateLimiterProperties.java): configuration binding · `src/main/java/com/sujay/ratelimiter/config/RateLimiterProperties.java`
- [Redis configuration](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/java/com/sujay/ratelimiter/config/RedisConfig.java): Redis integration · Centralizes connectivity and script/template setup. · `src/main/java/com/sujay/ratelimiter/config/RedisConfig.java`
- **Redis**: shared rate-limit state · Shared mutable state across service instances.
- [Token bucket Lua](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/resources/scripts/token_bucket.lua): Redis Lua script · Atomically refills, consumes, and persists bucket state. · `src/main/resources/scripts/token_bucket.lua`
- [Sliding window Lua](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/src/main/resources/scripts/sliding_window.lua): Redis Lua script · `src/main/resources/scripts/sliding_window.lua`
- **Decision metrics**: Prometheus metric · Emits ratelimiter_decisions_total tagged by algorithm and decision.

### Local infrastructure

- [Prometheus](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/prometheus.yml): metrics collector · `infra/prometheus.yml`
- [Grafana](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/grafana/datasources/prometheus.yml): metrics dashboard · `infra/grafana/datasources/prometheus.yml`
- [Local stack](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/docker-compose.yml): Docker Compose · Orchestrates Redis, Prometheus, and Grafana. · `infra/docker-compose.yml`
- [k6 load test](https://github.com/sujaydevx/distributed-rate-limiter-service/blob/main/infra/k6/load-test.js): load generator · Targets the HTTP enforcement boundary. · `infra/k6/load-test.js`

## Connections

- Spring Boot application → Rate limit filter: starts
- Rate limit filter → Algorithm selector: checks quota
- Rate limit filter → Controllers: allows
- Rate limit filter → Demo controller: allows
- Algorithm selector → Rate limiter contract: selects implementation
- Rate-limit properties → Algorithm selector: chooses algorithm
- Rate limiter contract → Token bucket: implementation
- Rate limiter contract → Fixed window: implementation
- Rate limiter contract → Sliding window: implementation
- Token bucket → Decision result: returns
- Fixed window → Decision result: returns
- Sliding window → Decision result: returns
- Token bucket → Token bucket Lua: executes
- Sliding window → Sliding window Lua: executes
- Token bucket Lua → Redis: atomic state transition
- Sliding window Lua → Redis: atomic state transition
- Fixed window → Redis: atomic increments
- Redis configuration → Redis: connects to
- Rate limit filter → Decision metrics: emits decisions
- Prometheus → Decision metrics: scrapes
- Grafana → Prometheus: queries
- Local stack → Redis: runs
- Local stack → Prometheus: runs
- Local stack → Grafana: runs
- k6 load test → Rate limit filter: sends HTTP traffic
