What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Laravel does not check that a job’s timeout is shorter than the queue connection’s retry_after value. The ordering is a rule you have to maintain yourself: set the effective job or worker timeout several seconds below retry_after, so the worker can exit before the queue makes the job available again. On Amazon SQS the equivalent control is the queue’s visibility timeout, not a Laravel setting.

Two settings that control two different events

The timeout and retry_after are easy to confuse because both are measured in seconds and both relate to a job that is taking a long time. They govern different things.

  • Timeout limits how long a worker may keep running a job. Laravel’s worker timeout is intended to stop a job that runs too long.
  • retry_after tells the queue how long to wait for a reserved job to be deleted or released before it treats the job as unacknowledged and makes it available to another worker.

A worker that is still running a job is not stopped by retry_after. The queue simply stops holding the job for that worker. That is the mechanism behind duplicate processing: if the queue hands the job out again while the first process is still executing it, two workers run the same job.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The ordering rule and what happens when it is reversed

Laravel’s Queues documentation (version 13.x) states the rule directly:

“The –timeout value should always be at least several seconds shorter than your retry_after configuration value.”

The same documentation describes the consequence of breaking it:

“If your –timeout option is longer than your retry_after configuration value, your jobs may be processed twice.”

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The rule is stated as guidance. Laravel does not validate the pair at runtime, and nothing in the framework will warn you when a timeout is set longer than retry_after. Treat the ordering as a configuration invariant that your deployment must keep true, and check it whenever either value changes.

A timeline with illustrative values

The documentation’s examples are a 60-second worker timeout and a 90-second retry_after. These are illustrative values, not mandatory settings. The timeline below shows why the ordering matters, using those numbers.

  1. t = 0 s: A worker reserves the job. The queue hides it from other workers.
  2. t = 0–60 s: The worker runs the job. If it finishes and deletes the job, the queue never redelivers it.
  3. t = 60 s: If the job is still running, the worker timeout fires and the worker process exits.
  4. t = 90 s: The job is still unacknowledged, so the queue makes it available again. Because the first worker has already exited, only one execution is in progress.

Now reverse the values: a 120-second timeout with a 90-second retry_after. At t = 90 s the queue makes the job available while the first worker is still inside its 120-second budget. A second worker can reserve it and begin running it. Both executions are now active.

The 30-second gap in the first example is wider than the “several seconds” minimum in Laravel’s rule. The rule is a floor, not a target. Size the gap from the behaviour of your jobs and your tolerance for delayed retries, not from the example.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Where the effective timeout comes from

More than one layer can set a timeout, and they do not all apply to the same job. The table lists the layers that matter for this ordering.

Layer Setting What it controls Precedence and notes
Job class $timeout property Maximum run time for that job Takes precedence over the command-line value, per Laravel’s Queues documentation (13.x)
Worker command queue:work --timeout Maximum run time for jobs that do not set $timeout Documented default is 60 seconds
Horizon supervisor Supervisor-level timeout Timeout for the Horizon worker process Should exceed any job-level timeout and stay a few seconds below retry_after
Queue connection retry_after Seconds before an unacknowledged job becomes available again Documentation example is 90 seconds; not a universal default
Amazon SQS queue Default Visibility Timeout (set in AWS) Redelivery window for SQS messages Replaces retry_after for SQS; Laravel does not use the connection option

When a job defines $timeout, that value is the one to compare with retry_after. Comparing the command-line default against retry_after while jobs override it can give a false sense of safety.

Settings the timeout does not cover

Blocking I/O

Laravel warns that blocking I/O, such as sockets and outgoing HTTP requests, may not respect the job timeout. An external call that hangs can keep the worker busy past its budget. Set connection and request timeouts in the client itself, and keep them comfortably inside the job timeout so the job fails on its own terms before the worker is forced to exit.

The PCNTL extension and process monitors

Laravel states that the PCNTL PHP extension must be installed for job timeouts to work. Without it, the timeout cannot be enforced as described above, and retry_after becomes the only effective limit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When a worker exits after a timeout, a process monitor such as Supervisor restarts it. If nothing restarts the worker, the queue stops processing until someone intervenes. Verify that your monitor’s own timeouts agree with the layers above rather than assuming one setting governs all of them.

Amazon SQS

SQS does not use Laravel’s retry_after option. Redelivery follows the queue’s Default Visibility Timeout, which you set in AWS. Make that visibility timeout exceed the applicable worker timeout by several seconds. Do not edit retry_after in a connection that uses the SQS driver expecting it to change redelivery behaviour, because it does not.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Attempts, timeouts and failed jobs

A timeout ends one execution. Attempts determine how many executions a job may have. If a job repeatedly times out and reaches its maximum attempts, Laravel marks it as failed. Laravel’s versioned documentation also describes a failOnTimeout job property, which changes how a timeout is handled; confirm that the property exists in the Laravel version you run before relying on it.

Because a timed-out job can also be redelivered, a job with side effects should be idempotent. Duplicate execution is the consequence the ordering rule exists to prevent, and idempotency is the protection for the cases the rule does not cover.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Checklist for checking your configuration

  • Identify the queue driver. If it is SQS, the redelivery control is the Default Visibility Timeout in AWS; otherwise it is retry_after on the connection.
  • Identify the effective timeout for each job class, including any $timeout property, and the queue:work --timeout value for jobs that do not define one.
  • Confirm that the effective timeout is several seconds below the redelivery threshold, using values sized to the longest realistic run of each job.
  • Set connection and request timeouts on every external client the jobs use.
  • Confirm that the PCNTL extension is installed and that your process monitor restarts exited workers.
  • Check the retry count and failed-job behaviour, and confirm that jobs with side effects can safely run more than once.

“

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.