queues
Skill4 starsChanged 4 months agoMITView on GitHub
Run work asynchronously with Laravel queues — dispatch jobs, choose a queue driver (sync, database, Redis, SQS, Beanstalkd), run workers or Horizon, and tune retries, backoff, timeouts, failed jobs, batching, and rate limiting. Use when the user needs to choose or configure a queue driver such as sync, database, Redis, SQS, or Beanstalkd; the user wants to move slow work (email, image processing, API calls) out of the web request into a background job; the user is configuring job retries, backoff, timeouts, or handling failed jobs and workers that keep reprocessing. Keywords: queue, queues, jobs, workers, horizon, redis, sqs, performance, retries, failed-jobs, input, laravel.
5 other projects use a version of this.
Adopted by
Most recently taken up by
- stacksyncdata/skillstheir own version, first seen Oct 20, 2026
- vercel/vercel-plugintheir own version, first seen Oct 8, 2026
- postproxy/postproxy-claude-plugintheir own version, first seen Sep 8, 2026
- vercel-labs/hatcherytheir own version, first seen Aug 13, 2026
- zllovesuki/cloudflare-agent-skillstheir own version, first seen Apr 28, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 5
- vercel/vercel-plugin★ 328same name
- zllovesuki/cloudflare-agent-skills★ 9same name
- vercel-labs/hatchery★ 7same name
- postproxy/postproxy-claude-plugin★ 0same name
- stacksyncdata/skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository119 other files it gives its agents.
- strategy-bitrix-d7-incrementalSkill
- strategy-explicit-over-magicSkill
- strategy-framework-conventionsSkill
- strategy-legacy-safe-editsSkill
- strategy-minimal-diffSkill
- strategy-no-untested-refactorSkill
- strategy-preserve-public-apiSkill
- strategy-readonly-immutabilitySkill
- strategy-security-firstSkill
- strategy-test-drivenSkill
- openapiSkill
- paginationSkill
- rest-designSkill
- versioningSkill
- cqrsSkill
- dependency-inversionSkill
- hexagonalSkill
- repository-patternSkill
- service-layerSkill
- bitrixSkill
- findings-reportSkill
- laravelSkill
- performanceSkill
- phpSkill
- project-analysisSkill
- refactoringSkill
- roi-prioritizationSkill
- securitySkill
- stack-detectionSkill
- cache-layersSkill
- component-engineSkill
- d7-eventsSkill
- d7-loaderSkill
- d7-orm-queriesSkill
- iblock-elementsSkill
- kernel-main-moduleSkill
- localizationSkill
- controllersSkill
- ormSkill
- validationSkill
- controllersSkill
- query-builderSkill
- routingSkill
- autoload-psr4Skill
- dependency-managementSkill
- scriptsSkill
- connection-poolingSkill
- mysql-indexingSkill
- redisSkill
- transactionsSkill
- ci-github-actionsSkill
- deployment-strategiesSkill
- docker-phpSkill
- env-configSkill
- associationsSkill
- entities-mappingSkill
- orm-basicsSkill
- entity-apiSkill
- module-developmentSkill
- routing-controllersSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
14 rules. 0 are common, 6 are distinctive, and 8 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
6
Distinctive
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 82
Do not use queues to run periodic time-based tasks.
- Distinctive: line 83
Do not queue work whose result the caller needs within the same request.
- Very specific: line 132
Run php artisan make:job SendInvoiceEmail.
- Very specific: line 134
Verify: The generated class implements ShouldQueue and has a handle() method.
- Very specific: line 137
Verify: handle() receives its dependencies and $tries is a finite number.
- Distinctive: line 140
Verify: The request returns immediately and the worker log shows the job processed once.
- Very specific: line 156
Verify: config('queue.default') is redis and retry_after exceeds the max job runtime.
- Very specific: line 157
Run php artisan queue:work redis --timeout=<below retry_after> (or install Horizon) and manage the process with Supervisor or systemd for …
- Distinctive: line 159
Verify: The worker consumes the redis queue and restarts automatically after it exits.
- Very specific: line 160
Add php artisan queue:restart to the deploy pipeline and configure a failed_jobs store plus alerting so exhausted jobs are surfaced.
- Distinctive: line 162
Verify: A deploy reloads worker code and a forced failure records to failed_jobs and alerts.
- Very specific: line 166
When many jobs form one logical unit and you need a completion or failure callback, dispatch them with …
- Very specific: line 168
When a job calls a rate-limited API, apply middleware such as RateLimited or WithoutOverlapping instead of sleeping inside the job
- Distinctive: line 170
When the same job must not run twice concurrently (e.g
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- generated: do not edit — source: knowledge/atoms/laravel/queues/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->Laravel Queues
When to use
- The user needs to choose or configure a queue driver such as sync, database, Redis, SQS, or Beanstalkd.
- The user wants to move slow work (email, image processing, API calls) out of the web request into a background job.
- The user is configuring job retries, backoff, timeouts, or handling failed jobs and workers that keep reprocessing.
When NOT to use
- Do not use queues to run periodic time-based tasks; use the task scheduler (cron) to dispatch them on a schedule.
- Do not queue work whose result the caller needs within the same request; run it synchronously instead.
Core guidance
- Use backoff and capped retries for flaky external calls — For jobs hitting external APIs, set a
$backoff(often an array for exponential delay) and a finite$triesorretryUntil()rather than unlimited retries. - Prefer Redis + Horizon for high-throughput, low-latency queues — When throughput is high or jobs must start within seconds, use the Redis driver with Horizon for near-instant dispatch, atomic pops, and per-queue autoscaling.
- Keep worker timeout below the connection retry_after — Set the worker
--timeoutlower than the queue connection'sretry_afterso a job is killed before the queue makes it available again.
Decision Engine
Walk this section before choosing an implementation path.
Do you need real async processing, and if so is the platform managed AWS or
self-hosted with Redis available?
├── No Redis or AWS, low volume: → database driver — zero extra infrastructure and transactional with your data;
fine for low volume but polls and contends on writes as load grows.
├── Redis available, need throughput and Horizon: → redis driver with Horizon — low latency, atomic pops, per-queue autoscaling and
metrics; the default choice for high-throughput self-hosted apps.
├── AWS-managed, no Redis to operate: → sqs driver — fully managed, scales without servers to run; accept ~seconds of
latency and the 15-minute visibility-timeout ceiling.
└── Local dev or tests only: → sync driver — runs jobs inline in the current process; use only in local
development and tests, never in production.
Full engine: references/decision-engine.md — Decision Tree, Priority Matrix, Decision Table.
Workflows
Workflow: Dispatch Job
Progress:
- [ ] Run `php artisan make:job SendInvoiceEmail`; it implements `ShouldQueue` and
gets the queueable traits so it runs asynchronously
- [ ] Type-hint dependencies in `handle()` so the container injects them, and set
`public int $tries` and `public array $backoff` for bounded, backed-off retries
- [ ] Dispatch with `SendInvoiceEmail::dispatch($invoice)` (pass an id, not a heavy
graph) and run a worker with `php artisan queue:work` to process it- Run
php artisan make:job SendInvoiceEmail; it implementsShouldQueueand gets the queueable traits so it runs asynchronously.- Verify: The generated class implements
ShouldQueueand has ahandle()method.
- Verify: The generated class implements
- Type-hint dependencies in
handle()so the container injects them, and setpublic int $triesandpublic array $backofffor bounded, backed-off retries.- Verify:
handle()receives its dependencies and $tries is a finite number.
- Verify:
- Dispatch with
SendInvoiceEmail::dispatch($invoice)(pass an id, not a heavy graph) and run a worker withphp artisan queue:workto process it.- Verify: The request returns immediately and the worker log shows the job processed once.
Workflow: Configure Redis Driver
Progress:
- [ ] Install predis or phpredis, then set `QUEUE_CONNECTION=redis` and configure the
redis connection's `retry_after` in `config/queue.php` above your longest job
- [ ] Run `php artisan queue:work redis --timeout=<below retry_after>` (or install
Horizon) and manage the process with Supervisor or systemd for auto-restart
- [ ] Add `php artisan queue:restart` to the deploy pipeline and configure a
failed_jobs store plus alerting so exhausted jobs are surfaced- Install predis or phpredis, then set
QUEUE_CONNECTION=redisand configure the redis connection'sretry_afterinconfig/queue.phpabove your longest job.- Verify:
config('queue.default')isredisandretry_afterexceeds the max job runtime.
- Verify:
- Run
php artisan queue:work redis --timeout=<below retry_after>(or install Horizon) and manage the process with Supervisor or systemd for auto-restart.- Verify: The worker consumes the redis queue and restarts automatically after it exits.
- Add
php artisan queue:restartto the deploy pipeline and configure a failed_jobs store plus alerting so exhausted jobs are surfaced.- Verify: A deploy reloads worker code and a forced failure records to failed_jobs and alerts.
Best practices
- When many jobs form one logical unit and you need a completion or failure
callback, dispatch them with
Bus::batch([...])->then(...)->catch(...) - When a job calls a rate-limited API, apply middleware such as
RateLimitedorWithoutOverlappinginstead of sleeping inside the job - When the same job must not run twice concurrently (e.g
Anti-patterns
| Anti-pattern | Why it fails | Do instead |
| Running queue:work without a process supervisor | The worker exits on fatal errors, deploys, or memory limits, and silently stops processing jobs with no restart. | Manage workers with Supervisor, systemd, or Horizon so they auto-restart and stay running. |
| Serializing heavy state into the job payload | Bloated payloads slow enqueue and dequeue, blow size limits (SQS caps at 256 KB), and can capture stale data. | Pass identifiers (or use SerializesModels, which stores only the model key) and<br>reload fresh state inside handle(). |
| QUEUE_CONNECTION=sync in production | Inline execution blocks the response and removes all queue benefits — slow requests, timeouts, and no retry safety. | Set a real driver (redis, sqs, or database) in production and run a worker or Horizon to process jobs. |
See references/anti-patterns.md.
Debugging
- Workers leak memory without recycling — Static caches, event listeners, and retained models keep growing the resident set of a persistent process. Fix: Recycle workers with
--max-jobsand--max-time, cap--memory, and avoid holding large collections in the job after they are processed. - Poison messages retry forever and block the queue — Unbounded retries turn one permanently-broken payload into a queue-wide denial of service. Fix: Set a finite
$tries(orretryUntil()) and a$maxExceptionscap so the job is sent to failed_jobs instead of cycling forever. - Confusing retry_after with the worker timeout — If
--timeoutis greater than or equal toretry_after, the queue re-dispatches the job to another worker while the first is still running it, causing duplicates. Fix: Always set--timeouta few seconds belowretry_after, and sizeretry_afterabove the job's worst-case runtime. - Long-lived workers run stale code after deploy — Workers silently process jobs with the old code, producing confusing "the fix didn't deploy" bugs. Fix: Run
php artisan queue:restartat the end of every deploy so workers exit and reload on new code.
Performance notes
- Workers leak memory without recycling — A long-lived worker accumulates memory across jobs and is eventually killed for exceeding the limit, dropping the in-flight job.
- Throttle jobs against rate-limited dependencies — When a job calls a rate-limited API, apply middleware such as
RateLimitedorWithoutOverlappinginstead of sleeping inside the job. - Prefer Redis + Horizon for high-throughput, low-latency queues — When throughput is high or jobs must start within seconds, use the Redis driver with Horizon for near-instant dispatch, atomic pops, and per-queue autoscaling.
Production checklist
- Every job sets a finite tries or retryUntil plus backoff so poison messages cannot retry forever.
- The deploy pipeline runs queue:restart so workers pick up newly deployed code.
- A failed_jobs store is configured and jobs implement failed() to alert and compensate on final failure.
- QUEUE_CONNECTION in production is a real driver (redis, sqs, or database), never sync.
- Workers run under Supervisor, systemd, or Horizon so they restart automatically on exit.
- The worker --timeout is set below the connection retry_after, which itself exceeds the job's max runtime.
Version notes
- Laravel 13 tightens queued job serialization — Laravel 13 serializes queued job properties more strictly; ensure
constructor arguments are serializable or guard with
WithoutOverlapping. - Job batching available from Laravel 8 —
Bus::batch()withthen/catch/finallycallbacks and a batches table has been available since Laravel 8 and is supported across the 10.x–12.x range. - ShouldBeUnique available from Laravel 8 — The
ShouldBeUniqueinterface withuniqueId()anduniqueFor()is available from Laravel 8 and requires a cache driver that supports locks (Redis, Memcached).
Security
- Treat job payloads as untrusted and never queue secrets — Job payloads are serialized to the queue store (DB rows, Redis, SQS) and may be
logged or inspected, so validate deserialized input inside
handle()and never put raw secrets or passwords in the constructor arguments.
Testing
- Activation and decision behavior are verified in
eval/scenarios/laravel/queues.yaml.
Additional resources
- references/anti-patterns.md
- references/core.md
- references/decision-engine.md
- references/examples.md
- references/pitfalls.md
- references/recipes.md
- references/version-differences.md
Knowledge graph
Prerequisites: laravel/service-container
Related: audit/laravel, databases/redis, laravel/eloquent-relationships
Behavior constraints: ai-rules/strategy-minimal-diff
<!-- graph-fragment: graph/fragments/laravel/queues.yaml -->Skill contract
Produces: queue.driver-selected, queue.worker-configured
Risk: medium · Confidence: 0.95
<!-- contract-fragment: contracts/fragments/laravel/queues.yaml -->Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

