Configuration precedence
When you build worker options, three sources combine. Higher in this list wins:
- Explicit overrides — values you pass to the
WorkerOptionsconstructor, or as overrides toWorkerOptions::fromEnv([...]). - Environment variables — read by
WorkerOptions::fromEnv(). - Built-in defaults.
Examples
Explicit constructor value, no environment involved:
$options = new WorkerOptions(
apiKey: 'zf_live_sk_...', // wins outright
queues: ['email'],
);
Environment values, with one explicit override:
// FLARE_QUEUES=default,email FLARE_POLL_INTERVAL=1.0
$options = WorkerOptions::fromEnv([
'concurrency' => 5, // override on top of the env-derived options
]);
// queues = ['default', 'email'] (env), pollIntervalSeconds = 1.0 (env),
// concurrency = 5 (override)
The API key
The API key resolves in this order:
- An explicit
apiKeypassed to the options. - The
FLARE_API_KEYenvironment variable.
If neither is set, constructing the worker's client fails fast with a clear error.
Job-level configuration
Per-job settings — queue, attempts, timeout, cron — live on each job's
#[FlareJob] attribute, not on WorkerOptions. The
worker-level defaultTimeoutSeconds / defaultMaxAttempts are only fallbacks
used when a job arrives without those values.
The heartbeat test seam
For deterministic timing in tests, the FLARE_HEARTBEAT_MIN_MS environment
variable (or the heartbeatMinMs option) lowers the floor of the heartbeat
cadence so a test doesn't have to wait the full interval. The explicit option
wins over the environment variable. Leave both unset in production.