Configuration¶
AIRelays resolves settings in this order:
- CLI flags
AIRELAYS_*environment variables- legacy
OPENAI_ENDPOINT_*migration variables where supported ~/.config/airelays/config.toml- built-in defaults
Traffic-log retention is live configuration: a saved policy in the selected
log directory takes precedence over its [logging] defaults. See
Traffic log retention below.
Traffic log retention¶
Traffic logs rotate hourly and at a size limit. Cleanup runs on startup, every 60 seconds while the relay is running (including when idle), on rotation, and when applying a policy. Both age and size limits apply; whichever requires removing a file first wins. Defaults are deliberately bounded on upgrades too.
| Parameter | Default | Meaning |
|---|---|---|
retention_days |
7 |
Maximum age since a file's last write; 30 means 30 days, 0 disables only the age limit. Range: 0–36500. |
max_total_mb |
1024 |
Total managed traffic-log budget in MiB (1 GiB by default). Range: 1–1048576. |
max_file_mb |
50 |
Rotate before the next record would exceed this size in MiB. Range: 1–10240; must not exceed the total budget. |
Retention is an upper limit, not a promise of seven days of history: under load,
the disk budget removes older files sooner. Cleanup reserves room for the active
file, so usage can be below the configured budget by up to a chunk plus the last
whole file removed. Files are deleted whole, oldest modification time first.
The budget counts file contents; filesystem allocation and metadata overhead
are not included in usage_bytes.
From the CLI (also works with the relay stopped):
airelays logs # policy and current usage; no cleanup
airelays logs --retention-days 30 # keep up to a month, save and apply
airelays logs --retention-days 7 --max-total-mb 1024 --max-file-mb 50
airelays logs --json # machine-readable policy, usage, errors
airelays logs --config /path/to/config.toml --retention-days 14
The selected --config, --data-dir, and --logs-dir determine which log
directory is managed. Use the same directory as the running relay.
In the cross-platform tray app, open Settings → Traffic log retention. Choose 1 week, 1 month (30 days), or a custom duration and disk limit, then Apply log retention. The relay must be running for the tray controls; the CLI can configure it offline. This section applies independently of the other settings' Save & Restart workflow. It shows disk usage and cleanup errors.
The HTTP API exposes the same policy. API/tray updates apply immediately. Other relay processes sharing the directory pick up the saved policy on their next write or within 60 seconds while idle.
Policy changes are saved atomically to <logs_dir>/.retention.json. That file
overrides the three TOML retention defaults and survives restarts, CLI sessions,
and the tray's regeneration of config.toml. Change it through the API or CLI;
editing the TOML defaults after saving a policy does not override that policy.
The stream_lines option remains a separate startup setting.
Cleanup includes existing YYYY/MM/DD-HH.log files and new size-rotated
YYYY/MM/DD-HH.<uuid>.log files. It does not manage console/stdout logs, uploads,
conversations, unrelated files, symlinks, or hard links. Use an app-owned local
log directory; every writer sharing it must run a retention-aware AIRelays
version. External writers or an older relay can defeat the disk limit.
A record larger than max_file_mb becomes an explicit log_record_omitted
JSON record with its request ID, phase, byte count and SHA-256; the payload is
omitted from the log without altering the actual request or response. Cleanup
and I/O failures are reported on stderr and through last_error; traffic
logging pauses on cleanup failure and retries, rather than growing past the
budget or failing client requests. Deletion is permanent: archive any logs you
need before first starting the upgraded relay or reducing a policy.
Default Paths¶
- config:
~/.config/airelays/config.toml - data dir:
~/.airelays - logs dir:
~/.airelays/logs - auth fallback file:
~/.airelays/auth.json - relay token file:
~/.airelays/relay-token
Earlier singular AIRelay paths remain compatible for local upgrades.
Sample Config¶
[server]
host = "127.0.0.1"
port = 8080
[paths]
data_dir = "~/.airelays"
logs_dir = "~/.airelays/logs"
[auth]
storage = "auto"
browser_open = false
login_timeout_seconds = 900
[upstream]
base_url = "https://chatgpt.com/backend-api/codex"
issuer_base_url = "https://auth.openai.com"
client_id = "app_EMoamEEZ73f0CkXaXp7hrann"
client_version = "auto"
request_timeout_seconds = 120.0
[security]
require_bearer_auth = true
bearer_token_file = "~/.airelays/relay-token"
auto_generate_bearer_token = false
rate_limit_per_minute = 120
rate_limit_burst = 40
concurrent_requests_per_ip = 8
failed_auth_window_seconds = 300
failed_auth_max_attempts = 8
failed_auth_block_seconds = 900
trust_x_forwarded_for = false
[uploads]
max_upload_bytes = 33554432
max_total_upload_bytes = 268435456
[logging]
# Opt-in: log every raw upstream SSE line. Hundreds of records per
# streamed response (~50x log growth under load); summary records
# (request, usage, response, errors) are always logged regardless.
stream_lines = false
retention_days = 7
max_total_mb = 1024
max_file_mb = 50
[providers.openai]
enabled = true
models_cache_ttl_seconds = 300.0
# Multi-account routing: "balanced" (default) routes to the account with
# the most remaining weekly quota so consumption equalizes as a
# percentage of each plan's capacity; "round_robin" sends equal request
# counts; "ordered" drains the first account first.
balance = "balanced"
# Extra model ids to advertise in /v1/models beyond the upstream catalog,
# for operator-confirmed models omitted from automatic discovery.
extra_models = []
# Fallback bench duration (seconds) when a limited account's reset time is
# unknown; upstream-reported reset times are used when available.
account_cooldown_seconds = 300
# Automatic retry for failed upstream LLM calls. Each retry re-runs the
# full account-pool failover pass, then waits the next backoff delay.
# 0 disables. A schedule shorter than the attempt count repeats its last
# delay. Retries only happen before any response byte reached the client
# (non-streaming requests, and the pre-header phase of streaming ones);
# retries that cannot succeed (a quota window that resets far beyond the
# backoff budget) are skipped so the honest 429 is not delayed.
retry_attempts = 3
retry_backoff_seconds = [5, 20, 60]
[providers.claude]
enabled = false
bin = "claude"
timeout_seconds = 600.0
max_concurrent_requests = 2
strip_api_key_env = true
models = ["claude:sonnet", "claude:opus", "claude:haiku", "claude:fable"]
Important Environment Variables¶
AIRELAYS_CONFIGAIRELAYS_HOSTAIRELAYS_PORTAIRELAYS_DATA_DIRAIRELAYS_LOGS_DIRAIRELAYS_AUTH_STORAGEAIRELAYS_BROWSER_OPENAIRELAYS_LOGIN_TIMEOUT_SECONDSAIRELAYS_UPSTREAM_BASE_URLAIRELAYS_ISSUER_BASE_URLAIRELAYS_CLIENT_IDAIRELAYS_CLIENT_VERSIONAIRELAYS_REQUEST_TIMEOUT_SECONDSAIRELAYS_REQUIRE_BEARER_AUTHAIRELAYS_BEARER_TOKENAIRELAYS_BEARER_TOKEN_FILEAIRELAYS_LOG_STREAM_LINESAIRELAYS_ENABLE_OPENAIAIRELAYS_OPENAI_MODELS_CACHE_TTL_SECONDSAIRELAYS_OPENAI_BALANCE(balanceddefault,round_robin, orordered)AIRELAYS_OPENAI_EXTRA_MODELS(comma-separated ids advertised beyond the upstream catalog)AIRELAYS_OPENAI_ACCOUNT_COOLDOWN_SECONDSAIRELAYS_OPENAI_RETRY_ATTEMPTS(automatic retries for failed upstream calls;3default,0disables)AIRELAYS_OPENAI_RETRY_BACKOFF_SECONDS(comma-separated wait before each retry;5,20,60default)AIRELAYS_ENABLE_CLAUDE(legacyAIRELAYS_ENABLE_CLAUDE_EXPERIMENTALis still honored)AIRELAYS_CLAUDE_BINAIRELAYS_CLAUDE_TIMEOUT_SECONDSAIRELAYS_CLAUDE_MAX_CONCURRENT_REQUESTSAIRELAYS_CLAUDE_STRIP_API_KEY_ENVAIRELAYS_CLAUDE_MODELS
Relay Token Inputs¶
AIRelays resolves the relay token in this order:
AIRELAYS_BEARER_TOKEN- the configured
bearer_token_file
Override examples:
AIRELAYS_BEARER_TOKEN='YOUR_AIRELAYS_TOKEN' airelays serve --port 8080
airelays serve --bearer-token-file /path/to/relay-token --port 8080
Provider Notes¶
[upstream] client_version = "auto" discovers the installed Codex CLI's
version for model-catalog requests, with a tested minimum of 0.153.4 for
standalone installations. The local version probe is bounded to three
seconds and cached for five minutes. Updating Codex allows discovery to
follow newer version-gated catalogs without adding model names to AIRelays.
The former shipped value 0.124.0 is treated as auto, including existing
desktop configuration files. Other explicit version pins are honored and
can select an older catalog.
OpenAI runtime:
- enabled by default
- uses AIRelays-owned auth storage
airelays loginmanages its subscription session- caches successful upstream model-list responses for
models_cache_ttl_secondsseconds by default - the model-list cache is process-local, in-memory, and disabled when
models_cache_ttl_seconds = 0 - cache state is visible under
providers.openai.models_cacheinGET /v1/relay/status extra_modelsdefaults to an empty list. Existing configured entries continue to extend a successful catalog and are deduplicated against it.
AIRELAYS_MODELS_CACHE_TTL_SECONDS remains accepted as a shorter alias for
AIRELAYS_OPENAI_MODELS_CACHE_TTL_SECONDS.
Claude runtime:
- discovers models and alias resolutions from the installed CLI, without
generating text; its model catalog uses
models_cache_ttl_secondstoo - configured
modelsextend discovery and remain available as fallback when CLI discovery is unavailable -
use
GET /v1/models?refresh=trueor the desktop Models Refresh button to reload provider catalogs immediately -
enabled by default; set
[providers.claude].enabled = falseorAIRELAYS_ENABLE_CLAUDE=falseto opt out (requests still require the localclaudeCLI to be installed and signed in) - uses the local
claudeCLI - browser login is handled by
claude auth login --claudeai - headless login is handled by
claude setup-tokenplusCLAUDE_CODE_OAUTH_TOKEN - follows the relay's protected or open local auth mode
- requires loopback binding