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.
Overview
The throttle 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
import "github.com/go-mizu/mizu/middlewares/throttle"
Quick Start
app := mizu.New()
// Allow max 100 concurrent requests
app.Use(throttle.New(100))
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
// Allow max 100 concurrent requests
app.Use(throttle.New(100))
With Backlog
// 50 concurrent with 200 waiting in queue
app.Use(throttle.WithOptions(throttle.Options{
Limit: 50,
Backlog: 200,
}))
With Timeout
// Wait max 10 seconds for a slot
app.Use(throttle.WithOptions(throttle.Options{
Limit: 50,
Timeout: 10 * time.Second,
}))
// Reject immediately when all slots busy
app.Use(throttle.WithOptions(throttle.Options{
Limit: 100,
Backlog: 0,
BacklogSet: true, // Required to use Backlog: 0
}))
With OnThrottle Callback
app.Use(throttle.WithOptions(throttle.Options{
Limit: 100,
OnThrottle: func(c *mizu.Ctx) {
log.Printf("Request throttled: %s", c.Request().URL.Path)
},
}))
API Reference
Functions
// New creates throttle with concurrent request limit
func New(limit int) mizu.Middleware
// WithOptions creates throttle with configuration
func WithOptions(opts Options) mizu.Middleware
// Concurrency is an alias for New
func Concurrency(limit int) mizu.Middleware
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 the Limit. 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.NewTimer with the configured Timeout
- Three exit conditions: slot acquired, timeout reached, or request context cancelled
- On timeout or cancellation, the backlog counter is decremented
-
Thread Safety: A
sync.Mutex protects the backlog counter to prevent race conditions.
Default Values
Limit: 100 concurrent requests
Backlog: 1000 waiting requests
Timeout: 30 seconds
Error Responses
503 Service Unavailable with “service busy” - backlog capacity exceeded
503 Service Unavailable with “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: true when using Backlog: 0 to disable queueing
- Use
OnThrottle callback 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 |