Configure Workers
Workers are background processes that run alongside your main application. They are typically used for processing long-running tasks, handling queues, or performing scheduled jobs.
Basic Worker Configuration
You can define workers in your config.cap.yaml under the workers section. Each worker needs a unique name and either a command or subcommand to execute.
Note
Learn more about subcommands in the application types documentation.
workers:
my-queue-processor:
command: "php artisan queue:work --queue=my_queue"
replicas: 1
resources: # Optional resource allocation for this worker
cpu: 250m
memory: 512Mi
| Property | Type | Description | Default |
|---|---|---|---|
replicas |
integer |
The number of instances of this worker to run. | 1 |
stateful |
boolean |
When enabled, worker instances have stable identities and hostnames. See Stateful Workers below. | false |
terminationTimeout |
integer or string |
How long the worker has to shut down gracefully before forcibly terminating it. Accepts seconds as an integer or a duration string (e.g. '5m', '1h 30s'). |
30 |
command |
string or array |
The full command to execute (e.g., php /app/script.php). See YAML Schema Reference. |
|
subcommand |
string or array |
The command to run using the application's framework binary (e.g., queue:work). See YAML Schema Reference. |
|
resources |
object |
Define CPU and memory resources for this worker. See YAML Schema Reference. | Defaults from application type |
Custom Base Image Required for Subcommands
The subcommand option generates a command with a custom binary that is only available within our base container. Only use this feature if you are using our base container.
Graceful Shutdown Timeout
By default, when a rollout happens or a shutdown is requested for any other reason, a worker
has 30 seconds to finish its current work and exit cleanly before being forcibly killed.
You can raise or lower this limit with terminationTimeout.
The value can be an integer (seconds) or a human-readable duration string:
workers:
my-queue-processor:
command: "php artisan queue:work"
terminationTimeout: 300 # 5 minutes in seconds
my-slow-worker:
command: "php artisan process:batch"
terminationTimeout: "10m" # 10 minutes as a string
Accepted duration string units include s (seconds), m (minutes), h (hours), and d (days), and they can be combined (e.g., '1h 30m').
Tip
Set terminationTimeout high enough to cover the longest job your worker may be processing at the time of a deployment.
If the timeout expires before the process exits, a SIGKILL will be sent and any in-progress work will be lost.
Stateful Workers
By default, workers can have multiple instances running simultaneously during updates (e.g., old and new versions briefly overlap). Setting stateful: true changes this behavior so that:
- Each instance gets a stable, predictable hostname (e.g.,
my-worker-0,my-worker-1). - Updates are performed in order: the existing instance is terminated before the new one starts.
- The number of running instances never exceeds the configured
replicas.
This is useful for workers that must not run concurrently (e.g., singleton background processors), or for workloads that benefit from a stable hostname.
workers:
my-singleton-worker:
stateful: true
command: "php artisan my-command"
With multiple replicas, each instance gets a dedicated hostname:
workers:
my-worker:
stateful: true
replicas: 3
# Instances: my-worker-0, my-worker-1, my-worker-2
Note
Stateful workers can be combined with scale: true for RabbitMQ-based autoscaling. Updates still respect the ordered rollout behavior.
RabbitMQ Autoscaling for Workers
CAP optionally supports autoscaling for workers based on RabbitMQ queue length. This allows your workers to scale up automatically when there's a backlog of messages and scale down when the queue is empty, optimizing resource usage.
Simple Autoscaling
A simple configuration is to just set scale: true on the worker object. This will automatically configure scaling based on the worker's name as the queue and a default scaling vector (e.g., scale up when more than 20 messages are in the queue).
workers:
runner:
scale: true
Advanced Autoscaling Configuration
You can customize the scaling behavior by providing more details in the scale block:
workers:
runner:
replicas: 2 # Minimum number of workers
scale:
enable: true
connection: "default" # Name of the RabbitMQ connection to use
queue: "my-custom-queue" # Name of the queue to monitor for scaling
vector: 20 # Determines when to scale workers based on queue length
maxReplicas: 10 # Maximum number of replicas for the scaler
Properties for scale:
| Property | Type | Description | Default |
|---|---|---|---|
enable |
boolean |
Whether to enable autoscaling for this worker. | false |
connection |
string |
The name of the RabbitMQ connection to use. | 'default' |
queue |
string |
The name of the RabbitMQ queue to monitor for scaling. | Worker's name |
vector |
integer |
(queue length / vector) determines the target number of replicas. | 20 |
maxReplicas |
integer |
The maximum number of worker replicas that can be scaled up to. | 10 |
Note
The replicas property in the main worker configuration still defines the minimum number of workers that will always be running, even when autoscaling is enabled and the queue is empty.