Skip to main content

Overview

The maxconns middleware limits the maximum number of concurrent connections to protect server resources. Use it when you need:
  • Connection limiting
  • Resource protection
  • DoS mitigation

Installation

import "github.com/go-mizu/mizu/middlewares/maxconns"

Quick Start

app := mizu.New()

// Limit to 1000 concurrent connections
app.Use(maxconns.New(1000))

Configuration

Options

OptionTypeDefaultDescription
MaxintRequiredMax connections
ErrorHandlerfunc(*mizu.Ctx) error503Custom error handler

Examples

Basic Limit

app.Use(maxconns.New(1000))

Custom Error

app.Use(maxconns.New(maxconns.Options{
    Max: 1000,
    ErrorHandler: func(c *mizu.Ctx) error {
        return c.JSON(503, map[string]string{
            "error": "Server at capacity",
        })
    },
}))

With Monitoring

m := maxconns.NewWithMetrics(1000)
app.Use(m.Middleware())

// Monitor in handler
app.Get("/stats", func(c *mizu.Ctx) error {
    return c.JSON(200, map[string]int{
        "active":  m.Active(),
        "max":     m.Max(),
    })
})

API Reference

Functions

// New creates max connections middleware
func New(max int) mizu.Middleware

// NewWithOptions creates with configuration
func NewWithOptions(opts Options) mizu.Middleware

// NewWithMetrics creates with metrics tracking
func NewWithMetrics(max int) *MaxConns

Technical Details

Implementation Architecture

The maxconns middleware uses atomic operations and mutexes to safely manage concurrent connections: Global Connection Tracking:
  • Uses atomic.LoadInt64 and atomic.AddInt64 for lock-free global connection counting
  • Atomic operations ensure thread-safe increments/decrements without mutex overhead
  • Counter is incremented before processing and decremented via defer after completion
Per-IP Connection Limiting:
  • Maintains a map[string]int for per-IP connection counts
  • Protected by sync.RWMutex to allow concurrent reads with exclusive writes
  • IP addresses extracted from X-Forwarded-For, X-Real-IP, or RemoteAddr headers
  • Map entries automatically cleaned up when IP count reaches zero
Connection Lifecycle:
  1. Check global limit using atomic load operation
  2. If PerIP enabled, check IP-specific limit under read lock
  3. Increment both counters (atomic for global, locked for per-IP)
  4. Process request through handler chain
  5. Decrement counters via defer (guarantees cleanup even on errors)
Zero/Negative Max Handling:
  • When Max <= 0, middleware immediately rejects all requests
  • Optimized fast path that bypasses counter management
Error Handling:
  • Default response: 503 Service Unavailable with β€œRetry-After: 60” header
  • Custom error handlers can be configured via Options
  • Error handler receives full context for custom responses

Key Components

Counter Type:
  • Provides observable connection metrics
  • Exposes Current() and Max() methods for monitoring
  • Can be used standalone for custom monitoring solutions
Helper Functions:
  • Global(max): Alias for New(max) for semantic clarity
  • PerIP(max): Convenience function setting per-IP limit with high global max (1,000,000)
  • getClientIP(): Extracts client IP from standard proxy headers

Best Practices

  • Set based on server capacity
  • Monitor connection counts
  • Use with rate limiting
  • Return appropriate error response

Testing

The maxconns middleware includes comprehensive test coverage for all major scenarios:
Test CaseDescriptionExpected Behavior
TestNewConcurrent requests exceeding max limitAccepts up to max connections, rejects excess with 503
TestWithOptions_PerIPMultiple concurrent requests from same IP with PerIP limitOnly allows configured number per IP, rejects others
TestWithOptions_CustomErrorHandlerCustom error handler with Max=0Uses custom handler returning custom status/response
TestPerIPSequential requests with PerIP limitSequential requests succeed as connections are released
TestGlobalGlobal limit using Global() helperRequest succeeds within global limit
TestCounterCounter type for monitoringCounter tracks current connections and exposes metrics
TestRetryAfterHeaderRejected request header validationSets β€œRetry-After: 60” header on 503 responses