Skip to main content

Startup Configuration Reference

This reference documents the startup configuration file that defines process-level settings such as listeners, resource-source connectivity, TLS, observability, cache and rate-limit backends, and the AISIX Cloud connection.

Models, caller API keys, provider keys, guardrails, cache policies, and observability exporters are not defined in the startup configuration. For an open-source AISIX gateway, a resources.yaml file or etcd supplies them. For a gateway connected to AISIX Cloud, the control plane supplies them.

AISIX accepts YAML, TOML, or JSON startup configuration files. Common files include:

  • config.yaml: the local startup configuration file loaded by AISIX.
  • config.example.yaml: a complete store-backed example for a gateway that runs without a control plane. You can copy or mount it as the loaded config.yaml.
  • config.managed.yaml: the gateway bootstrap configuration used when AISIX Cloud supplies resources at runtime.

The examples below use YAML because the packaged example configurations use YAML. TOML and JSON files can define the same startup fields. For the task-oriented setup flow, see Startup Configuration.

Configuration Models

Every AISIX gateway uses a startup configuration file. The management model determines where its dynamic resources come from and which settings the operator owns directly.

Gateway configurationResource sourceSelect withHow changes arrive
Open-source AISIX gateway using a resources fileDeclarative fileresources_fileLoaded at startup and reloaded on SIGHUP.
Open-source AISIX gateway using a configuration storeAn etcd cluster you manageetcdInitial synchronization followed by etcd watch events.
AISIX gateway connected to AISIX CloudAISIX Cloud control planemanaged.enabled: true and the generated connection settingsThe gateway receives resources projected by the control plane through its managed etcd connection.

The proxy, downstream, upstream, cache, rate-limit backend, and local observability settings remain gateway startup settings in every model. AISIX Cloud supplies dynamic resources such as models, keys, policies, and exporters; it does not replace these process-level settings.

An open-source AISIX gateway can bind its Admin API when admin.enabled is true and admin.admin_keys is configured. Its write operations are deprecated in favor of a resources file or direct configuration automation. A gateway connected to AISIX Cloud never binds the gateway Admin API; manage it through AISIX Cloud instead.

Common Startup Configuration

The following example shows an open-source AISIX gateway that uses etcd, with common startup settings. The gateway can instead load dynamic resources from a resources_file; see Resource Source.

config.yaml
etcd:
endpoints: # etcd endpoints used to store dynamic gateway resources.
- "http://127.0.0.1:2379"
prefix: "/aisix" # Key prefix used by AISIX in etcd.
# env_id: "ENVIRONMENT_ID" # Optional environment scope for gateway resources in etcd.
# user: "aisix" # Optional etcd username.
# password_env: "AISIX_ETCD_PASSWORD" # Environment variable containing the etcd password.
dial_timeout_ms: 5000 # Timeout for establishing an etcd connection.
request_timeout_ms: 5000 # Timeout for etcd requests.
# tls: # mTLS settings; all three certificate fields are required together.
# ca_cert_file: "/etc/aisix/mtls/ca.crt"
# client_cert_file: "/etc/aisix/mtls/client.crt"
# client_key_file: "/etc/aisix/mtls/client.key"
# domain_name: "etcd.example.com" # Optional SNI and certificate-name override.

