> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Adaptive

> Adaptive rate limiting middleware that adjusts based on system load.

## Overview

The `adaptive` middleware dynamically adjusts rate limits based on system metrics like latency, error rate, and resource utilization.

Use it when you need:

* Auto-scaling rate limits
* Load-based throttling
* Self-tuning protection

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/adaptive"
```

## Quick Start

```go theme={null}
app := mizu.New()

// Adaptive limiting based on latency
app.Use(adaptive.New(adaptive.Options{
    MinRate:         10,
    MaxRate:         1000,
    TargetLatency:   100 * time.Millisecond,
}))
```

## Configuration

### Options

| Option            | Type            | Default | Description              |
| ----------------- | --------------- | ------- | ------------------------ |
| `MinRate`         | `int`           | `10`    | Minimum requests/sec     |
| `MaxRate`         | `int`           | `1000`  | Maximum requests/sec     |
| `TargetLatency`   | `time.Duration` | `100ms` | Target response time     |
| `TargetErrorRate` | `float64`       | `0.01`  | Target error rate (1%)   |
| `Window`          | `time.Duration` | `10s`   | Measurement window       |
| `AdjustInterval`  | `time.Duration` | `1s`    | Rate adjustment interval |

## Examples

### Latency-Based

```go theme={null}
app.Use(adaptive.New(adaptive.Options{
    MinRate:       50,
    MaxRate:       500,
    TargetLatency: 200 * time.Millisecond,
}))
```

### Error Rate-Based

```go theme={null}
app.Use(adaptive.New(adaptive.Options{
    MinRate:         10,
    MaxRate:         1000,
    TargetErrorRate: 0.05, // 5% error rate
}))
```

### Combined Metrics

```go theme={null}
app.Use(adaptive.New(adaptive.Options{
    MinRate:         50,
    MaxRate:         500,
    TargetLatency:   100 * time.Millisecond,
    TargetErrorRate: 0.01,
    Window:          30 * time.Second,
    AdjustInterval:  5 * time.Second,
}))
```

## How It Works

1. Measure latency and error rate in sliding window
2. If metrics exceed targets, decrease rate
3. If metrics are good, gradually increase rate
4. Rate stays within min/max bounds

## API Reference

### Functions

```go theme={null}
// New creates adaptive rate limiter
func New(opts Options) mizu.Middleware

// GetCurrentRate returns current rate limit
func GetCurrentRate(c *mizu.Ctx) int
```

## Technical Details

### Architecture

The adaptive middleware uses a token bucket algorithm with dynamic rate adjustment:

* **Token Bucket**: Implements a refillable token bucket where tokens are added at the current rate per second
* **Atomic Operations**: Uses `sync/atomic` for lock-free access to metrics (request count, error count, latency)
* **Background Adjustment**: Runs a goroutine that periodically adjusts the rate based on collected metrics

### Rate Adjustment Algorithm

The middleware adjusts rates based on three conditions:

1. **High Error Rate**: If error rate > threshold, reduce rate by 20%
2. **High Latency**: If average latency > target, reduce rate by 10%
3. **Good Performance**: If latency \< target/2 AND error rate \< threshold/2, increase rate by 10%

All adjustments are clamped to the configured `MinRate` and `MaxRate` bounds.

### Metrics Collection

The middleware tracks:

* **Request Count**: Total requests in current adjustment interval
* **Error Count**: Requests that returned errors
* **Total Latency**: Cumulative response time in nanoseconds
* **Current Rate**: Dynamically adjusted rate limit

Metrics are atomically swapped and reset on each adjustment interval to prevent data races.

### Token Refill Mechanism

Tokens are refilled based on elapsed time:

```
refill = (elapsed_nanoseconds * current_rate) / 1_second_in_nanoseconds
```

Tokens are capped at the current rate to prevent unbounded accumulation.

## Best Practices

* Start with conservative limits
* Set reasonable target latency
* Monitor rate adjustments
* Use with circuit breaker for full protection

## Testing

The adaptive middleware includes comprehensive test coverage for all features and edge cases:

| Test Case                               | Description                      | Expected Behavior                                                    |
| --------------------------------------- | -------------------------------- | -------------------------------------------------------------------- |
| `TestNew`                               | Basic middleware creation        | Middleware processes request successfully                            |
| `TestLimiter_RateLimited`               | Rate limiting enforcement        | First request succeeds, immediate second request is blocked with 429 |
| `TestLimiter_CurrentRate`               | Current rate retrieval           | Returns the configured initial rate                                  |
| `TestLimiter_Stats`                     | Statistics retrieval             | Returns current rate, min/max bounds, and request/error counts       |
| `TestSimple`                            | Simple preset configuration      | Middleware works with default simple settings                        |
| `TestHighThroughput`                    | High throughput preset           | Handles 100 concurrent requests with some successes                  |
| `TestConservative`                      | Conservative preset              | Middleware works with conservative settings                          |
| `TestRetryAfterHeader`                  | Retry-After header on rate limit | Returns "Retry-After: 1" header when rate limited                    |
| `TestCustomErrorHandler`                | Custom error handler             | Uses custom JSON error response instead of default                   |
| `TestNewLimiter_Defaults`               | Default value handling           | Negative values are replaced with sensible defaults                  |
| `TestLimiter_Adjust`                    | Adjustment with no requests      | Rate remains unchanged when no requests are made                     |
| `TestLimiter_AdjustHighErrorRate`       | High error rate adjustment       | Rate decreases when error rate exceeds threshold                     |
| `TestLimiter_AdjustHighLatency`         | High latency adjustment          | Rate decreases when latency exceeds target                           |
| `TestLimiter_AdjustLowLatencyAndErrors` | Good performance adjustment      | Rate increases when latency is low and errors are minimal            |
| `TestLimiter_AdjustClampToMin`          | Minimum rate clamping            | Rate cannot decrease below configured minimum                        |
| `TestLimiter_AdjustClampToMax`          | Maximum rate clamping            | Rate cannot increase above configured maximum                        |
| `TestLimiter_AllowTokenRefill`          | Token refill mechanism           | Tokens are refilled over time after exhaustion                       |
| `TestLimiter_AllowTokenCap`             | Token accumulation limit         | Tokens are capped at current rate, not unlimited                     |
| `TestLimiter_ErrorCounting`             | Error metric tracking            | Requests are counted correctly in statistics                         |

## Related Middlewares

* [ratelimit](/middlewares/ratelimit) - Fixed rate limiting
* [circuitbreaker](/middlewares/circuitbreaker) - Circuit breaker
* [bulkhead](/middlewares/bulkhead) - Bulkhead pattern
