Configuration

Every LeanLLMConfig field and its env var — the canonical reference.

LeanLLMConfig is a Pydantic model that controls everything from persistence to redaction to retry behavior. Two ways to build it:

from leanllm import LeanLLMConfig

# Explicit construction
config = LeanLLMConfig(
    database_url="sqlite:///events.db",
    capture_content=True,
    sampling_rate=0.1,
)

# Or from environment variables
config = LeanLLMConfig.from_env()

LeanLLMConfig.from_env() is also what runs implicitly when you call LeanLLM(api_key=...) without passing a config=.

Persistence

Two operating modes, mutually exclusive. Setting both raises ValueError at startup. Setting neither disables persistence (events still flow through last_event / recent_events).

FieldEnv varDefaultWhat it does
database_urlLEANLLM_DATABASE_URLNonepostgresql://... (asyncpg) or sqlite:///... (aiosqlite). Self-hosted.
leanllm_api_keyLEANLLM_API_KEYNonelllm_... token for the LeanLLM Service.
endpointLEANLLM_ENDPOINThttps://api.leanllm.devTarget host for the remote backend.
enable_persistenceLEANLLM_ENABLE_PERSISTENCEtrueMaster switch. false skips queue + worker entirely.
auto_migrateLEANLLM_AUTO_MIGRATEtrueRun pending Alembic migrations on Postgres store init.

Worker / queue

The worker drains the queue in batches. Whichever trigger fires first wins.

FieldEnv varDefaultWhat it does
queue_max_sizeLEANLLM_QUEUE_MAX_SIZE10000In-memory queue capacity. Overflow drops oldest events (counted in dropped_events_count).
batch_sizeLEANLLM_BATCH_SIZE100Events per save_batch call.
flush_interval_msLEANLLM_FLUSH_INTERVAL_MS180000Force flush after this many milliseconds.

Resilient delivery

In-memory retry only. No disk fallback by design — see the rationale in the request interception page.

FieldEnv varDefaultWhat it does
retry_max_attemptsLEANLLM_RETRY_MAX_ATTEMPTS5Attempts per batch before dropping it.
retry_initial_backoff_msLEANLLM_RETRY_INITIAL_BACKOFF_MS500Base sleep between attempts; doubles each retry, ±20% jitter.
retry_total_budget_msLEANLLM_RETRY_TOTAL_BUDGET_MS30000Cap on total retry time per batch.

Privacy

FieldEnv varDefaultWhat it does
capture_contentLEANLLM_CAPTURE_CONTENTfalseStore prompt + response text on the event.
redaction_modeLEANLLM_REDACTION_MODEmetadatametadata / hashed / full. See redaction.

Normalization

FieldEnv varDefaultWhat it does
auto_normalizeLEANLLM_AUTO_NORMALIZEfalsePopulate normalized_input / normalized_output on every event. See normalization.

Runtime toggles

FieldEnv varDefaultWhat it does
sampling_rateLEANLLM_SAMPLING_RATE1.0Producer-side sampling (0.0–1.0). Errors always emit regardless.
environmentLEANLLM_ENVIRONMENTNoneMirrored into LLMEvent.metadata["environment"].
debugLEANLLM_DEBUGfalseDEBUG log level + per-event stderr summary.

See runtime toggles for per-call overrides (log=False, sample=..., redaction_mode=...).

DX helpers

FieldEnv varDefaultWhat it does
last_event_bufferLEANLLM_LAST_EVENT_BUFFER32Ring buffer size for client.last_event / client.recent_events(). 0 disables.
auto_chainLEANLLM_AUTO_CHAINfalseAuto-fill parent_request_id with the previous emitted event_id on the same task.

Precedence rules

  • Per-call kwargs > ambient context > config. For example, client.chat(..., redaction_mode=RedactionMode.HASHED) overrides any ambient LeanLLMContext and the global config.redaction_mode.
  • LEANLLM_DATABASE_URL and LEANLLM_API_KEY are mutually exclusive. Setting both raises at startup.
  • Errors bypass sampling. Every error event is emitted regardless of sampling_rate or per-call sample=.
  • log=False is a hard bypass. No event is built, no hooks fire, the call is a pure pass-through to LiteLLM.