Skip to main content

Routing and Upstreams

This page expands the routing, upstream, backend, and load-balancing sections of the Configuration Reference. The main configuration reference remains authoritative for the schema; this page keeps the traffic-selection rules together in one place.

Upstream Schema​

The top-level upstream value is a non-empty map. Each key is an upstream pool name used by routing, metrics, runtime views, and policies such as brownout core_routes.

FieldTypeRequiredDefaultMeaning
routeobjectYes—Request matcher for this upstream.
backendsarray of objectsYes—Non-empty backend pool.
load_balancingobjectNo{ type: round-robin, key: null }Backend-selection policy for this upstream.
authobjectNo{}API-key, JSON Web Token (JWT), external-auth, scope, and role policy for this route. See Authentication and Secrets.
host_policyobjectNo{ mode: pass_through, host: null }Upstream Host/:authority selection.
forwarded_headersobjectNo{ mode: overwrite }Forwarded and X-Forwarded-* handling.
tlsobject or nullNonullComplete per-upstream TLS override. null inherits upstream_tls.

Upstream names must be non-empty. The top-level load_balancing field is not a fallback in v0.6; each upstream either configures its own policy or uses round-robin.

Route Matching​

FieldTypeRequiredDefaultMeaning
hoststring or nullConditionallynullExact host or a single leading-wildcard suffix such as *.example.com. At least host or path_prefix is required.
path_prefixstring or nullConditionallynullNon-empty path beginning with /. At least host or path_prefix is required.
methodstring or nullNonullOptional HTTP method restriction.

All configured fields must match the request. A method alone does not make a valid route.

Host Behavior​

  • Matching is case-insensitive.
  • Configuration and request hosts are trimmed and normalized to lowercase.
  • A numeric port and one or more trailing dots are removed before matching.
  • An exact host matches only that host.
  • A leading wildcard matches one or more subdomain labels. For example, *.example.com matches api.example.com and a.b.example.com, but not example.com.
  • Only one leading *. wildcard is accepted. Embedded wildcards, whitespace, paths, queries, and fragments are rejected.

Path Behavior​

  • Routing uses the URI path and ignores the query component.
  • Prefixes match on segment boundaries. /api matches /api and /api/users, but not /apix.
  • / is the catch-all path prefix.
  • Percent-encoded unreserved bytes are canonicalized before matching, so /%61pi is routed as /api. Ambiguous encodings and path forms are rejected by request validation.

Method Behavior​

The configured method is trimmed and normalized to uppercase. Request matching is therefore case-insensitive. An omitted, null, empty, or whitespace-only value means any method. Use valid HTTP method tokens such as GET, POST, or DELETE.

Selection Precedence​

Declaration order does not choose a route. When more than one route matches, Impulse applies these tie-breakers in order:

  1. Longer path_prefix.
  2. Host-specific route over a host-agnostic route.
  3. Exact host over a wildcard host.
  4. Longer wildcard suffix, so *.a.example.com beats *.example.com.
  5. Method-specific route over a method-agnostic route.
  6. Lexicographically smaller upstream name.

Duplicate normalized (host, path_prefix, method) matchers are rejected.

Load-Balancing Schema​

FieldTypeRequiredDefaultMeaning
typestringNoround-robinStrategy name or accepted alias. Values are matched case-insensitively; surrounding whitespace is not accepted.
keystring or nullNonullRequest-key source used by consistent-hash, or by sticky-cid as an explicit override.

Strategies and Aliases​

StrategyAccepted valuesSelection behavior
Round robinround-robin, round_robin, rrWalks a deterministic weighted schedule of healthy backends.
RandomrandomSamples healthy backends in proportion to weight.
Consistent hashconsistent-hash, consistent_hash, chMaps a request key onto a weighted hash ring; the same key remains stable while healthy membership is unchanged.
Least connectionsleast-connections, least_connections, lcChooses the healthy backend with the fewest active requests; backend index breaks ties.
Latency awarelatency-aware, latency_aware, laScores measured latency plus active-request pressure, with bounded probing and exploration for unsampled backends.
Sticky CIDsticky-cid, sticky_cid, cid-sticky, cid_stickyUses the consistent-hash ring with the QUIC connection ID by default.

Unknown strategy names are rejected. Every strategy excludes unhealthy backends. If no healthy backend remains, selection fails instead of sending to an unhealthy backend.

Request-Key Sources​

Request-key specifications are trimmed and normalized to lowercase. A header, cookie, or query source must include a non-empty name after the colon.

Accepted valueMeaning
header:<name>Value of the named request header. Header names are case-insensitive.
cookie:<name>Value of the named cookie from the Cookie header. Cookie-name comparison is case-insensitive.
query:<name>Value of the named query parameter. Parameter-name comparison is case-insensitive.
pathRequest path without the query string.
authorityRequest authority.
methodUppercase HTTP method.
cid, sticky-cidAliases for the current QUIC connection ID.
peer_ip, client_ipAliases for the connected client IP when that value is available to the selector.
bearer_tokenToken from a case-insensitive Bearer scheme in the Authorization header.

In the v0.6 backend-selection path, the client socket address is not supplied to the request-key resolver. Consequently, peer_ip and client_ip are accepted configuration values but fall through to the default key during backend selection. They remain usable by policy selectors that supply a client address.

