All env vars are prefixed Z4J_ (brain-side) or read from the Z4J dict in framework settings (agent-side). Brain settings map onto fields in z4j_brain.settings.Settings; the prefix is dropped and the name lowercased (e.g. Z4J_EVENT_RETENTION_DAYS -> settings.event_retention_days).
This page lists every Z4J_* variable the brain reads. Most operators set only the required five plus a handful from the Database, Retention, and Metrics sections; the rest are exposed for fine-tuning under sustained load or unusual deployments.
Master application secret. Derives per-project frame HMAC keys, hashes agent and reset tokens, and encrypts stored TOTP secrets. It does not sign sessions; Z4J_SESSION_SECRET is independent. 64 hex chars recommended.
Z4J_SESSION_SECRET
Independent secret for user-session cookies. Rotating it invalidates active sessions.
Z4J_AUDIT_CHAIN_SECRET
Dedicated audit-chain signing key, at least 32 bytes, independent of Z4J_SECRET. Required outside development, with no fallback: the brain refuses to start without it rather than signing the audit log with a key that protects other things. Keep it where the database operator cannot read it.
Z4J_PUBLIC_URL
Full externally reachable base URL with scheme (https://z4j.example.com). Validated: no whitespace, no userinfo, http(s) only.
Comma-separated previous Z4J_SECRET values still accepted when verifying agent bearer tokens and stored secrets. It does NOT cover frame signing: post-handshake frames use a per-project key derived from the current Z4J_SECRET alone, so rotation still requires re-credentialing every agent. Empty = no rotation in progress. See incident response.
Z4J_PREVIOUS_SESSION_SECRETS
-
Comma-separated previous session secrets still accepted while verifying older cookies during rotation.
Z4J_AUDIT_CHAIN_PREVIOUS_SECRETS
-
Comma-separated previous audit-chain keys still accepted by the verifier during rotation. Writes use the current Z4J_AUDIT_CHAIN_SECRET. Rotation never re-signs or re-anchors old rows. Keep an old key until retention has removed every live row signed by it, then use z4j audit retire-chain-key --key-id <id>; the command refuses while its authenticated live count is non-zero.
Connections held open per engine. Each brain worker builds its own engine, so worst-case demand is workers x (pool_size + max_overflow). Check that against your server's max_connections before raising it.
Z4J_DATABASE_MAX_OVERFLOW
10
Additional connections allowed above the pool under burst, per engine. Counts toward the same worst-case total.
Hard cap on a session's age (default 7 days). Sessions are rejected past this regardless of activity.
Z4J_SESSION_IDLE_TIMEOUT_SECONDS
1800
Sliding idle timeout (default 30 minutes). Sessions whose last_seen_at is older than this are rejected.
Z4J_SESSION_COOKIE_SAMESITE
lax
SameSite attribute on the session cookie. lax or strict.
Z4J_SESSION_PIN_USER_AGENT
false
If true, the resolved client User-Agent at session issue time is enforced on every subsequent request. Off by default; too many false positives on mobile networks.
Z4J_LOGIN_LOCKOUT_THRESHOLD
10
Failed login attempts on a single account before lockout.
Z4J_LOGIN_LOCKOUT_DURATION_SECONDS
900
Lockout duration after threshold exceeded.
Z4J_LOGIN_BACKOFF_BASE_SECONDS
0.5
Deprecated compatibility value; the login path does not read it.
Z4J_LOGIN_BACKOFF_MAX_SECONDS
5.0
Deprecated compatibility value; the login path does not read it.
Z4J_LOGIN_MIN_DURATION_MS
300
Minimum response floor applied before account-dependent bookkeeping. It reduces short-path timing differences but is not a whole-request constant-time guarantee.
Z4J_LOG_LOGIN_EMAIL
false
Log the attempted email on failed logins. Off by default (PII consideration).
Days raw events rows live before the retention worker drops their partition.
Z4J_AUDIT_RETENTION_DAYS
90
Days audit_log rows live before the retention worker prunes them.
Z4J_AUDIT_RETENTION_SWEEP_INTERVAL_SECONDS
3600
Seconds between audit retention sweeps (default 1 hour).
Z4J_AUDIT_RETENTION_SWEEP_BATCH_SIZE
5000
Rows pruned per database round-trip inside one sweep pass.
Z4J_AUDIT_RETENTION_SWEEP_MAX_PER_PASS
200000
Hard cap on rows deleted in a single sweep pass. Sweeps stop and resume on the next interval if the cap is hit.
Z4J_AUDIT_CHAIN_VERIFY_ENABLED
false
Run the scheduled audit-chain verification worker. Off by default, because verification walks every retained row. Leader-gated, so replicas do not each walk the same table. A failed verification is logged at error level and counted; it does not stop the brain.
Z4J_AUDIT_CHAIN_VERIFY_INTERVAL_SECONDS
86400
Cadence for the scheduled verification. Floor 900 (15 minutes), ceiling 604800 (one week).
Bearer token required by /metrics. Operators may provide one explicitly via env or ~/.z4j/secret.env; if absent and Z4J_METRICS_PUBLIC is unset, z4j serve auto-mints one and writes it to ~/.z4j/secret.env. Run z4j metrics-token to print or rotate.
Z4J_METRICS_PUBLIC
false
Set to 1 to leave an enabled /metrics endpoint open. It has no effect when Z4J_METRICS_ENABLED=false. Use only when the endpoint is firewalled or behind an authenticated proxy.
Z4J_METRICS_ENABLED
true
Set to false to leave the /metrics route unmounted; requests return 404 regardless of the public or token settings.
Heartbeats older than this mark the agent offline in the dashboard.
Z4J_AGENT_OFFLINE_ALERT_GRACE_SECONDS
60
Extra silence past the offline timeout before the outage is confirmed and alerted (audit row + worker.offline rules + agent.offline subscriptions). See agent offline alerts.
Z4J_AGENT_HEALTH_SWEEP_SECONDS
10
Cadence for the agent health-check sweep.
Z4J_AGENT_STALE_PRUNE_DAYS
30
Live agents are soft-revoked and hidden after this many days without activity. This includes offline agents whose last heartbeat is old and UNKNOWN agents that never connected whose creation time is old. The agent row and historical IDs remain; audit entries retain target_id as a value, not through a foreign key. Set 0 to disable.
The brain's BrainRegistry routes commands to agent connections across replicas. The default postgres_notify backend uses Postgres LISTEN/NOTIFY; SQLite forces local automatically.
Variable
Default
Description
Z4J_REGISTRY_BACKEND
postgres_notify
postgres_notify or local. SQLite forces local.
Z4J_REGISTRY_LISTENER_HEARTBEAT_SECONDS
10
Self-NOTIFY heartbeat for the watchdog on the LISTEN connection.
Z4J_REGISTRY_LISTENER_HEARTBEAT_TIMEOUT_SECONDS
25
Timeout before the watchdog reconnects the LISTEN connection.
Z4J_REGISTRY_LISTENER_MAX_AGE_SECONDS
900
Hard-recycle interval for the LISTEN connection.
Z4J_REGISTRY_RECONCILE_INTERVAL_SECONDS
30
Poll cadence for pending commands targeting an agent this replica owns.
Load-bearing, not a label. The exact string dev relaxes the startup invariants (audit-chain key, allowed hosts, HTTPS public URL), names the session, CSRF and MFA-trust cookies without their hardened prefixes, and loosens host validation. Any other value, including development, is treated as production. See dev vs production.
Z4J_LOG_JSON
true
Emit logs as JSON (true) or human-readable console output (false).
Z4J_LOG_LEVEL
INFO
Stdlib logging level.
Z4J_VERSION_CHECK_URL
(canonical GitHub raw URL)
Source URL for the dashboard "Check for updates" button. Override to point at a private mirror in restricted environments.
When the brain needs to push a schedule trigger to z4j-scheduler, it dials an outbound gRPC channel. Without Z4J_SCHEDULER_TRIGGER_URL set, the brain falls back to its in-process scheduler path and the TLS variables are ignored.
Variable
Default
Description
Z4J_SCHEDULER_TRIGGER_URL
-
host:port of the scheduler's TriggerSchedule listener.
Z4J_SCHEDULER_TRIGGER_TLS_CERT
-
Path to the brain's client certificate.
Z4J_SCHEDULER_TRIGGER_TLS_KEY
-
Path to the brain's client key.
Z4J_SCHEDULER_TRIGGER_TLS_CA
-
Path to the CA bundle the brain uses to verify the scheduler's server cert.
When > 0, a rule that already emitted a notify within the window suppresses further notifies, so an event flood cannot fan out one notification per event per member. The first alert in each window always goes out. 0 notifies on every matching event.
Z4J_AUTOMATION_OUTBOX_DRAIN_INTERVAL_SECONDS
30
Cadence for the firing-outbox drain worker that replays automation firings deferred under backpressure.
Z4J_AUTOMATION_OUTBOX_MAX_ROWS_PER_PROJECT
10000
Per-project ceiling on deferred firings; above it, further firings are dropped (counted on a metric) rather than growing the outbox without bound.
Set these in the framework's config dict (for example Django
settings.Z4J) or, where the table names one, through the exact environment
variable shown. Fields marked "dict/kwargs only" are deliberately not
environment-backed.
Key
Environment variable
Required
Default
Description
brain_url
Z4J_BRAIN_URL
yes
-
HTTP(S) base URL of the brain. The transport derives its WebSocket URL.
token
Z4J_TOKEN
yes
-
Agent bearer token.
project_id
Z4J_PROJECT_ID
yes
-
Project slug. There is no "default" fallback.
hmac_secret
Z4J_HMAC_SECRET
yes at runtime
None
Per-project frame-signing secret returned at agent-mint time. The model permits None, but the runtime refuses to start without it.
agent_name
Z4J_AGENT_NAME
no
None
Optional display label. It does not default to $HOSTNAME.
agent_id
Z4J_AGENT_ID
long-poll only
""
Required when transport=longpoll; WebSocket learns it during the handshake.
environment
Z4J_ENVIRONMENT
no
"production"
Reserved deployment label available to adapters.
tags
Z4J_TAGS
no
{}
Comma-separated key=value pairs. Reserved metadata available to adapters.
transport
Z4J_TRANSPORT
no
"auto"
auto, ws, or longpoll; auto currently selects WebSocket.
engines
Z4J_ENGINES
no
[]
Comma-separated engine adapter names.
schedulers
Z4J_SCHEDULERS
no
[]
Comma-separated scheduler adapter names.
heartbeat_seconds
Z4J_HEARTBEAT_SECONDS
no
10
Seconds between heartbeats.
buffer_path
dict/kwargs only
no
$Z4J_HOME/buffer-<pid>.sqlite
Per-process SQLite buffer path. Set Z4J_HOME to move its parent; the removed Z4J_BUFFER_PATH variable is rejected.
buffer_max_events
Z4J_BUFFER_MAX_EVENTS
no
100000
Buffered event cap. Minimum 1000.
buffer_max_bytes
Z4J_BUFFER_MAX_BYTES
no
268435456
Buffer file-size cap in bytes.
max_payload_bytes
Z4J_MAX_PAYLOAD_BYTES
no
8192
Per-field truncation limit.
log_level
Z4J_LOG_LEVEL
no
"INFO"
Local agent log level.
autostart
Z4J_AUTOSTART
no
true
Start the runtime during installation.
strict_mode
Z4J_STRICT_MODE
no
false
Compatibility field; the current runtime does not branch on it.
worker_role
Z4J_WORKER_ROLE
no
None
Dashboard hint: web, task, scheduler, beat, or other.
Agent configuration precedence, highest first, is explicit installer keyword
arguments, Z4J_* environment variables, framework settings, then Config
defaults. An empty environment value is treated as unset. Agent configuration
does not read the brain's ~/.z4j/config.env file.
We use analytics cookies
Anonymous pageview + referrer data via Google Analytics so we can see which docs are useful. No advertising, no cross-site tracking. You can change your mind any time.