Overview
Thethrottle middleware limits the number of concurrent requests being processed, ensuring your application doesn’t get overwhelmed by too many simultaneous operations.
Use it when you need:
- Limit concurrent request processing
- Prevent resource exhaustion
- Control server load
- Queue requests during high traffic
Installation
Quick Start
Configuration
Options
| Option | Type | Default | Description |
|---|---|---|---|
Limit | int | 100 | Maximum concurrent requests |
Backlog | int | 1000 | Max queued requests waiting for a slot |
BacklogSet | bool | false | Internal flag for explicit backlog setting |
Timeout | time.Duration | 30s | Max wait time for a slot |
OnThrottle | func(*mizu.Ctx) | nil | Callback when request is throttled |
Examples
Simple Throttle
With Backlog
With Timeout
No Backlog (Immediate Rejection)
With OnThrottle Callback
API Reference
Functions
Technical Details
Implementation
The throttle middleware uses a semaphore-based approach to control concurrency:-
Semaphore: A buffered channel (
chan struct{}) acts as a semaphore with capacity equal to theLimit. Each slot represents permission to process one request concurrently. -
Request Flow:
- When a request arrives, the middleware attempts to acquire a slot from the semaphore (non-blocking)
- If a slot is available immediately, the request proceeds
- If no slot is available, the request checks the backlog capacity
-
Backlog Queue:
- A counter tracks the number of requests waiting for a slot
- If backlog capacity is reached, new requests are rejected immediately with
503 Service Unavailable - Requests in the backlog wait with a timeout for a slot to become available
-
Timeout Handling:
- Waiting requests use
time.NewTimerwith the configuredTimeout - Three exit conditions: slot acquired, timeout reached, or request context cancelled
- On timeout or cancellation, the backlog counter is decremented
- Waiting requests use
-
Thread Safety: A
sync.Mutexprotects the backlog counter to prevent race conditions.
Default Values
Limit: 100 concurrent requestsBacklog: 1000 waiting requestsTimeout: 30 seconds
Error Responses
503 Service Unavailablewith “service busy” - backlog capacity exceeded503 Service Unavailablewith “request timeout” - timeout waiting for slot
Throttle vs Rate Limit
| Feature | Throttle | Rate Limit |
|---|---|---|
| Purpose | Limit concurrency | Limit request rate |
| Behavior | Queues requests | Rejects excess |
| Metric | Concurrent requests | Requests per time window |
| Use case | Resource protection | Abuse prevention |
Best Practices
- Use for upstream service protection
- Set reasonable wait timeouts
- Monitor queue depths
- Combine with rate limiting for full control
- Set
BacklogSet: truewhen usingBacklog: 0to disable queueing - Use
OnThrottlecallback for monitoring and metrics collection
Testing
| Test Case | Description | Expected Behavior |
|---|---|---|
TestNew | Tests basic concurrency limiting with limit of 2 | Maximum concurrent requests never exceeds the configured limit (2) |
TestWithOptions_Backlog | Tests backlog queue with limit=1, backlog=1 | With 3 concurrent requests, at least one should be rejected with 503 Service Unavailable |
TestWithOptions_Timeout | Tests timeout functionality with 50ms timeout and slow handler (200ms) | Second request should timeout waiting for slot and return 503 Service Unavailable |
TestWithOptions_OnThrottle | Tests OnThrottle callback with zero backlog | OnThrottle callback is invoked when a request is throttled/rejected |
TestConcurrency | Tests the Concurrency alias function | Concurrency() alias works identically to New() and processes requests successfully |