An unsupported key specification is rejected during configuration validation. If extraction from a valid specification produces a missing, empty, invalid, or unavailable value, selection uses the default key: request authority when present, otherwise the request target, otherwise the method. For sticky-cid, an available connection ID is tried before that default. An explicit key overrides the normal sticky-cid CID choice when extraction succeeds.

Strategies other than consistent-hash and sticky-cid accept a valid key value but do not use it to choose a backend.

Backend Weights​

Every backend weight must be in the inclusive range 1–1000; the default is 100.

StrategyWeight supportEffect
round-robinSupportedControls frequency in the deterministic schedule.
randomSupportedControls relative selection probability.
consistent-hashSupportedControls virtual-node count on the hash ring.
sticky-cidSupportedControls virtual-node count on its consistent-hash ring.
least-connectionsRejected unless 100The strategy is intentionally unweighted.
latency-awareRejected unless 100The strategy is intentionally unweighted.

Backends​

FieldTypeRequiredDefaultMeaning
idstringYes—Non-empty label used in logs, metrics, and runtime views.
addressstringYes—Backend origin: host, host:port, https://host[:port], http://host[:port], or bracketed IPv6 with an explicit port.
weightintegerNo100Relative weight in the range 1–1000, subject to the strategy matrix above.
health_checkobject or nullNonullActive health-check policy. null disables active polling.

Only http and https schemes are accepted. Addresses cannot contain a path, query, or fragment. A missing scheme means HTTPS. HTTPS defaults to port 443 and selects HTTP/2 transport; HTTP defaults to port 80 and selects HTTP/1.1. Both protocols can appear in one upstream. Duplicate normalized origins are rejected across the entire configuration.

Health Checks​

FieldTypeRequiredDefaultMeaning
pathstringNo/healthRequest path. A blank value is normalized to /.
intervalintegerNo5000Poll interval in milliseconds; must be greater than 0.
timeout_msintegerNo1000Per-check timeout in milliseconds; must be greater than 0.
failure_thresholdintegerNo3Consecutive failures required to mark the backend unhealthy; must be greater than 0.
success_thresholdintegerNo2Consecutive successes required to mark the backend healthy; must be greater than 0.
cooldown_msintegerNo5000Unhealthy cooldown in milliseconds; must be greater than 0.

Omitting health_check disables active polling. Passive health and other runtime eligibility signals can still remove a backend from selection.

Backend DNS refresh is global, under performance:

FieldTypeRequiredDefaultMeaning
backend_dns_refresh_enabledbooleanNofalseEnables periodic refresh for hostname backends.
backend_dns_refresh_interval_msintegerNo30000Refresh interval in milliseconds; must be greater than 0 even when refresh is disabled.

Upstream Request Headers and TLS​

FieldTypeRequiredDefaultMeaning
host_policy.modestringNopass_throughHost selection mode.
host_policy.hoststring or nullConditionallynullRequired for rewrite; rejected for other modes.
forwarded_headers.modestringNooverwriteForwarded-header handling mode.

host_policy.mode accepts these canonical values:

ModeBehavior
pass_throughUses client :authority, then client Host, then backend authority. The alias pass-through is also accepted.
rewriteUses the required static host_policy.host value.
upstreamUses the backend authority, including its port.

host_policy.host is required for rewrite and rejected for other modes.

forwarded_headers.mode controls Forwarded, X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host:

ModeBehavior
overwriteDiscards inbound values and writes the current hop.
appendRetains the inbound chain and appends the current hop.
preserveRetains inbound values without adding the current hop.

When upstream.<name>.tls is present, it replaces rather than merges with the top-level upstream_tls policy.

FieldTypeRequiredDefaultMeaning
verify_certificatesbooleanNotrueVerifies the backend certificate and identity.
strict_snibooleanNotrueSends the backend hostname in the TLS SNI extension.
ca_filestring or nullNonullPEM CA bundle path.
ca_dirstring or nullNonullDirectory containing PEM CA material.
client_certificatestring or nullConditionallynullClient-certificate PEM file path; must be paired with a client key.
client_certificate_refobject or nullConditionallynullSecret reference ({ ref: "..." }) for the client certificate; mutually exclusive with client_certificate.
client_keystring or nullConditionallynullClient private-key PEM file path; must be paired with a client certificate.
client_key_refobject or nullConditionallynullSecret reference ({ ref: "..." }) for the client key; mutually exclusive with client_key.

Client certificate and key settings require at least one HTTPS backend. Setting strict_sni: false disables SNI only; it does not disable certificate verification. See TLS Configuration for CA composition, client mTLS, and activation behavior.

Canonical Example​

This is the only complete backend-pool example on this page. It demonstrates combined host, path, and method routing; an explicit request key; weighted consistent hashing; and active health checks.

upstream:
tenant_api:
route:
host: "api.example.com"
path_prefix: "/v1"
method: GET
load_balancing:
type: consistent-hash
key: "header:x-tenant-id"
host_policy:
mode: upstream
forwarded_headers:
mode: overwrite
backends:
- id: "api-a"
address: "https://api-a.internal.example:8443"
weight: 100
health_check:
path: "/ready"
interval: 5000
timeout_ms: 1000
failure_threshold: 3
success_threshold: 2
cooldown_ms: 5000
- id: "api-b"
address: "https://api-b.internal.example:8443"
weight: 200
health_check:
path: "/ready"
interval: 5000
timeout_ms: 1000
failure_threshold: 3
success_threshold: 2
cooldown_ms: 5000