---
title: "The configuration model"
url: "/docs/concepts/configuration-model/"
kind: "concept"
summary: "The Arion file's top-level keys, how flags and environment variables override them, and how static and dynamic resources fit together."
---

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

# The configuration model

The Arion file's top-level keys, how flags and environment variables override them, and how static and dynamic resources fit together.

Arion is configured by one YAML file whose top-level keys tune the process and whose `envoy_bootstrap` key carries the actual proxy resources in Envoy's own format — this page explains that split and everything that can override it. Read it before writing your first proxy config; examples marked as proxy configuration fragments fit inside this file.

## Why it matters

The model draws a deliberate line. Process-level concerns — threading, logging, metrics — are Arion's own keys, small and stable. Everything that describes traffic — listeners, clusters, routes, secrets — lives inside `envoy_bootstrap` in standard Envoy syntax, which is why existing Envoy configs, control planes, and tooling carry over (see [the compatibility promise](@/docs/concepts/envoy-compatibility.md)). Knowing which side of the line a setting sits on tells you where to look it up and whether an environment variable can change it.

## How it works

The file has six top-level keys. `runtime`, `logging`, `access_logging`, `metrics`, and `timezone` configure the process; the resources come from **at most one** of `bootstrap` (Arion's [native format](@/reference/configuration/native-bootstrap.md)) or `envoy_bootstrap` (an Envoy v3 bootstrap, verbatim). Setting both is an error, and a config that ends up with no listeners and no ADS cluster is refused at startup because there is nothing to serve. Every key has a default; the documentation uses `envoy_bootstrap` throughout.

```yaml,name=arion.yaml,arion=fragment
runtime:
  num_cpus: 4
  num_runtimes: 2
logging:
  log_level: info
envoy_bootstrap:
  dynamic_resources:
    ads_config:
      grpc_services:
        - envoy_grpc: { cluster_name: xds }
  static_resources:
    clusters:
      # the xds cluster, plus any static listeners and clusters
```

{{ <figure src="img/docs/configuration-model.svg" alt="File, environment variables and CLI flags converge into the parsed Config, which splits into static resources and xDS-delivered dynamic resources" caption="Three inputs, one parsed model, two kinds of resources." label="Figure 1." /> }}

### Flags and environment variables

The command line selects the file and can override the `runtime` block; it never changes resources. `arion -c arion.yaml` is the normal invocation. `--with-envoy-bootstrap envoy.yaml` loads a plain, unmodified Envoy bootstrap file — either on its own (no `-c`, defaults for everything else) or alongside `-c`, in which case it replaces the file's bootstrap. The runtime flags mirror the `runtime` keys: `--num-cpus`, `--num-runtimes`, `--num-service-threads`, `--global-queue-interval`, `--event-interval`, `--max-io-events-per-tick`.

Environment variables cover the same runtime settings for container use — `ARION_CPU_LIMIT` (alias `ARION_GATEWAY_CORES`), `ARION_GATEWAY_RUNTIMES`, `ARION_SERVICE_THREADS`, and `ARION_RT_*` for the Tokio tuning knobs. Precedence is environment variable, then flag, then file. The full lists live in the [CLI](@/reference/configuration/cli.md) and [environment variable](@/reference/configuration/environment-variables.md) references.

### Static and dynamic resources

`static_resources` — listeners, clusters, and secrets — are parsed, validated, and live before the first connection is accepted. `dynamic_resources` instead delegates to a control plane: `ads_config` names a cluster (defined in `static_resources`) that serves aggregated xDS over gRPC, and Arion subscribes to listener, cluster, route, endpoint, and secret updates on that stream. The two mix freely — a common pattern is static listeners whose route configuration arrives via `rds` with `config_source: { ads: {} }`. Resources are identical in both channels; a listener delivered over xDS is parsed by the same code, and rejected under the same rules, as one written in the file. See [xDS control planes](@/docs/operate/xds-control-planes.md) for the operational side.

The [Arion control plane](@/docs/operate/arion-control-plane.md) also accepts YAML resource documents through `arionctl apply`. These use `apiVersion: ctl.arion.io/v1alpha1`, with resource identity and fleet in `metadata` and the Envoy resource in `spec`. They configure the resources delivered over xDS; proxy process settings and the connection to the control plane remain in the bootstrap file described here.

> [!NOTE]
> Arion validates the entire file before starting any runtime. A misspelled key, an unsupported Envoy field, or both `bootstrap` and `envoy_bootstrap` set will stop the process with an error naming the offending path — nothing is silently ignored.

## Key terms

- **`envoy_bootstrap`** — the top-level key holding a standard Envoy v3 bootstrap; the canonical dialect in these docs.
- **Native bootstrap** — the same model in Arion's own YAML shape, under `bootstrap`.
- **Static resources** — listeners, clusters, and secrets defined in the file and live at startup.
- **Dynamic resources** — resources subscribed from a control plane over the ADS stream.
- **Runtime overrides** — environment variables and flags that adjust the `runtime` block only.

## Next

- Every top-level key and field: the [file format reference](@/reference/configuration/file-format.md).
- What the `runtime` block actually controls: [runtime and threading](@/docs/concepts/runtime-and-threading.md).
- Serve the bootstrap's resources from a control plane: [xDS control planes](@/docs/operate/xds-control-planes.md).
