Skip to content

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.