Skip to main content

Backends

In Otoroshi, every route is built from three building blocks: a frontend (what to match), a backend (where to forward), and a plugin chain (what processing to apply). The backend is the part that answers the question: "once a request has been matched, where should it go?"

A backend encapsulates the full downstream configuration: the list of target servers, how to distribute traffic across them, how to connect to them, and how to react when they fail. By grouping all of this into a single entity, Otoroshi cleanly separates routing decisions from forwarding decisions -- you can change your target servers, adjust timeouts, or switch load balancing strategies without touching any routing rule.

Inline vs stored backends

Backends can be used in two ways:

  • Inline -- the backend configuration is embedded directly inside a route definition. This is the simplest approach when a backend is used by a single route.
  • Stored (global) -- the backend is saved as a standalone entity with its own identifier. Multiple routes and APIs can then reference the same backend via backend_ref. When you update the stored backend, every route that references it picks up the change automatically. This is the recommended approach when several routes share the same set of targets.

Key capabilities

  • Multiple targets with weights -- define several downstream servers and assign each a weight to control how traffic is distributed. Mark targets as backup so they only receive traffic when all primary targets are down.
  • Load balancing strategies -- choose from RoundRobin, Random, Sticky, IpAddressHash, BestResponseTime, WeightedBestResponseTime, LeastConnections, PowerOfTwoRandomChoices, Failover, or hash-based strategies on cookies, headers, and query parameters.
  • Health checks -- periodically probe your targets so that unhealthy servers are automatically removed from the load balancing pool.
  • TLS and mTLS to backends -- call targets over HTTPS, present client certificates, pin trusted CA certificates, or trust all certificates for development environments.
  • Path rewriting -- prepend a root path to every forwarded request, or completely rewrite the request path using named path parameters and the expression language.
  • Client configuration -- fine-tune how Otoroshi connects to your targets with retries (with exponential backoff), connection/idle/call timeouts, circuit breaker thresholds, connection pooling, path-specific timeout overrides, and HTTP proxy support.

UI page

You can find all backends here

Properties

PropertyTypeDefaultDescription
targetsarray of Target[]List of target servers
rootstring"/"Path prefix added to each request sent to the downstream service
rewritebooleanfalseWhen enabled, the request path is completely replaced by root. Supports expression language for dynamic rewriting
load_balancingobject{"type": "RoundRobin"}Load balancing algorithm (see below)
health_checkobjectnullOptional health check configuration (see below)
clientobjectHTTP client settings (see below)

Full path rewrite

When rewrite is enabled, the original request path is stripped and replaced by the root value. Combined with named path parameters, this enables powerful URL rewriting:

  • Input: subdomain.domain.tld/api/users/$id<[0-9]+>/bills
  • Output: target.domain.tld/apis/v1/basic_users/${req.pathparams.id}/all_bills

Targets

Each target represents a downstream server that Otoroshi can forward requests to.

PropertyTypeDefaultDescription
idstringUnique identifier of the target
hostnamestringHostname of the target (without scheme)
portnumberPort of the target
tlsbooleanCall the target via HTTPS
weightnumber1Weight used by the load balancing strategy to distribute traffic
protocolstringHTTP/1.1Protocol: HTTP/1.0, HTTP/1.1, HTTP/2.0, or HTTP/3.0
predicateobjectAlwaysMatchPredicate function to filter this target based on request properties
ip_addressstringnullIP address of the target (optional, for DNS bypass)
tls_configobjectTLS settings for this specific target (see below)
backupbooleanfalseIf true, this target is only used when all primary (non-backup) targets are unavailable

Target TLS settings

PropertyTypeDefaultDescription
enabledbooleanfalseEnable custom TLS configuration for this target
loosebooleanfalseIf enabled, will block all untrusted SSL configurations
trust_allbooleanfalseAccept any server certificate, including self-signed ones
certsarray of string[]Client certificate IDs used to communicate with the target
trusted_certsarray of string[]Trusted certificate IDs expected from the target

Target JSON example

{
"id": "target_1",
"hostname": "api.backend.internal",
"port": 8443,
"tls": true,
"weight": 1,
"protocol": "HTTP/1.1",
"predicate": { "type": "AlwaysMatch" },
"ip_address": null,
"tls_config": {
"enabled": true,
"loose": false,
"trust_all": false,
"certs": [],
"trusted_certs": ["cert_backend_ca"]
},
"backup": false
}

