Skip to main content
The reverse proxy module is a powerful and flexible handler that proxies HTTP requests to upstream servers with load balancing, health checks, circuit breakers, and more. Module ID: http.handlers.reverse_proxy

Overview

Upon proxying, the reverse proxy sets placeholders that can be used in subsequent handlers or logging:

Basic Configuration

array
Static list of backends to proxy to.
string
required
The address to dial to reach the upstream. Supports placeholders and network addresses.Examples:
  • localhost:8080
  • 192.168.1.10:9000
  • unix//var/run/app.sock
integer
Maximum concurrent requests to this upstream. If exceeded, the upstream is considered unhealthy.
module
Module for retrieving the list of upstreams dynamically. Dynamic upstreams are retrieved at every iteration of the proxy loop for each request.
Active health checks do not work on dynamic upstreams. Passive health checks are only effective if the proxy is busy enough that concurrent requests to the same backends are continuous.
Module namespace: http.reverse_proxy.upstreams

Transport

module
Configures the method of transport for the proxy. A transport performs the actual “round trip” to the backend. The default is plaintext HTTP.Module namespace: http.reverse_proxy.transportAvailable transports:
  • http - Standard HTTP transport (default)
  • fastcgi - FastCGI transport for PHP and other applications

Load Balancing

object
Distributes load/requests between backends.
module
How to select an upstream from the pool. Default is random.Available policies:
  • random - Select randomly
  • random_choose - Select N randomly, pick least loaded
  • least_conn - Pick upstream with fewest active requests
  • round_robin - Cycle through upstreams sequentially
  • weighted_round_robin - Round robin with weights
  • first - Select first available
  • ip_hash - Hash based on client IP
  • client_ip_hash - Hash based on trusted client IP
  • uri_hash - Hash based on request URI
  • query - Hash based on query parameter
  • header - Hash based on request header
  • cookie - Hash based on cookie (with sticky sessions)
duration
How long to try selecting available backends for each request.
duration
default:"250ms"
How long to wait between selecting the next host when retrying.
integer
Maximum number of retries (not counting the first attempt).
matcher
Request matcher for determining which requests are idempotent and safe to retry. By default, only GET requests are retried.

Health Checks

object
Configures active and passive health checks.

Active Health Checks

object
Run in the background on a timer. Do not work for dynamic upstreams.
string
The URI (path and query) to use for health checks.
integer
Alternative port to use for health checks (if different from upstream dial address).
object
HTTP headers to set on health check requests.
duration
default:"30s"
How frequently to perform active health checks.
duration
default:"5s"
How long to wait for a response before considering the backend unhealthy.
integer
default:"1"
Number of consecutive passes before marking a previously unhealthy backend as healthy.
integer
default:"1"
Number of consecutive failures before marking a previously healthy backend as unhealthy.
integer
The HTTP status code to expect from a healthy backend.
string
Regular expression to match against the response body of a healthy backend.

Passive Health Checks

object
Monitor proxied requests for errors or timeouts. State is shared globally across all handlers.
duration
How long to remember a failed request. Must be > 0 to enable passive health checks.
integer
default:"1"
Number of failures within fail_duration to mark a backend as down.
integer
Mark backend as down if it has this many concurrent requests or more.
array of integers
HTTP status codes that count as failures.
duration
Count request as failed if response takes at least this long.

Circuit Breaker

module
Acts as an early-warning system for health checks when backends are getting overloaded.Module namespace: http.reverse_proxy.circuit_breakers

Headers

object
Manipulates headers between Caddy and the backend.By default, all headers are passed through without changes, except for special hop-by-hop headers.X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host are set implicitly.
object
Header operations to apply to the request before sending to upstream.
object
Header operations to apply to the response before sending to client.
array of strings
IP ranges (CIDR notation) from which X-Forwarded-* header values should be trusted. By default, no proxies are trusted.

Request/Response Handling

object
Rewrites the copy of the upstream request. Allows changing the request method and URI.The rewrite is applied to the copy, so it doesn’t persist past the reverse proxy handler.If the method is changed to GET or HEAD, the request body will not be copied to the backend.
array
List of handlers to evaluate after successful roundtrips. The first handler that matches the response will be invoked.Three new placeholders available in this handler chain:
  • {http.reverse_proxy.status_code} - Status code from response
  • {http.reverse_proxy.status_text} - Status text from response
  • {http.reverse_proxy.header.*} - Headers from response

Buffering

integer (bytes)
If nonzero, the entire request body up to this size will be read and buffered in memory before being proxied.
This should be avoided if possible for performance reasons, but could be useful if the backend is intolerant of read latency or chunked encodings.
integer (bytes)
If nonzero, the entire response body up to this size will be read and buffered in memory before being proxied to the client.
duration
How often to flush the response buffer. By default, no periodic flushing is done.A negative value disables response buffering and flushes immediately after each write.

Streaming

duration
If nonzero, streaming requests such as WebSockets will be forcibly closed at the end of the timeout.
duration
If nonzero, streaming requests will not be closed when the proxy config is unloaded. Instead, the stream will remain open until the delay is complete.This prevents streams from closing when Caddy’s config is reloaded, avoiding a thundering herd of reconnecting clients.

Configuration Examples

Basic Reverse Proxy

Multiple Upstreams with Load Balancing

With Health Checks

With Header Manipulation

The reverse proxy automatically adds X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host headers unless explicitly configured otherwise.