Appearance
Environment variables
Every runtime knob merido reads, generated directly from the Config struct so this table is never out of date. Each is set with its MERIDO_-prefixed environment variable. For how configuration is layered and which knobs matter most, see Configuration.
| Variable | Default | Description |
|---|---|---|
MERIDO_PROFILE | local | — |
MERIDO_HOST | 127.0.0.1 | Address to bind the HTTP server to. |
MERIDO_PORT | 8788 | — |
MERIDO_DATA_DIR | (computed) | Local data directory (SQLite, logs) for the local profile. |
MERIDO_DATABASE_URL | unset | Explicit database URL. When unset, a SQLite file under data_dir is used. Also accepts a bare DATABASE_URL (no MERIDO_ prefix) as a fallback, the convention Supabase/Fly/Heroku Postgres inject — see [Config::load]. |
MERIDO_REDIS_URL | unset | Redis URL for shared cluster state (HA). Accepts bare REDIS_URL as a fallback. Stored but not yet consumed until the HA data plane lands. |
MERIDO_MULTI_TENANT | false | Enable self-serve multi-tenancy: email+password signup, per-user org isolation, and admin tier. Off by default — single-user self-host keeps its current password-free local behavior. |
MERIDO_ADMIN_EMAILS | empty | Emails that become system admins on signup (comma-separated in env). Matched case-insensitively against the signup email. |
MERIDO_GOOGLE_CLIENT_ID | unset | Google OAuth (OIDC) client id for "Sign in with Google". When set together with [Config::google_client_secret], Google-only login activates: password/signup endpoints are disabled and the dashboard renders only the Google button. One global OAuth app serves the whole deployment. Google is a standard OIDC provider (issuer = https://accounts.google.com) driven through the existing relying-party flow. When unset, login falls back to the existing password behaviour (fail-safe: an empty Google config never bricks login). |
MERIDO_GOOGLE_CLIENT_SECRET | unset | Google OAuth client secret (confidential client). REQUIRED alongside [Config::google_client_id] — Google's token endpoint rejects a public client — so Google-only mode only activates when BOTH are present. |
MERIDO_GOOGLE_ALLOWED_DOMAINS | empty | Optional allow-list of email domains permitted to sign in with Google. When non-empty, ONLY addresses whose domain is listed may log in (a leading @ on an entry is tolerated); empty = any Google account. Comma-separated in MERIDO_GOOGLE_ALLOWED_DOMAINS, matched case-insensitively on the part after the last @. |
MERIDO_GOOGLE_ISSUER | unset | Override the Google OIDC issuer (default https://accounts.google.com). Rarely set in production; exists as a test seam and an escape hatch for a Google-compatible issuer / proxy. The discovery document, JWKS, and id-token iss are all taken relative to this value. |
MERIDO_RESEND_API_KEY | unset | Resend HTTP API key for transactional email (verification / password reset). When unset, emails are logged instead of sent (dev/local). |
MERIDO_EMAIL_FROM | unset | Verified Resend sender address, e.g. merido <[email protected]>. |
MERIDO_PUBLIC_URL | unset | Public base URL used to build verification / reset links in emails. |
MERIDO_DASHBOARD_DIR | unset | Directory of built dashboard assets to serve. When unset, falls back to dashboard/dist if present. |
MERIDO_DIST_DIR | unset | Directory of prebuilt CLI release artifacts (merido-<triple>.tar.gz / .zip and latest.json) served at /dl/* for self-hosted install and merido update. When unset (and dist_base_url is also unset), /dl/* returns 404. |
MERIDO_DIST_BASE_URL | unset | Base URL of an object store / CDN holding the CLI release artifacts. When set, /dl/* requests 302-redirect here (taking precedence over dist_dir) instead of the server reading bytes itself, e.g. https://dl.merido.dev. |
MERIDO_MASTER_KEY_PATH | unset | Path to the 32-byte master key used for encryption-at-rest. When unset, a key is created under data_dir/master.key (or taken from MERIDO_MASTER_KEY). |
MERIDO_DASHBOARD_PASSWORD_HASH | unset | Argon2 PHC hash of the dashboard password. When unset, the dashboard/admin API is open (local single-user default); when set, login is required. |
MERIDO_JWT_SECRET | unset | Secret used to sign dashboard session JWTs. When unset, one is derived from the master key at startup. |
MERIDO_REQUIRE_API_KEY | false | Require a valid client API key on every /v1/* proxy request. Off by default (local single-user convenience: anonymous localhost callers are allowed); MUST be enabled on any deployment reachable from the public internet, otherwise unauthenticated callers can burn upstream provider credits. |
MERIDO_VIRTUAL_MODELS_ONLY | false | Strict gateway mode: require every /v1/* chat request to target a configured Virtual Model (or a MERIDO_ROUTES route, or the built-in auto). When on, a bare provider/model id is rejected with a 400 and GET /v1/models advertises only the Virtual Models — raw upstream models are never exposed or directly callable, so all traffic flows through Virtual Models. Off by default (direct provider/model passthrough is allowed, the local-first convenience). |
MERIDO_FREE_POOL_VM | merido/free | Name of the system-level virtual model that serves the free token pool. A request for this model from any tenant that has no org VM of the same name falls through to the operator's system pool. |
MERIDO_FREE_POOL_GLOBAL_DAILY_TOKEN_CAP | unset | Coarse global cap on tokens served by the free pool per UTC day. None disables the cap (Phase 1 cost brake; per-user quotas arrive in Phase 2). |
MERIDO_FREE_TIER_TOKEN_LIMIT_HOUR | unset | Per-user (per-org) free-pool token limit per rolling hour. None disables the hour window. Recommended starting value when enabling the free tier: 200000. |
MERIDO_FREE_TIER_TOKEN_LIMIT_DAY | unset | Per-user free-pool token limit per rolling day. None disables. Recommended: 1000000. |
MERIDO_FREE_TIER_TOKEN_LIMIT_WEEK | unset | Per-user free-pool token limit per rolling 7-day window. None disables. Recommended: 5000000. |
MERIDO_FREE_TIER_REQUIRES_VERIFIED_EMAIL | true | Require a verified email before a user's requests are served by the free pool (merido/free). Applies only in multi-tenant mode. Default true. |
MERIDO_RATE_LIMIT_RPM | unset | Per-client-key sustained rate limit, in requests per minute. None disables rate limiting. |
MERIDO_RATE_LIMIT_BURST | unset | Per-client-key burst allowance (max tokens). Defaults to rate_limit_rpm when unset and a limit is configured. |
MERIDO_ACCOUNT_MAX_INFLIGHT | unset | Maximum number of in-flight (simultaneously executing) requests allowed per upstream account. Excess requests are not queued: the router falls back to the next account, and returns HTTP 429 if every candidate is at capacity. Unlike rate_limit_rpm (a per-minute rate), this bounds concurrency, matching a slow upstream's real parallelism so admitted requests are served promptly instead of piling into a deep queue. None disables the in-flight limiter (no behavior change). Enforced cluster-wide via Redis when configured; in-memory otherwise. |
MERIDO_COOLDOWN_RETRY_MAX_WAIT_MS | unset | Longest upstream retry-after, in milliseconds, that the dispatcher will WAIT out in-request and retry on the SAME account, instead of immediately failing over to the next account. When an upstream returns a short, precise rate-limit retry-after (≤ this cap), waiting preserves the warm prompt-cache and avoids spending a second account's quota; a longer/absent retry-after falls over as before. Bounded to one wait per account per request. None or 0 disables it (no behavior change) — the default. |
MERIDO_UPSTREAM_CONNECT_TIMEOUT_MS | 10000 | Data-plane upstream HTTP connect timeout, in milliseconds — the cap on establishing the TCP+TLS connection to an upstream provider. It does NOT bound the total request or a streaming response (a total timeout would truncate long SSE streams); it only fails a connection that never establishes, so a half-open/black-holed provider can't hang request tasks (and leak in-flight permits) gateway-wide. 0 disables. Default 10000. |
MERIDO_UPSTREAM_IDLE_TIMEOUT_MS | 120000 | Data-plane upstream idle/read timeout, in milliseconds — the cap on time between bytes received from an upstream. SSE-safe: any streamed chunk or keepalive resets it, so it reaps only a stalled connection, not a slow-but-live stream. 0 disables. Default 120000. |
MERIDO_UPSTREAM_POOL_MAX_IDLE_PER_HOST | 32 | Maximum idle keep-alive connections retained per upstream host in the data-plane connection pool. Bounds socket accumulation during a provider incident. Default 32. |
MERIDO_UPSTREAM_TCP_KEEPALIVE_SECS | 60 | TCP keepalive probe interval, in seconds, for data-plane upstream sockets, so a silently-dropped connection is detected instead of hanging. 0 disables. Default 60. |
MERIDO_COST_CENTER_MAX_INFLIGHT | unset | Maximum concurrent in-flight upstream requests attributed to a single cost_center, enforced ON TOP OF account_max_inflight. In a multi-tenant reselling deployment (many keys sharing one upstream account pool) this is the per-tenant fair-share lever: one busy cost_center can no longer monopolize the shared accounts and starve the others. None (default) disables the per-cost_center reservation (no behavior change). Enforced cluster-wide via Redis when configured. |
MERIDO_COST_CENTER_HEADER_TRUSTED | true | Whether the per-request x-merido-cost-center header may OVERRIDE a key's stored cost_center (#8). Default true preserves the header-wins precedence. Set false in a multi-tenant reselling deployment — where many keys share one org and the cost_center tag is the only intra-org spend/usage/quota discriminator — so a client cannot spoof another tenant's cost_center; the key's stored tag then always wins. |
MERIDO_METRICS_REQUIRE_OPERATOR | false | Require an OPERATOR credential (dashboard session or a management token) to scrape /metrics, rather than accepting any valid API key (#12). Default false keeps the existing behavior (any authenticated caller when the surface is hardened). Set true in a multi-tenant reselling deployment so a tenant's data-plane key cannot read the process-global platform aggregates (spend/volume/model mix) exposed on /metrics. |
MERIDO_LIMITER_REDIS_FALLBACK | fail-open | How the admission limiters (per-key rate limit and per-account / per-cost_center concurrency caps) behave when Redis is configured but unreachable at request time: fail-open (admit the request — today's behavior, and the default), local (fall back to the bounded in-memory limiters), or fail-closed (reject). local and fail-closed stop a Redis blip from removing every tenant's rate/concurrency cap at once and stampeding the shared upstream pool. |
MERIDO_REASONING_REPLAY | false | Replay assistant reasoning/thinking blocks that a client stripped. Thinking models (DeepSeek/Kimi/Qwen-thinking) reject a follow-up whose prior assistant turn omits the reasoning that produced its tool calls; when on, merido caches each turn's reasoning by tool-call id and re-injects it on later turns. Off by default (zero behavior change). Enabling it routes requests through canonical-IR normalization so the re-injection can run even on same-format passthrough. |
MERIDO_STREAM_HEARTBEAT_MS | 15000 | Interval, in milliseconds, between SSE heartbeat comment frames (: ping) on data-plane streaming responses while the upstream is quiet. Heartbeats are spec-legal SSE comments ignored by every client parser, emitted only BETWEEN complete frames, so a slow time-to-first-token or a long tool-building pause no longer lets idle proxies/load-balancers sever the stream. 0 disables. Default 15000. |
MERIDO_MAX_BODY_BYTES | (computed) | Maximum accepted request-body size, in bytes, on the data-plane JSON endpoints (/v1/chat/completions, /v1/messages, /v1/responses, /v1/embeddings). Bodies above the cap are rejected with an OpenAI-shaped 413 error envelope instead of the framework's plain-text default. Inline base64 images make multi-megabyte chat bodies legitimate, so this defaults to 20 MiB (the audio/ image upload routes keep their own larger cap). |
MERIDO_PAYLOAD_RULES_PATH | unset | Path to a JSON file of declarative payload rules applied to every outbound upstream request body: per provider / model glob / wire format, set a default for an absent field, force-override a field, or remove fields (dotted paths supported). Externalizes provider quirks — clamp/drop/inject — so operators patch them at runtime without a rebuild; the file is re-read when its mtime changes. None (default) disables the engine. |
MERIDO_STRIP_UNSUPPORTED_FIELDS | true | Recover from upstream 400s that NAME an unsupported request field (e.g. "Unknown parameter: 'logit_bias'"): strip exactly that field from the outbound body and retry the same account once per field (bounded), instead of failing the request. Covers the long tail of per-provider parameter support without hardcoding every matrix. Default true; set false to return the provider's 400 verbatim on the first occurrence. |
MERIDO_ALERT_WEBHOOK_URL | unset | Outbound alert webhook: POST a message on notable operational events (a request completing with a server error, or a budget/rate-limit rejection). None (the default) disables it. A single-URL incoming webhook — Slack/Discord/generic. |
MERIDO_ALERT_WEBHOOK_FORMAT | generic | Payload shape for alert_webhook_url: slack ({"text":…}), discord ({"content":…}), or generic (a structured JSON event). Default generic. |
MERIDO_DEDUP_TTL_MS | unset | Request-dedup cache TTL in milliseconds. When set, identical non-streaming requests within the window return a cached response. None disables dedup. |
MERIDO_SEMANTIC_CACHE_TTL_MS | unset | Semantic-cache TTL in milliseconds. The fuzzy sibling of dedup: a request whose prompt embedding is within semantic_cache_threshold of a recent one reuses that response. Requires semantic_cache_embed_model; None disables. |
MERIDO_SEMANTIC_CACHE_THRESHOLD | unset | Minimum cosine similarity for a semantic-cache hit (default 0.95 when the cache is enabled but this is unset). Higher is stricter / fewer false hits. |
MERIDO_SEMANTIC_CACHE_EMBED_MODEL | unset | The provider/model used to embed prompts for the semantic cache, e.g. openai/text-embedding-3-small. Required to enable the semantic cache. Must be an external provider — a merido/… model would re-enter the proxy and is rejected (the cache stays off). Cache entries are scoped per target (provider, model, wire-format, client key, request params), so a hit is only ever another request to the same model with the same parameters whose prompt embeds within the threshold; the embedding model only needs to be stable, not shared across chat providers. |
MERIDO_SEMANTIC_CACHE_ENABLED | false | Master switch for the productized semantic cache (Wave 22.3). Off by default because a fuzzy cache can return a semantically-different answer (a "false hit"), which is correctness-sensitive — an operator must opt in explicitly. Independent of the legacy semantic_cache_ttl_ms/embed_model plumbing: this flag (plus the per-route map) governs whether a lookup is consulted and at what similarity bar. (MERIDO_SEMANTIC_CACHE_ENABLED.) |
MERIDO_SEMANTIC_CACHE_REVALIDATE_RATE | 0.05 | Fraction of semantic-cache hits to divert into sampled re-validation, in [0.0, 1.0]. On a sampled hit the server treats the lookup as a MISS, lets the real request proceed, and compares the fresh response against the value the cache would have served — measuring how often a "hit" was actually correct (precision). Default 0.05 (5%) bounds the false-hit blast radius while keeping the re-validation tax small. 0.0 disables the guard. (MERIDO_SEMANTIC_CACHE_REVALIDATE_RATE.) |
MERIDO_SEMANTIC_CACHE_PRECISION_FLOOR | 0.90 | Measured-precision floor in [0.0, 1.0]. When a route's sampled precision drops below this, the guard self-protects by raising that route's effective threshold (and, at the limit, disabling the route's cache). Default 0.90: fewer than 1-in-10 sampled hits may be false before the guard clamps down. (MERIDO_SEMANTIC_CACHE_PRECISION_FLOOR.) |
MERIDO_ROUTES | empty | Virtual-model routes: named, cost-ordered candidate model lists with model-level fallback. A client requesting a route's name is served by the best capable target. Populated from the MERIDO_ROUTES env var (a JSON array of route objects) by [Config::load]; empty by default. |
MERIDO_HEALTH_CHECK_INTERVAL_SECS | unset | Active health-check interval in seconds. When set, a background prober calls each connection's /models endpoint on this cadence and feeds the result to the circuit breaker, so a recovered provider is detected proactively rather than on the next failed request. None (default) disables active probing. |
MERIDO_MONTHLY_BUDGET_USD | unset | Monthly spend budget in USD. When set, the advisor reports budget status (a linear end-of-month projection and any overage) for the current calendar month. None (default) disables budget tracking. |
MERIDO_SESSION_BUDGET_USD | unset | Per-session spend cap in USD: cumulative cost allowed per agent session (session_id) before requests are blocked (402). None disables the cap. Overridable per API key via api_keys.session_budget_usd. |
MERIDO_BUDGET_FAIL_CLOSED | false | When true, requests that cannot have their budgets verified (a storage error while loading budgets) are rejected with 503 instead of being admitted (fail-open); counter reads on the reserve path are in-memory and infallible, so only budget-load errors can trigger this. Default: false. (MERIDO_BUDGET_FAIL_CLOSED.) |
MERIDO_DEFAULT_KEY_BUDGET_USD | unset | When set (> 0), every newly created API key automatically gets a key-scoped USD budget with this hard limit. Default: unset (new keys are unlimited). (MERIDO_DEFAULT_KEY_BUDGET_USD.) |
MERIDO_DEFAULT_KEY_BUDGET_WINDOW | monthly | Window for the auto-created key budget: hourly|daily|weekly|monthly|yearly|lifetime. Default monthly. Consulted only when default_key_budget_usd is set; an unrecognized value is logged and the auto-budget is skipped. (MERIDO_DEFAULT_KEY_BUDGET_WINDOW.) |
MERIDO_MAX_KEY_BUDGET_USD | unset | When set (> 0), caps the hard_limit_usd of key-scoped USD budgets created or updated via the API — a request above the cap is rejected with 400. Temporary increases are exempt (the escape hatch). Default: unset (uncapped). (MERIDO_MAX_KEY_BUDGET_USD.) |
MERIDO_BUDGET_TIMEZONE | UTC | IANA timezone (e.g. "Asia/Ho_Chi_Minh", "US/Eastern") for calendar budget window boundaries (daily/weekly/monthly/yearly reset at local midnight, DST-aware). Hourly windows and lifetime budgets are unaffected. Default: "UTC" — leaving this unset preserves current behavior exactly. An unparseable value is logged at startup and falls back to UTC (never fatal). (MERIDO_BUDGET_TIMEZONE.) |
MERIDO_CAVEMAN_LEVEL | unset | Caveman output-compression level applied to every request. When set to a recognised level (lite, full, ultra, wenyan-lite, wenyan, wenyan-ultra), an intensity-tuned, format-aware system prompt is injected to cut output verbosity. None or an empty/blank value disables it; an unrecognised value is ignored (logged) at startup. |
MERIDO_PONYTAIL_LEVEL | unset | Ponytail output-minimization level applied to every request. When set to a recognised level (lite, full, ultra), a "lazy senior dev" system prompt is injected to cut the amount of code the agent writes. Independent of and stackable with caveman_level. None/blank disables it. |
MERIDO_MITM_ENABLED | false | Enable the MITM interception server at startup. When true, merido spawns a local TLS proxy that intercepts known coding-CLI hosts and rewrites their traffic to this gateway's /v1 API. Off by default. (MERIDO_MITM_ENABLED.) |
MERIDO_MITM_PORT | unset | Port the MITM interception server binds (on host). Defaults to 8443 when unset and MITM is enabled. (MERIDO_MITM_PORT.) |
MERIDO_MITM_MANAGE_HOSTS | false | When MITM is enabled, also manage the OS hosts file: map every intercepted host to 127.0.0.1 so the local proxy receives their traffic. Best-effort and requires elevated privileges; failures are logged, not fatal. (MERIDO_MITM_MANAGE_HOSTS.) |
MERIDO_MITM_INSTALL_CA | false | When MITM is enabled, install the generated root CA into the OS trust store so intercepted TLS handshakes validate. Best-effort; failures are logged, not fatal. (MERIDO_MITM_INSTALL_CA.) |
MERIDO_OUTBOUND_PROXY | unset | Global outbound proxy URL applied to every upstream request (e.g. http://user:pass@host:port or socks5://host:port). A per-connection proxy_url overrides this. None (default) sends traffic directly. (MERIDO_OUTBOUND_PROXY.) |
MERIDO_PLUGIN_PATH | unset | Path to a WASM filter plugin — a sandboxed request/response byte transform run by the plugin host on the chat request path. Honoured only when the binary is built with the server's wasm cargo feature; otherwise it is logged and ignored. None (default) disables plugins entirely. (MERIDO_PLUGIN_PATH.) |
MERIDO_SHADOW_EVAL_ENABLED | false | Enable shadow evaluation (Wave 21.1): replay a small, deterministic % of live traffic against an alternate ("shadow") model to prove a cheaper model is good enough, WITHOUT affecting the live response. Opt-in and off by default — it captures request/response bodies (encrypted at rest, TTL-bounded) and spends upstream credits on the replay. (MERIDO_SHADOW_EVAL_ENABLED.) |
MERIDO_SHADOW_SAMPLE_RATE | 0.02 | Fraction of eligible requests to shadow-sample, in [0.0, 1.0] (deterministic per-request sampling). Default 0.02 (2%) keeps the replay cost and stored volume small. (MERIDO_SHADOW_SAMPLE_RATE.) |
MERIDO_SHADOW_DAILY_USD_BUDGET | 5.0 | Daily USD budget cap on shadow-replay spend. Once the day's replays reach this cap, further sampling is skipped until the next day. Default 5.0. (MERIDO_SHADOW_DAILY_USD_BUDGET.) |
MERIDO_SHADOW_TTL_DAYS | 7 | Retention, in days, for stored shadow samples (the concrete expires_at a TTL sweep deletes by). Default 7. (MERIDO_SHADOW_TTL_DAYS.) |
MERIDO_PRICING_SYNC_ENABLED | true | Keep model prices fresh by syncing a public rate-card snapshot on startup and then on an interval, layered above the compiled-in fallback table (operator overrides always win). Default true; failures are non-fatal — the gateway falls back to the last cached snapshot, then the built-in table. (MERIDO_PRICING_SYNC_ENABLED.) |
MERIDO_PRICING_SYNC_URL | https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json | Primary pricing source: a LiteLLM-format model_prices_and_context_window.json (USD per token). Default points at LiteLLM's main. (MERIDO_PRICING_SYNC_URL.) |
MERIDO_PRICING_FALLBACK_URL | https://models.dev/api.json | Fallback pricing source used only when the primary fetch fails: a models.dev api.json (USD per 1M tokens). (MERIDO_PRICING_FALLBACK_URL.) |
MERIDO_PRICING_SYNC_INTERVAL_SECS | 21600 | How often (seconds) to re-sync prices in the background. Default 21600 (6 hours). (MERIDO_PRICING_SYNC_INTERVAL_SECS.) |
MERIDO_PRICING_SYNC_FETCH_TIMEOUT_SECS | 90 | Per-fetch HTTP timeout (seconds) when downloading an upstream rate card. Default 90 — the pinned LiteLLM snapshot is ~1.5 MB and takes up to ~80 s on a slow link; 20 s (the old hard-coded value) cuts it off. (MERIDO_PRICING_SYNC_FETCH_TIMEOUT_SECS.) |
MERIDO_PRICING_SYNC_LITELLM_REF | v1.89.1 | Git ref (tag or commit SHA) used to build the LiteLLM pricing URL, so the synced rate card is pinned to a reproducible snapshot rather than the floating main branch. Default is a pinned release tag; operators should update this when a new LiteLLM release is available. (MERIDO_PRICING_SYNC_LITELLM_REF.) |
MERIDO_PRICING_SYNC_DRIFT_PCT | 25.0 | Price-change percentage that triggers a drift review flag. When a model's input or output price shifts by more than this percentage between two consecutive synced snapshots, the change is logged as a warning and recorded in the process-global review list (but the new price is always applied). Default 25.0 (flag changes larger than 25%). (MERIDO_PRICING_SYNC_DRIFT_PCT.) |
MERIDO_USAGE_RETENTION_DAYS | 30 | Retention for the raw usage_events family (events, savings ledger, compression hits, quota snapshots, terminal batches): a background pruner deletes rows older than this many days. Defaults to 30 days (ON). Set MERIDO_USAGE_RETENTION_DAYS=0 to keep usage data forever — a non-positive value disables the pruner. (MERIDO_USAGE_RETENTION_DAYS.) |
MERIDO_AUDIT_RETENTION_DAYS | unset | Opt-in retention for the tamper-evident audit_log hash chain: when set (> 0), the SIEM-export task prunes entries older than this many days — but NEVER past the export cursor (audit.export.cursor), so an entry is only ever deleted after it was shipped to the configured sink (export-before-prune). None (the default) keeps the chain forever — no pruning runs, so the chain grows unbounded. (MERIDO_AUDIT_RETENTION_DAYS.) |
MERIDO_ERROR_RULES | empty | Operator-supplied error-classification rules that supplement and override the compiled-in defaults. Consulted by [merido_router::classify_with_rules] before the built-ins, so an operator can reclassify an upstream error (e.g. treat a provider-specific "warming up" 503 as a short cooldown) without recompiling. Populated from the MERIDO_ERROR_RULES env var (a JSON array of rule objects) by [Config::load]; empty by default, leaving built-in classification unchanged. (MERIDO_ERROR_RULES.) |
MERIDO_LOG_ENABLED | true | Whether to persist a per-request log of every /v1 data-plane request (metadata + request/response bodies) for the Monitor → Logs page. true by default; capture is best-effort and never blocks a request. (MERIDO_LOG_ENABLED.) |
MERIDO_LOG_BODIES | false | Whether to store request/response bodies (and redacted headers) alongside the log metadata. false by default (privacy-first: only metadata is kept); set true to also capture prompt/response content. Can be toggled at runtime from the dashboard (Logs page) via the request_log.bodies setting, which overrides this startup default. (MERIDO_LOG_BODIES.) |
MERIDO_LOG_MAX_BODY_BYTES | 1048576 | Max bytes of a single request or response body stored per request; larger bodies are truncated and flagged. Default 1048576 (1 MiB). (MERIDO_LOG_MAX_BODY_BYTES.) |
MERIDO_LOG_RETENTION_DAYS | 30 | Retention for request logs: a background pruner deletes rows older than this many days. Default 30; 0 disables time-based pruning. (MERIDO_LOG_RETENTION_DAYS.) |
MERIDO_LOG_RETENTION_MAX_BYTES | 2147483648 | Size cap (bytes) for the total compressed request-log bodies; the pruner evicts oldest rows until under it. Default 2147483648 (2 GiB); 0 disables size-based pruning. (MERIDO_LOG_RETENTION_MAX_BYTES.) |
MERIDO_LOG_BODY_RETENTION_DAYS | 0 | Separate, shorter retention for the stored request/response bodies. Bodies older than this many days are deleted while their log rows — who called, which model, cost, latency, status — are kept for the full log_retention_days window. A body is the customer's actual prompt and response text; the metadata row is not. Most deployments want the text to age out in days and the numbers to survive for months of cost and reliability analysis. Default 0 = no separate window: bodies live exactly as long as their log rows, which is the behaviour before this setting existed. Raising it above log_retention_days has no effect (the row is gone first). (MERIDO_LOG_BODY_RETENTION_DAYS.) |
MERIDO_LIVE_EVENT_BUFFER | 256 | Live-event broadcast buffer: how many recent request events are retained for dashboard (SSE) subscribers that briefly fall behind. A subscriber lagging past this many events misses the overflow (surfaced as merido_live_events_lagged_total on /metrics); raise it for high-RPS deployments with many live viewers. Default 256. (MERIDO_LIVE_EVENT_BUFFER.) |