proxy:
addr: "0.0.0.0:3000" # Address for caller-facing proxy APIs.
# request_body_limit_bytes: 0 # Maximum request body size. 0, the default, applies no cap:
# providers accept larger requests than any fixed gateway
# default (Anthropic takes 32 MB), so a gateway-side cap
# rejects requests the upstream would have served. Set a
# byte value to bound per-request memory; over-limit
# requests get a 413 in the caller's error envelope.
# Upgrade note: earlier releases defaulted to 10485760
# (10 MiB). If the gateway accepts requests directly from
# untrusted clients, set a value here or enforce a body
# limit at the load balancer or ingress in front of it.
# thread_per_core: true # Serve from independent workers, each with its own listener
# and upstream connection pool. Omitted, it is on for Linux
# and off elsewhere. Set false to serve from one shared
# runtime. Applied at startup; restart to change.
# See Deployment > Thread-per-Core Workers.
# workers: 4 # Number of proxy worker threads, in either serving mode.
# Omitted, it follows the parallelism available to the
# process, so a container CPU limit or a taskset affinity
# mask sizes it. Must be at least 1. Applied at startup.
# tls: # HTTPS certificate and key for the proxy listener.
# cert_file: "/etc/aisix/tls/proxy.crt"
# key_file: "/etc/aisix/tls/proxy.key"
# real_ip: # Caller IP resolution when AISIX runs behind trusted proxies.
# trusted_proxies:
# - "10.0.0.0/8"
# recursive: true
# header: "x-forwarded-for"
# url_rewrites: # Entry-level path rewriting before routing (first match wins).
# - name: per-server-mcp-compat # Optional label used in gateway logs.
# match: "^/mcp-servers/([^/]+)/mcp$" # Regex on the raw request path.
# rewrite: "/mcp/$1" # Replaces the matched portion; broken rules fail startup.
# # See Deployment > URL Rewriting for full semantics.

admin:
enabled: false

observability:
service_name: "aisix" # Service name used in telemetry.
log_level: "info" # Process log level.
metrics:
prometheus:
enabled: true # Whether to expose Prometheus metrics.
path: "/metrics" # Metrics endpoint path.
addr: "0.0.0.0:9090" # Dedicated metrics/status listener address.

# managed: # Enable when this gateway uses the AISIX Cloud control plane.
# enabled: true

# cache: # Redis connection used by cache policies that select Redis.
# redis:
# mode: "single"
# url: "redis://127.0.0.1:6379"
# # nodes: ["redis://10.0.0.1:6379"] # Cluster mode seed nodes.
# # sentinels: ["redis://10.0.0.1:26379"] # Sentinel mode nodes.
# # master_name: "mymaster" # Sentinel mode master group.
# # username: "default" # Cluster or Sentinel data-node ACL user.
# # password: "replace-me" # Cluster or Sentinel data-node ACL password.
# # database: 0 # Sentinel master database index.
# # For single mode, put credentials in the Redis URL.

ratelimit:
backend: "memory" # Rate-limit counter backend. Use redis for shared counters across replicas.
# redis:
# mode: "single"
# url: "redis://127.0.0.1:6379"
# # nodes: ["redis://10.0.0.1:6379"] # Cluster mode seed nodes.
# # sentinels: ["redis://10.0.0.1:26379"] # Sentinel mode nodes.
# # master_name: "mymaster" # Sentinel mode master group.
# # username: "default" # Cluster or Sentinel data-node ACL user.
# # password: "replace-me" # Cluster or Sentinel data-node ACL password.
# # database: 0 # Sentinel master database index.
# # For single mode, put credentials in the Redis URL.
# concurrency_ttl_secs: 300 # Redis backend only. Reclaims stale concurrency slots.

upstream: # Outbound calls to providers. Values shown are the defaults.
pool_idle_timeout_secs: 30 # Keep below the shortest idle timeout between the gateway and the provider.
# timeout_ms: 6000000 # Default request deadline (6000 s) when neither the model nor its group/router sets `timeout`. 0 disables the backstop.
# stream_timeout_ms: 0 # Default streaming chunk-gap deadline. 0 falls back to `timeout_ms`.
# retries: 2 # Attempts after a retryable failure, when neither the model nor its group/router sets `retries`. 0 disables retrying.
# connect_timeout_ms: 5000 # Budget for DNS, TCP, and TLS. 0 disables.
# tcp_keepalive_secs: 60 # Idle time before the first keepalive probe. 0 disables.
# tcp_keepalive_interval_secs: 30 # Interval between keepalive probes.
# tcp_keepalive_retries: 5 # Unacknowledged probes before the connection is dropped.
# pool_max_idle_per_host: 32 # Cap on idle connections per upstream host. Unset means
# unbounded. Applies per worker to worker-local pools.
# tls: # Which certificates the gateway trusts when it calls out.
# ca_file: "/etc/aisix/tls/private-ca.pem" # Trusted in addition to the platform's own authorities.
# client_cert_file: "/etc/aisix/tls/client.crt" # For an upstream that requires mutual TLS.
# client_key_file: "/etc/aisix/tls/client.key" # Required together with client_cert_file.
# verify: true # false accepts any certificate. Test environments only.

