Skip to content

SpaceLeam/Cadence

Repository files navigation

Cadence

Lightweight in-memory rate limiter for JVM applications using Token Bucket algorithm.

Build Coverage Java License

Features

  • Zero dependencies - Pure Java implementation
  • Thread-safe - Lock-free atomic operations
  • Sub-millisecond latency - Minimal overhead
  • Flexible - Custom capacity, refill rate, weighted tokens
  • Timeout support - Wait for tokens with configurable timeout
  • Monitoring hooks - Integrate with metrics systems
  • Preset configs - Ready-to-use configurations

Installation

Gradle

dependencies {
    implementation("io.github.spaceleam:cadence:1.0.0")
}

Maven

<dependency>
    <groupId>io.github.spaceleam</groupId>
    <artifactId>cadence</artifactId>
    <version>1.0.0</version>
</dependency>

Quick Start

import io.github.spaceleam.cadence.Cadence;
import io.github.spaceleam.cadence.core.RateLimiter;

// Create rate limiter: 100 requests per minute
RateLimiter limiter = Cadence.builder()
    .capacity(100)
    .refillRate(100, TimeUnit.MINUTES)
    .build();

if (limiter.tryAcquire()) {
    // Process request
} else {
    // Rate limited
}

Preset Configurations

RateLimiter loginLimiter = Cadence.forLogin();     // 5 req/min
RateLimiter apiLimiter = Cadence.forAPI();         // 100 req/sec
RateLimiter otpLimiter = Cadence.forOTP();         // 3 req/hour
RateLimiter downloadLimiter = Cadence.forDownload(); // 10 req/hour

Advanced Features

Timeout with Waiting

// Wait up to 5 seconds for a token
if (limiter.tryAcquire(5, TimeUnit.SECONDS)) {
    processRequest();
}

Detailed Result

RateLimitResult result = limiter.tryAcquireWithInfo();
if (!result.isSuccess()) {
    long retryAfter = result.getRetryAfter(TimeUnit.SECONDS);
    return Response.status(429).header("Retry-After", retryAfter).build();
}

Monitoring

RateLimiter limiter = Cadence.builder()
    .capacity(100)
    .listener(new RateLimiterListener() {
        @Override
        public void onAcquire(int tokens) {
            metrics.increment("acquired", tokens);
        }
        @Override
        public void onReject(int requested, int available) {
            metrics.increment("rejected");
        }
    })
    .build();

Documentation

API Reference

RateLimiter

Method Description
tryAcquire() Acquire 1 token
tryAcquire(int tokens) Acquire multiple tokens
tryAcquire(timeout, unit) Acquire with timeout
tryAcquireWithInfo() Acquire with detailed result
getAvailableTokens() Current available tokens
reset() Reset to full capacity

CadenceBuilder

Method Description
capacity(int) Max tokens (default: 10)
refillRate(int, TimeUnit) Tokens per time unit
listener(RateLimiterListener) Add monitoring listener

Performance

Metric Value
Single-thread throughput >1M ops/sec
Multi-thread throughput >5M ops/sec
Latency (p50) <1 µs
Memory per instance ~100 bytes

Requirements

  • Java 21+

License

MIT License - see LICENSE

About

A lightweight, thread-safe rate limiter to keep your application's flow in perfect rhythm.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages