Configuration

The Immich URL and user credentials are configured in the app. Infrastructure settings use environment variables or an optional TOML file. Environment variables override matching TOML values.

Set IMMICH_EDIT_CONFIG=/path/to/config.toml to load a file. TOML keys use lowercase names, such as render_max_concurrency for RENDER_MAX_CONCURRENCY.

Settings

Environment variable Default Valid values or purpose
BIND_ADDR 0.0.0.0:3000 Listen socket
DATA_DIR ./data Durable database, key, imports, models, and mask rasters; Docker sets /data
DATABASE_URL sqlite://DATA_DIR/immich-edit.db?mode=rwc SQLite connection URL
PREVIEW_MAX_EDGE 65535 256 to 65535; hard ceiling for preview requests
RENDER_MAX_CONCURRENCY Half the CPU cores, clamped to 2 through 4 Total concurrent renders: previews, exports, AI mask scene renders and edited thumbnails together; must be nonzero
THUMB_MAX_CONCURRENCY Quarter of the CPU cores, clamped to 2 through 4 Background renders (edited thumbnails and batch export jobs), capped one below RENDER_MAX_CONCURRENCY so the editor keeps a slot; with RENDER_MAX_CONCURRENCY=1 background renders share the only slot; must be nonzero
RAW_FRAME_CACHE_MB max(RENDER_MAX_CONCURRENCY * 256, 512) 64 to 16384; decoded preview frames in RAM, subtracted from the host memory budget
QUALITY_FRAME_CACHE_MB 512 64 to 16384; decoded quality frames in RAM, subtracted from the host memory budget
GPU_TEXTURE_CACHE_MB An eighth of the GPU memory budget, 256 to 4096; 512 without a budget 64 to 16384; reusable GPU textures plus cached white balance, noise reduction, and capture sharpening results
GPU_MEMORY_BUDGET_MB Measured from the GPU 64 or more; GPU memory that server renders share. See GPU memory
MASK_CACHE_MB 512 Disk budget for unreferenced mask rasters; must be nonzero
EMBEDDING_CACHE_MB 2048 Disk budget for click-model embeddings; must be nonzero
DENOISE_CACHE_MB 4096 Disk budget for AI Denoise results; must be nonzero and hold at least one result, up to 6 bytes per pixel. The two most recent results also stay in RAM
IMMICH_EDIT_RENDERER auto auto, gpu, or cpu for the server renderer. A software rasterizer such as llvmpipe is used when no hardware GPU is present, and Diagnostics marks it. Browser previews are chosen per browser under Settings > This device > Preview rendering; see rendering
GPU_TIMESTAMPS false true records device time per GPU render stage in Diagnostics. Needs an adapter with timestamp queries; others fall back to wall time only
ML_RUNTIME auto auto, gpu, cpu, or off
ML_MAX_EDGE 2048 256 to 8192; source edge sent to mask inference
ML_MAX_CONCURRENCY 1 Concurrent inference jobs for AI masks and AI Denoise; must be nonzero
ML_IDLE_SECS 60 Seconds before an inactive model session unloads
ALLOWED_ORIGINS Empty Comma-separated HTTP or HTTPS origins without a path or trailing slash
TRUSTED_PROXIES Loopback, private, and link-local ranges Comma-separated IP addresses or CIDR prefixes whose X-Forwarded-For and X-Forwarded-Proto headers are believed
MAX_BODY_MB 128 Maximum request body size; must be nonzero
REQUEST_TIMEOUT_SECS 60 Timeout for ordinary API requests; must be nonzero. Export requests use ORIGINAL_TIMEOUT_SECS plus EXPORT_TIMEOUT_SECS instead
ORIGINAL_TIMEOUT_SECS 120 Immich original-download timeout
EXPORT_TIMEOUT_SECS 300 Immich export/upload timeout
CF_ACCESS_CLIENT_ID Empty Cloudflare Access service token ID sent to Immich; see Cloudflare Access
CF_ACCESS_CLIENT_SECRET Empty Cloudflare Access service token secret; set together with CF_ACCESS_CLIENT_ID

Environment-only paths

These settings do not have TOML equivalents:

Variable Native default Docker value Purpose
WEB_DIR ./web /app/web Built static frontend
DCP_DIR ./assets/dcp /app/assets/dcp Bundled camera profiles imported at startup
IMMICH_EDIT_CONFIG None None TOML configuration path
RUST_LOG info info Log filter; see logs
LOG_FORMAT pretty pretty pretty for readable lines, json for one JSON object per line

Logs

Every API response writes one line on the http target. It carries the request ID, method, path without the query string, user, status and latency. Error responses add the error code and the message sent to the client, including why a malformed request body was rejected. Server errors (5xx) log at error. 400, 408, 409, 413, 422 and 429 log at warn. Other 4xx responses log at info, except 401 and 404, which log at debug with successful responses.

A session cookie the server cannot read, for example after instance.key changes, logs an error and the request continues as signed out.

Other targets:

Target Content
upstream Failed Immich calls with their cause
client Browser errors from signed-in sessions, at most 30 a minute per user
panic Panics with location and backtrace
onnxruntime ONNX Runtime messages from AI models. Warnings and errors by default; debug adds session setup and per-run detail

The application itself logs under immich_edit_backend. For example, RUST_LOG=info,http=debug adds successful requests.

Example TOML

bind_addr = "127.0.0.1:3000"
data_dir = "/srv/immich-edit"
renderer = "auto"
ml_runtime = "auto"
render_max_concurrency = 2
allowed_origins = ["https://edit.example.com"]
trusted_proxies = ["10.0.0.0/8", "2001:db8::/32"]

Trusted proxies

The client IP used for login rate limiting, and the Secure flag on the session cookie, come from X-Forwarded-For and X-Forwarded-Proto. Those headers are only believed when the connecting peer is listed in TRUSTED_PROXIES, because any client can send them.

The default list is 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, ::1/128, fc00::/7, and fe80::/10, which covers a reverse proxy on the same host or the same Docker network. Set the variable when your proxy connects from a public address:

TRUSTED_PROXIES=203.0.113.7,2001:db8::/32

Setting the variable replaces the defaults rather than extending them, so include the private ranges you still need. An entry without a prefix length is a single host. To trust nothing, set trusted_proxies = [] in the TOML file; every request then uses the peer address and no session cookie is marked Secure.

Startup logs a warning when the server binds a specific public address and no trusted prefix is outside the private ranges, because that combination silently collapses every client to the proxy address.

Cloudflare Access

When Immich sits behind Cloudflare Access (Zero Trust) and immich-edit cannot reach it on a private network, Access answers every server-side Immich call with a redirect to its login page. Setup then fails with upstream status 302.

Create a service token under Access > Service credentials > Service Tokens. Then add a policy to the Immich application with the action Service Auth that includes that token. Give immich-edit the token:

CF_ACCESS_CLIENT_ID=<id>.access
CF_ACCESS_CLIENT_SECRET=<secret>

Every request from immich-edit to Immich then carries the CF-Access-Client-Id and CF-Access-Client-Secret headers. Browser sign-in through Immich OAuth still goes through your normal Access login.

Removed settings

v0.4.0 refuses to start when a removed key is present. The error names the replacement.

Removed Replacement
CACHE_DIR DATA_DIR
SEGMENT_RUNTIME ML_RUNTIME
SEGMENT_MAX_EDGE ML_MAX_EDGE
SEGMENT_MAX_CONCURRENCY ML_MAX_CONCURRENCY
SEGMENT_IDLE_SECS ML_IDLE_SECS

IMMICH_URL, IMMICH_API_KEY, AUTH_TOKEN, and IMMICH_EDIT_INSECURE are also no longer read. Configure the Immich connection through first-run setup.