Health check

PropertyTypeDefaultDescription
enabledbooleanfalseEnable periodic health checks
urlstringThe URL to call for health checks

When enabled, Otoroshi periodically calls the health check URL. Unhealthy targets can be temporarily removed from the load balancing pool.

Load balancing

TypeDescription
RoundRobinDistributes requests evenly across all targets in order
RandomRandomly selects a target for each request
StickyRoutes requests from the same client to the same target
IpAddressHashSelects target based on a hash of the client IP address
BestResponseTimeRoutes to the target with the lowest response time
WeightedBestResponseTimeCombines weight and response time for target selection

Client settings

Client settings control how Otoroshi connects to backend targets.

PropertyTypeDefaultDescription
retriesnumber1Number of retry attempts after a failed request
max_errorsnumber20Number of errors before opening the circuit breaker
retry_initial_delaynumber50Delay (ms) before the first retry
backoff_factornumber2Multiplier applied to the delay between each retry
connection_timeoutnumber10000Maximum duration (ms) for establishing a connection
idle_timeoutnumber60000Maximum duration (ms) a connection can stay idle
call_and_stream_timeoutnumber120000Maximum duration (ms) for handling the request and streaming the response
call_timeoutnumber30000Maximum duration (ms) for a single call
global_timeoutnumber30000Maximum duration (ms) for the entire call including retries
sample_intervalnumber2000Delay (ms) between retries. Multiplied by backoff_factor at each retry
custom_timeoutsarray of object[]Path-specific timeout overrides (see below)
cache_connection_settingsobjectConnection caching settings (see below)
proxyobjectnullHTTP proxy settings for reaching the backend

Custom timeouts

Custom timeouts allow overriding timeout values for specific paths:

PropertyTypeDefaultDescription
pathstring/*Path pattern to match
connection_timeoutnumber10000Connection timeout (ms)
idle_timeoutnumber60000Idle timeout (ms)
call_and_stream_timeoutnumber3600000Call and stream timeout (ms)
call_timeoutnumber30000Call timeout (ms)
global_timeoutnumber30000Global timeout (ms)

Connection cache settings

PropertyTypeDefaultDescription
enabledbooleanfalseTry to keep TCP connections alive between requests
queue_sizenumber2048Queue size for open TCP connections

Proxy settings

PropertyTypeDescription
hoststringProxy hostname
portnumberProxy port
protocolstringProxy protocol (http or https)
principalstringProxy username
passwordstringProxy password

Complete backend JSON example

{
"targets": [
{
"id": "target_1",
"hostname": "api-1.backend.internal",
"port": 8080,
"tls": false,
"weight": 1,
"protocol": "HTTP/1.1",
"predicate": { "type": "AlwaysMatch" },
"backup": false
},
{
"id": "target_2",
"hostname": "api-2.backend.internal",
"port": 8080,
"tls": false,
"weight": 1,
"protocol": "HTTP/1.1",
"predicate": { "type": "AlwaysMatch" },
"backup": true
}
],
"root": "/api/v1",
"rewrite": false,
"load_balancing": { "type": "RoundRobin" },
"health_check": {
"enabled": true,
"url": "http://api-1.backend.internal:8080/health"
},
"client": {
"retries": 1,
"max_errors": 20,
"retry_initial_delay": 50,
"backoff_factor": 2,
"connection_timeout": 10000,
"idle_timeout": 60000,
"call_and_stream_timeout": 120000,
"call_timeout": 30000,
"global_timeout": 30000,
"sample_interval": 2000,
"cache_connection_settings": {
"enabled": false,
"queue_size": 2048
},
"custom_timeouts": []
}
}

Admin API

GET    /api/backends           # List all stored backends
POST /api/backends # Create a stored backend
GET /api/backends/:id # Get a stored backend
PUT /api/backends/:id # Update a stored backend
DELETE /api/backends/:id # Delete a stored backend
PATCH /api/backends/:id # Partially update a stored backend
  • Routes - Routes reference backends inline or via backend_ref
  • APIs - APIs define backends that are shared across API routes