---
title: "Life of a request"
url: "/docs/concepts/life-of-a-request/"
kind: "concept"
summary: "The path a connection and its requests take through Arion, from accept to upstream and back, and where each filter runs."
---

> Arion site index: [/llms.txt](/llms.txt)

# Life of a request

The path a connection and its requests take through Arion, from accept to upstream and back, and where each filter runs.

The life of a request is the fixed sequence of stages every connection passes through inside Arion — worth knowing whenever you are deciding where a policy belongs or debugging why one fired. Each stage below maps to a configuration surface, so once you can name the stage, you know which page configures it.

## Why it matters

Filters see requests in a strict order, and that order decides behavior: whether RBAC evaluates the original path or the one a filter rewrote, whether a rate limit protects the TLS handshake or only requests, whether a header added on the response passes back through your Wasm filter. Envoy users will recognize the shape deliberately — Arion keeps the same ordering guarantees, which is what makes its [compatibility promise](@/docs/concepts/envoy-compatibility.md) meaningful.

## How it works

{{ <figure src="img/docs/life-of-a-request.svg" alt="Numbered pipeline from accept through listener filters, chain match, network filters, HTTP filters, router, load balancer to upstream, with the response returning through HTTP filters in reverse" caption="The request path in eight stages; the response retraces stages 5–8 in reverse." label="Figure 1." /> }}

1. **Accept.** The kernel hands the new connection to one proxy runtime (every runtime listens on the same port — see [runtime and threading](@/docs/concepts/runtime-and-threading.md)). If the listener has a local rate limit, the token bucket is checked here, before anything is read; over-limit connections are dropped at once. The listener spawns a task, and everything that follows happens on that runtime.

2. **Listener filters.** If PROXY protocol is configured, Arion reads the header first and adopts the original client addresses. If the TLS inspector is enabled, it peeks at the ClientHello to extract the SNI, then rewinds — no bytes are consumed and no handshake happens yet.

3. **Filter chain match.** The listener picks exactly one filter chain by progressively narrowing on destination port, destination IP, SNI, source IP, and source port; at each step only the most specific matches survive. No surviving chain means the connection is closed and counted.

4. **Network filters.** The chain applies its connection-level checks in a fixed order: the connection limit, then the global rate limit (a call to the configured rate limit service), then the [RBAC](@/docs/security/rbac.md) rules, which see addresses and SNI. Only then, for TLS chains, does the handshake run — ALPN selects HTTP/1.1 or HTTP/2 within the configured codec — and the terminal filter takes over: the HTTP connection manager, or the [TCP proxy](@/docs/traffic/tcp-proxy.md), which simply streams bytes to its cluster and skips the remaining stages.

5. **HTTP filters.** The connection manager decodes requests and, for each one, first matches the route (virtual host by domain, then route by path and headers). With the route known, the effective filter list — declared filters plus any [per-route overrides](@/docs/concepts/filter-chain.md) — runs in declared order. Any filter may end the request with a direct response, such as 403 from RBAC or 429 from a rate limit; a filter that rewrites the request can ask for the route to be matched again.

6. **Router.** The matched route's action runs: a direct response, a redirect, or forwarding to a cluster, with the route's header mutations, timeout, and retry policy applied. See [routing](@/docs/traffic/routing.md).

7. **Load balancer and pool.** The cluster is resolved in the registry, circuit breakers admit or refuse the request, and the [load balancing policy](@/docs/traffic/upstreams-and-load-balancing.md) picks a healthy endpoint. The request is sent on that endpoint's connection pool — pooled HTTP/1 connections or a multiplexed HTTP/2 channel.

8. **Upstream and back.** The upstream response streams back and passes through the filters that ran in stage 5 — in reverse order. Filters without response-side behavior (RBAC, rate limits, JWT) are skipped; ext_proc, Wasm, CORS, and the MCP gateway get to act before the response reaches the client.

## Key terms

- **Listener filter** — runs on raw bytes at connection start: PROXY protocol, TLS inspector, local rate limit.
- **Filter chain** — one TLS context, network filter set, and terminal filter, selected per connection.
- **Terminal filter** — the network filter that consumes the connection: HTTP connection manager or TCP proxy.
- **Direct response** — a response produced by a filter or route without contacting any upstream.
- **Connection pool** — per-endpoint reuse of upstream connections across requests.

## Next

- The ordering rules behind stages 2–5, in detail: [the filter chain](@/docs/concepts/filter-chain.md).
- Configure the entry point on the [listeners](@/docs/traffic/listeners.md) page.
- Configure stage 7 in [upstreams and load balancing](@/docs/traffic/upstreams-and-load-balancing.md).
