Skip to main content
Version: Next 🚧

Environment variables

All settings are read from environment variables at boot. The exporter uses zod to validate them and fails fast with a clear error if anything is invalid. Provide them via a .env file (loaded by dotenv) or your container runtime.

Core​

VariableDefaultDescription
MONGO_URImongodb://host.docker.internal:27017/librechatConnection string for your LibreChat MongoDB database.
PORT9087The port on which the exporter runs and exposes /metrics.
MONGO_POOL_SIZE50maxPoolSize passed to mongoose.connect.
REFRESH_INTERVAL30000Interval in ms for the basic metrics scrape (cheap, runs often).
ADVANCED_REFRESH_INTERVALREFRESH_INTERVAL × 10Interval in ms for the advanced metrics scrape (heavy $facet aggregations, runs on a separate timer so a slow advanced cycle never blocks basic).
CARDINALITY_REFRESH_INTERVALADVANCED_REFRESH_INTERVALInterval in ms for the cardinality scrape (per-user id-labeled metrics). A no-op (no Mongo queries) when EMIT_PER_USER_METRICS=false.
LOG_TIMINGSfalseWhen true, prints per-scrape and per-section timing logs. Per-section durations are always exposed as the librechat_exporter_section_duration_seconds histogram regardless. Accepts true or false (case-insensitive).

Cardinality and tenancy​

VariableDefaultDescription
EMIT_PER_USER_METRICSfalseWhen true, emits three high-cardinality id-labeled metrics — one Prometheus series per user. Off by default to protect large deployments. See Cardinality below.
ANONYMIZE_EMAIL_LABELtrueControls the value of the id label on the three cardinality metrics. When true (default), the value is the user's Mongo _id (24-char ObjectId). When false, it's the real email address. The label name stays id either way so dashboards don't need to change.
TENANT_ID(unset)When set, installs mongoose schema hooks that scope every aggregate / find / count query to the named tenant. Leave unset on single-tenant LibreChat installs (the default).

HTTP server hardening​

VariableDefaultDescription
METRICS_PORT(unset)Optional second port for /metrics only. If set and different from PORT, /metrics binds there and /health stays on PORT. Useful for k8s sidecar / internal-only metrics scraping.
TRUST_PROXYloopbackValue passed to app.set('trust proxy', ...). Set when running behind a reverse proxy so req.ip (and the IP allowlist) see real clients. Accepts true, false, a CIDR list, or loopback / linklocal / uniquelocal.
RATE_LIMIT_WINDOW_MS60000Per-IP rate-limit window in ms.
RATE_LIMIT_MAX120Max requests per IP to /metrics per window.
HEALTH_RATE_LIMIT_MAX600Max requests per IP to /health per window.

Auth (all optional)​

See the Auth reference for the full guide. Summary:

VariableDefaultDescription
METRICS_BEARER_TOKEN(unset)Static bearer token. If set, /metrics requires Authorization: Bearer <token>.
METRICS_BASIC_AUTH_USER(unset)HTTP Basic username. Must be set together with METRICS_BASIC_AUTH_PASSWORD.
METRICS_BASIC_AUTH_PASSWORD(unset)HTTP Basic password.
METRICS_OAUTH2_ISSUER(unset)OIDC issuer URL. Exporter discovers JWKS from ${issuer}/.well-known/openid-configuration at boot. Mutually exclusive with METRICS_OAUTH2_JWKS_URI.
METRICS_OAUTH2_JWKS_URI(unset)Direct JWKS endpoint URL. Use when the IdP does not expose OIDC discovery.
METRICS_OAUTH2_AUDIENCE(unset)Required if any METRICS_OAUTH2_* is set. The aud claim the exporter accepts.
METRICS_OAUTH2_REQUIRED_SCOPES(unset)Space-separated scopes. Token must carry every listed scope in scope or scp.
METRICS_OAUTH2_ALGORITHMSRS256,ES256Comma-separated allowed JWT signing algorithms.
METRICS_ALLOWED_IPS(unset)Comma-separated CIDRs (IPv4 / IPv6). Requests outside the list are rejected with 403. Combine with a token method (both must pass) or use standalone.
METRICS_AUTH_LOG_REJECTStrueLog auth rejections (rate-limited to ~1/sec). Set to false to silence.

Example .env​

MONGO_URI=mongodb://my-mongo-host:27017/librechat
PORT=9087
ADVANCED_REFRESH_INTERVAL=300000
EMIT_PER_USER_METRICS=false

Cardinality​

Why this matters

Prometheus charges (and slows down) per unique label combination, not per metric. Adding a per-user label creates one time series per value — easily tens of thousands on a busy LibreChat install.

Three metrics carry an id label and emit one Prometheus series per user. On large deployments this grows unbounded, so they are gated behind EMIT_PER_USER_METRICS=true:

  • librechat_transaction_cost_by_user{id}
  • librechat_transaction_token_sum_by_model_user{model,tokenType,id}
  • librechat_agent_usage_by_user_count{agent,id}

By default (ANONYMIZE_EMAIL_LABEL=true) the id label carries the user's Mongo _id. Set ANONYMIZE_EMAIL_LABEL=false if you want the real email address as the label value instead. These metrics live on their own scrape loop (CARDINALITY_REFRESH_INTERVAL) so you can refresh them less often than the rest of the advanced tier — for example only twice a day.

The corresponding *_by_email_domain variants are bounded by company-domain count and remain enabled by default.

See the Adding a metric playbook for the cardinality budget rules new metrics should follow.