# Environment variables The `picloud` server is configured entirely through environment variables. This is the complete list, grouped by area. Only `DATABASE_URL` and a master key are strictly required to boot. ## Required to boot | Variable | Default | Purpose | |---|---|---| | `DATABASE_URL` | — | **Required.** Postgres connection string. | | `PICLOUD_SECRET_KEY` | — | Master encryption key, base64 of 32 bytes. Required **unless** dev mode is acknowledged (below). Encrypts secrets and realtime keys at rest. | On a **fresh** database you also need the [bootstrap admin](#bootstrap-admin) vars. After that, only the two above are required. ## Dev mode | Variable | Default | Purpose | |---|---|---| | `PICLOUD_DEV_MODE` | `false` | Enables local-dev conveniences (in-memory email sink). **Never in production.** | | `PICLOUD_DEV_INSECURE_KEY` | — | Set to the literal `i-understand-this-is-insecure` to boot without `PICLOUD_SECRET_KEY`, using a deterministic, world-known dev key. `PICLOUD_DEV_MODE=true` **alone aborts** — you must also set this. Never in production. | ## Network & process | Variable | Default | Purpose | |---|---|---| | `PICLOUD_BIND` | `0.0.0.0:8080` | HTTP listen address. (In Compose, picloud binds 8080 *inside* the network; Caddy publishes 8000.) | | `PICLOUD_PUBLIC_BASE_URL` | `http://localhost:8000` | Public origin reported by `/version` and used to render URLs. | | `PICLOUD_DB_MAX_CONNECTIONS` | `32` | Postgres pool size (matched to the execution cap). | | `PICLOUD_MAX_CONCURRENT_EXECUTIONS` | `32` | Global cap on simultaneous script runs. Overflow → `503` + `Retry-After: 1`, no queue. | | `PICLOUD_SESSION_TTL_HOURS` | `24` | Admin session sliding-window lifetime. | | `RUST_LOG` | `info` | `tracing` filter, e.g. `info,picloud=debug`. | | `PICLOUD_CONFIG_DIR` | platform default | Where the `pic` CLI stores credentials. | ## Bootstrap admin {#bootstrap-admin} Read only on a fresh install (empty `admin_users`); ignored afterward. See [Server admin commands](../cli/server-admin.md). | Variable | Purpose | |---|---| | `PICLOUD_ADMIN_USERNAME` | first admin's username (seeded as `owner`) | | `PICLOUD_ADMIN_PASSWORD_HASH` | preferred: Argon2id PHC string | | `PICLOUD_ADMIN_PASSWORD` | fallback: raw password | ## Data-plane size caps Exceeding any cap throws in the script. All in bytes. | Variable | Default | Caps | |---|---|---| | `PICLOUD_KV_MAX_VALUE_BYTES` | `262144` (256 KiB) | `kv::...set` value | | `PICLOUD_DOCS_MAX_VALUE_BYTES` | `262144` | `docs` document | | `PICLOUD_PUBSUB_MAX_MESSAGE_BYTES` | `262144` | `pubsub::publish_durable` message | | `PICLOUD_QUEUE_MAX_PAYLOAD_BYTES` | `262144` | `queue::enqueue` message | | `PICLOUD_SECRET_MAX_VALUE_BYTES` | `262144` | `secrets::set` value | | `PICLOUD_FILES_MAX_FILE_SIZE_BYTES` | `104857600` (100 MiB) | `files::...create/update` blob | | `PICLOUD_EMAIL_MAX_MESSAGE_BYTES` | — | inbound/outbound email size | | `PICLOUD_EMAIL_MAX_RECIPIENTS` | — | recipients per send | | `PICLOUD_HTTP_MAX_REQUEST_BODY_BYTES` | — | outbound `http` request body | | `PICLOUD_HTTP_MAX_RESPONSE_BODY_BYTES` | — | outbound `http` response body read | ## Sandbox ceilings Upper bounds on per-script [sandbox overrides](../../guide/writing-scripts.md#sandbox-limits). An override above the ceiling is rejected at deploy time. Defaults are the conservative built-ins. | Variable | Default ceiling | |---|---| | `PICLOUD_SANDBOX_MAX_OPERATIONS` | 10,000,000 | | `PICLOUD_SANDBOX_MAX_STRING_SIZE` | 1 MiB | | `PICLOUD_SANDBOX_MAX_ARRAY_SIZE` | 100,000 | | `PICLOUD_SANDBOX_MAX_MAP_SIZE` | 100,000 | | `PICLOUD_SANDBOX_MAX_CALL_LEVELS` | 128 | | `PICLOUD_SANDBOX_MAX_EXPR_DEPTH` | 128 | Two related platform-level depth bounds (not per-script overridable): | Variable | Default | Purpose | |---|---|---| | `PICLOUD_MAX_TRIGGER_DEPTH` | `8` | max trigger fan-out / `invoke` re-entry depth | | `PICLOUD_MODULE_IMPORT_DEPTH_MAX` | `8` | max `import` chain depth | ## Outbound HTTP (`http` SDK) | Variable | Default | Purpose | |---|---|---| | `PICLOUD_HTTP_ALLOW_PRIVATE` | `false` | **Dev/test only.** `true` disables the SSRF deny-list (allows requests to private/loopback IPs). Never production. | ## Email / SMTP Configure a relay to make `email::send` work; without it, sends throw `NotConfigured` (or hit the dev sink in dev mode). | Variable | Purpose | |---|---| | `PICLOUD_SMTP_HOST` / `PICLOUD_SMTP_PORT` | relay address | | `PICLOUD_SMTP_USER` / `PICLOUD_SMTP_PASSWORD` | relay auth | | `PICLOUD_SMTP_TLS` | TLS mode | | `PICLOUD_SMTP_TIMEOUT_SECS` | send timeout | ## Triggers, dispatcher & background workers | Variable | Default | Purpose | |---|---|---| | `PICLOUD_DISPATCHER_ASYNC_EXEC_TIMEOUT_SEC` | `120` | per-message executor budget for async/triggered runs | | `PICLOUD_DISPATCHER_TICK_INTERVAL_MS` | — | dispatcher poll interval | | `PICLOUD_CRON_TICK_INTERVAL_MS` | — | cron scheduler resolution | | `PICLOUD_QUEUE_RECLAIM_INTERVAL_MS` | — | how often expired claims are reclaimed | | `PICLOUD_QUEUE_DEFAULT_VISIBILITY_TIMEOUT_SECS` | — | default queue claim lease | | `PICLOUD_TRIGGER_RETRY_MAX_ATTEMPTS` | `3` | default trigger retry attempts | | `PICLOUD_TRIGGER_RETRY_BACKOFF` | `exponential` | default backoff shape | | `PICLOUD_TRIGGER_RETRY_BASE_MS` | `1000` | default backoff base | | `PICLOUD_TRIGGER_RETRY_JITTER_PCT` | — | retry jitter | | `PICLOUD_DEAD_LETTER_RETENTION_DAYS` | `30` | how long dead-letters are kept | | `PICLOUD_ABANDONED_EXECUTIONS_RETENTION_DAYS` | — | sweep window for stale in-flight executions | ## Realtime, subscriber tokens & caches | Variable | Default | Purpose | |---|---|---| | `PICLOUD_REALTIME_HEARTBEAT_SEC` | `30` | SSE heartbeat interval | | `PICLOUD_REALTIME_BROADCAST_CAPACITY` | — | per-topic broadcast buffer | | `PICLOUD_SUBSCRIBER_TOKEN_TTL_DEFAULT_SEC` / `_MIN_SEC` / `_MAX_SEC` | — | bounds for `pubsub::subscriber_token` TTLs | | `PICLOUD_SCRIPT_CACHE_SIZE` / `PICLOUD_MODULE_CACHE_SIZE` | — | in-memory cache sizes | ## Files storage | Variable | Default | Purpose | |---|---|---| | `PICLOUD_FILES_ROOT` | `./data` | filesystem root for `files` blobs | | `PICLOUD_FILES_ORPHAN_SWEEP_INTERVAL_SEC` / `PICLOUD_FILES_ORPHAN_TMP_TTL_SEC` | — | cleanup of stale temp blobs | ## App-user token lifetimes (`users` SDK) | Variable | Purpose | |---|---| | `PICLOUD_APP_USER_SESSION_TTL_HOURS` / `_ABSOLUTE_HOURS` | sliding & absolute session lifetime | | `PICLOUD_APP_USER_VERIFICATION_TTL_HOURS` | email-verification token TTL | | `PICLOUD_APP_USER_PASSWORD_RESET_TTL_HOURS` | password-reset token TTL | | `PICLOUD_APP_USER_INVITATION_TTL_DAYS` | invitation TTL | ## `pic` CLI | Variable | Purpose | |---|---| | `PICLOUD_URL` | default server URL for `pic` | | `PICLOUD_TOKEN` | bearer token for `pic` (CI) | > Values shown as "—" have an internal default that's safe to leave unset; consult the running > instance or release notes if you need the exact number for capacity planning.