downstream: # Connection layer for inbound calls from clients. Values shown are the defaults.
idle_timeout_secs: 0 # Close a connection idle between requests. 0 never closes.
# sse_keepalive_interval_secs: 15 # Heartbeat interval on a silent streaming response. 0 disables.

# Optional deployment-wide override for AWS Bedrock guardrail traffic.
# bedrock_endpoint_url: "https://bedrock-runtime.us-east-1.amazonaws.com"

Changes to the startup configuration take effect after restarting the gateway.

Tune the Upstream Connection Layer

The upstream block controls how the gateway opens and reuses connections to providers. The defaults suit a gateway that reaches providers directly over the internet. Tune them when the gateway sits behind a load balancer, NAT gateway, corporate proxy, or service mesh.

pool_idle_timeout_secs is the setting to review first. The gateway reuses pooled connections, so this value must stay below the shortest idle timeout anywhere on the path to the provider. If an intermediate hop closes an idle connection sooner than the gateway expires it, the pool eventually hands out a connection the far end has already closed, and the request fails with a transport error against an otherwise healthy provider.

TCP keepalive keeps the connection visible to those same hops while a slow model produces its first token. A NAT or load-balancer idle timer can otherwise reap a connection that is legitimately waiting on a long-running request.

In thread-per-core serving, the default on Linux, normal proxy dispatches use worker-local connection pools, and pool_max_idle_per_host applies per worker. The idle connections a process holds toward one host can therefore reach proxy.workers times this cap. Request paths with dedicated clients, such as Provider Keys with custom TLS settings, keep separate process-wide pools and are not included in that multiplication. See Thread-per-Core Workers for the serving modes and their sizing consequences.

timeout_ms and stream_timeout_ms are deployment-wide defaults for the per-model timeout and stream_timeout fields. A request resolves its deadline from the first level that sets one: the target model, then the routing model or semantic router it was addressed through, then these defaults. The default of 6000 seconds is a backstop, not a responsiveness target — it exists so that an upstream that accepted the connection and then goes silent forever cannot hold a request open indefinitely, while never cutting a legitimate long request (deep-reasoning calls can run past ten minutes; set a per-model timeout to enforce anything tighter). A model opts out of the backstop with timeout: 0; setting timeout_ms: 0 removes the default deployment-wide.

Every duration accepts 0 to switch that individual setting off.

upstream.tls decides which certificates the gateway trusts on those connections. It covers every outbound path on a request: model endpoints, guardrail services, MCP and A2A upstreams, OIDC discovery, the Realtime WebSocket, Amazon Bedrock, and log exports.

Set ca_file when a private or enterprise certificate authority signed the certificate an upstream presents. Those certificates are trusted in addition to the platform's, so public providers stay reachable. See TLS and mTLS for per-endpoint trust, mutual TLS, and the settings for a Redis backend.

Tune the Downstream Connection Layer

The downstream block is the mirror of upstream: it controls the connections the gateway accepts from clients, or from a gateway placed in front of it.

idle_timeout_secs closes a connection that sits idle between requests — the response has been fully written and no next request has started. A request in flight is never interrupted, however long the model takes, and neither is a streaming response. The same deadline also bounds how long a freshly accepted connection may take to send its first request line and headers, so keep it comfortably above the round-trip time of the slowest client you serve.

It defaults to 0, which never closes an idle connection and leaves that decision to the peer. That default is deliberate. Whatever sits in front of the gateway pools its own connections, and the node that closes first is the one that hands its peer a connection the peer still considers usable — the same failure pool_idle_timeout_secs avoids in the outbound direction. If you set idle_timeout_secs, keep it above the pool idle timeout of the node in front, and treat reclaiming idle connections as the reason to set it.

