Rate Limiting in Java: Libraries, Algorithms, and Implementation

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Rate Limiting in Java: From Theory to Practical Implementation



Rate Limiting is one of the key mechanisms for protecting and managing load in modern distributed systems. In Java, this problem is solved both at the level of built-in tools and with the help of specialized libraries. In this article, we will analyze the main algorithms, popular libraries, and provide working code examples.



Why is Rate Limiting needed?

Rate Limiting allows you to:

  • Protect the API from abuse (DDoS, password brute-forcing)
  • Distribute load evenly on the backend
  • Comply with Service Level Agreements (SLA)
  • Prevent exceeding quotas of external services


Basic Rate Limiting Algorithms

Before choosing a library, it is important to understand the underlying algorithms:



1. Token Bucket (Bucket4j, Guava)

A classic algorithm. Tokens are added to a "bucket" at a certain rate. Each request takes one or more tokens. If there are no tokens, the request is rejected.

// Pseudocode exampleclass TokenBucket {    private int tokens;    private long lastRefillTime;    private final int capacity;    private final double refillRate; // tokens per second

synchronized boolean tryConsume() { refill(); if (tokens > 0) { tokens--; return true; } return false; }}


2. Sliding Window Log

Stores timestamps of recent requests. On each new request, it removes timestamps older than the window and checks if the limit has been exceeded. Accurate, but requires memory to store timestamps.



3. Fixed Window Counter

A simple counter for a fixed interval (e.g., 100 requests per minute). Resets every minute. Vulnerable to "burst" loads at window boundaries.



Popular Java Libraries for Rate Limiting



1. Bucket4j

Bucket4j is a mature library that fully implements the Token Bucket algorithm. Supports distributed scenarios via Redis, Hazelcast, JCache. Has a Java 8+ API.

Installation (Maven):

<dependency>    <groupId>com.github.vladimir-bukhtoyarov</groupId>    <artifactId>bucket4j-core</artifactId>    <version>8.7.0</version></dependency>

Usage example:

import io.github.bucket4j.*;import java.time.Duration;

public class Bucket4jExample { public static void main(String[] args) { // Create a bucket: 10 tokens, refill 1 token per second Bandwidth limit = Bandwidth.simple(10, Duration.ofSeconds(1)); Bucket bucket = Bucket4j.builder().addLimit(limit).build();

for (int i = 0; i < 15; i++) { if (bucket.tryConsume(1)) { System.out.println("Request #" + i + " executed"); } else { System.out.println("Request #" + i + " rejected (limit exceeded)"); } } }}


2. Resilience4j RateLimiter

Part of a popular fault-tolerance framework. Works based on SemaphoreBasedRateLimiter or AtomicRateLimiter. Easily integrates with Spring Boot.

Configuration example:

import io.github.resilience4j.ratelimiter.*;import java.time.Duration;

public class Resilience4jExample { public static void main(String[] args) { RateLimiterConfig config = RateLimiterConfig.custom() .limitForPeriod(5) // 5 requests .limitRefreshPeriod(Duration.ofSeconds(1)) // every second .timeoutDuration(Duration.ofMillis(100)) .build();

RateLimiter rateLimiter = RateLimiter.of("myService", config);

for (int i = 0; i < 8; i++) { Runnable task = R

Recommendations