Replicated workflow and execution workers can share a runtime daemon. Without coordination, a cold image can trigger simultaneous pulls that waste bandwidth and amplify registry throttling.
Lock scope
The Redis lock key includes the runtime node scope and exact image string. Workers sharing a runtime node coordinate; workers on different runtime nodes may pull in parallel. Docker host is used as a fallback when a request omits an explicit runtime scope.
Acquisition flow
The first worker acquires the lock and pulls or inspects the image. Other workers poll until the lock is released, the image becomes available, or the configured wait timeout expires. Workflow workers use this while resolving image digests. Execution workers use it before container creation so cold runtime nodes can pull the resolved digest safely.
Configuration
WORKFLOW_WORKER_IMAGE_PULL_LOCK_TTLWORKFLOW_WORKER_IMAGE_PULL_LOCK_WAIT_TIMEOUTWORKFLOW_WORKER_IMAGE_PULL_LOCK_RETRY_INTERVALWORKFLOW_WORKER_IMAGE_PREFETCH_ENABLEDWORKFLOW_WORKER_IMAGE_PREFETCH_MAX_FANOUTEXECUTION_WORKER_IMAGE_PULL_LOCK_TTLEXECUTION_WORKER_IMAGE_PULL_LOCK_WAIT_TIMEOUTEXECUTION_WORKER_IMAGE_PULL_LOCK_RETRY_INTERVAL
Set the TTL and wait timeout above normal large-image pull time. Aggressive polling increases Redis pressure.
Prefetch fan-out
After a build resolves the image digest on one runtime node, the workflow worker best-effort pulls that digest on up to WORKFLOW_WORKER_IMAGE_PREFETCH_MAX_FANOUT other READY nodes (least-loaded first) in the background. Execution-time pulls remain the fallback, so a prefetch failure only costs a cold pull later. Disable with WORKFLOW_WORKER_IMAGE_PREFETCH_ENABLED=false.
Failure behavior
A timeout is retryable Kafka work rather than permission to start another same-runtime pull. TTL expiry prevents a crashed owner from holding the lock forever.
Separate runtime nodes can still pull the same image concurrently. Registry-wide rate limits need capacity planning outside this lock.