sse_keepalive_interval_secs emits an SSE comment on a streaming response while the model has produced nothing. Without it, a model that is slow to its first token looks like an abandoned connection to a proxy between the client and the gateway. The comment is ignored by every conforming SSE client, and applies to every streaming endpoint.

Both settings apply to the proxy listener. idle_timeout_secs applies to HTTP/1.1 connections.

How the Timeouts Relate

Each setting below bounds a different phase of a request. They are not interchangeable.

SettingWhereWhat it bounds
upstream.connect_timeout_msStartup configDNS, TCP, and TLS to the provider, before a request is sent.
upstream.timeout_msStartup configDefault for timeout when neither the model nor the routing model / semantic router it was addressed through sets one.
upstream.stream_timeout_msStartup configDefault for stream_timeout; 0 falls back to upstream.timeout_ms.
upstream.pool_idle_timeout_secsStartup configHow long an unused connection to the provider stays in the pool, after a response completes.
downstream.idle_timeout_secsStartup configHow long an accepted client connection stays open with no request on it.
timeoutModelThe whole upstream call, from send to the last byte. Resolves model → routing model / semantic router → upstream.timeout_ms; 0 on the model disables it.
stream_timeoutModelThe gap between two chunks of a streaming response — the wait for the first chunk and every gap after it, reset on each chunk. Not a cap on total stream duration. 0 or absent falls back to the group/router stream_timeout, then to timeout, then to the deployment defaults.

The two pool settings manage connection reuse; the model settings bound a request that is in flight. TCP keepalive is a network-layer liveness probe and bounds nothing at the request layer.

Readers coming from a general-purpose proxy usually look for a connect / send (write) / read timeout trio. The mapping: connect_timeout_ms is the connect timeout; stream_timeout is the read timeout for streaming responses (same inter-chunk semantics), while non-streaming responses get the stricter end-to-end timeout instead; there is no separate send timeout because a stalled request upload is already bounded by the same end-to-end or streaming budget, and unacknowledged sends are cut earlier still at the TCP layer. A general-purpose proxy needs the trio because it has no per-request deadline concept — the gateway does, so the trio is covered with fewer knobs.

For a chain of gateways, the rule at every hop is the same: a node's client-side idle timeout must stay below the next node's server-side idle timeout, with margin. A violation of that ordering is what produces intermittent transport errors against an otherwise healthy path.

Resource Source

Configure exactly one resource source. The selection affects how resources are loaded, but does not change the caller-facing Proxy API.

Resources File

An open-source AISIX gateway reads its dynamic resources from exactly one source. Set resources_file to load them from a declarative resources file:

config.yaml
resources_file: /etc/aisix/resources.yaml

resources_file and the etcd section are mutually exclusive — configuring both fails at startup. resources_file also cannot be combined with managed.enabled: true, because a gateway connected to AISIX Cloud receives resources from the control plane.

With resources_file set, the gateway loads the file at startup and reloads it on SIGHUP. See the Resources File Reference for every resource kind and field. Use the Open-Source AISIX Gateway Quickstart for the workflow and the CLI Reference for validation or etcd export. Configuration Status shows what a running gateway loaded.

etcd Configuration Store

Set etcd.endpoints when configuration automation writes resources directly to etcd:

config.yaml
etcd:
endpoints:
- "https://etcd.example.com:2379"
prefix: "/aisix"
dial_timeout_ms: 5000
request_timeout_ms: 5000
tls:
ca_cert_file: "/etc/aisix/mtls/ca.crt"
client_cert_file: "/etc/aisix/mtls/client.crt"
client_key_file: "/etc/aisix/mtls/client.key"
domain_name: "etcd.example.com"
FieldRequiredDescription
etcd.endpointsYesOne or more etcd endpoints. An open-source AISIX gateway requires this field when resources_file is not set.
etcd.prefixNoKey prefix containing AISIX resources. Defaults to /aisix; gateways sharing resources must use the same prefix.
etcd.env_idNoEnvironment scope included in the key layout when the writer uses environment-scoped keys.
etcd.userNoetcd username.
etcd.password_envNoName of the environment variable that contains the etcd password.
etcd.dial_timeout_msNoTimeout for establishing the connection. Defaults to 5000.
etcd.request_timeout_msNoTimeout for etcd requests. Defaults to 5000.
etcd.tlsNoClient CA, certificate, key, and optional server-name override for an mTLS connection. The three certificate-file fields are required together.

Use aisix export when migrating an existing store to a resources file.

AISIX Cloud

Set managed.enabled to true when the gateway receives resources from AISIX Cloud. Use the generated gateway installation snippet rather than composing the bootstrap values manually; it supplies the correct control-plane endpoints and certificate material for the selected environment.

config.yaml
managed:
enabled: true
cp_base_url: "https://aisix.example.com"
cp_etcd_endpoint: "aisix.example.com:443"
mtls_dir: "/var/lib/aisix/mtls"
dp_id_file: "/var/lib/aisix/dp_id"
snapshot_cache_path: "/var/lib/aisix/config_cache.json"
heartbeat_interval_secs: 15

The connection certificate, private key, and CA can be supplied as one complete inline triplet (cp_cert_pem, cp_key_pem, and cp_ca_pem) or one complete file-path triplet (cp_cert_file, cp_key_file, and cp_ca_file). Do not mix inline and file forms within the same bundle. Keep credential material in environment variables or mounted secret files rather than committing it to the startup configuration.

FieldRequiredDescription
managed.enabledYesEnables the AISIX Cloud connection and disables the gateway Admin API listener.
managed.cp_base_urlYesAISIX Cloud control-plane origin used for heartbeat, telemetry, certificate rotation, and budget checks.
managed.cp_etcd_endpointNoExplicit managed etcd endpoint as host:port. When omitted, AISIX derives it from cp_base_url.
managed.cp_ca_cert_fileNoAdditional CA bundle for the control-plane HTTP and etcd TLS connections, commonly needed with a private CA for an On-Premises control plane.
managed.mtls_dirNoDirectory where AISIX persists the materialized mTLS bundle. Defaults to /var/lib/aisix/mtls.
managed.dp_id_fileNoFile where AISIX persists the gateway ID. Defaults to /var/lib/aisix/dp_id.
managed.snapshot_cache_pathNoLast-known configuration cache used across control-plane outages and restarts. Defaults to /var/lib/aisix/config_cache.json when connected to AISIX Cloud; set an empty string to disable it.
managed.heartbeat_interval_secsNoHeartbeat interval in seconds. Defaults to 15 and is clamped to the range 5300.

The managed connection appears as source.type: "etcd" in Configuration Status, because the gateway consumes the control plane's projected resources through its managed store connection. For the certificate issuance and installation workflow, see Connect an AISIX Gateway. For environment-variable forms of these fields, see Environment Variables.

Select a Configuration File

When running the binary directly, provide a config path with --config or AISIX_CONFIG.

aisix --config config.yaml

When running the official container image, mount the config file at /etc/aisix/config.yaml, or set AISIX_CONFIG_PATH to another path inside the container.

The following example mounts a production config file and asks the entrypoint to load it:

docker run \
-v "$(pwd)/config.prod.yaml:/etc/aisix/config.prod.yaml:ro" \
-e AISIX_CONFIG_PATH="/etc/aisix/config.prod.yaml" \
ghcr.io/api7/aisix:latest

If AISIX_CONFIG_PATH is unset, the entrypoint uses /etc/aisix/config.yaml.

Loading Order

AISIX loads startup configuration in the following order:

  1. Built-in default values.
  2. File contents from the path selected by --config or AISIX_CONFIG.
  3. Environment-variable overrides with the AISIX_ prefix.

Environment-variable overrides apply only to startup configuration fields. For override syntax and AISIX Cloud connection variables, see Environment Variables.