jobs-events
When to use
Use when creating jobs, events, listeners, or queued workflows.
Do NOT use when:
- Artisan commands (use
artisan-commands skill)
- Scheduling configuration (use
laravel-scheduling skill)
Procedure: Create a Job
Step 0: Inspect
- Check existing jobs — match naming, queue config, retry strategy, failure handling.
- Determine sync vs. async — only queue work that is slow, retryable, or non-blocking.
- Check queue driver:
.env / config/queue.php (Redis, database, sync).
- Check Horizon:
config/horizon.php for queue names, supervisors, balancing.
Step 1: Create the job class
- Pass IDs or compact DTOs in constructor — not full models with relations.
- Set queue via
$this->onQueue(Queue::NAME->value).
- Add
tags() for Horizon filtering.
- Set
$maxExceptions, backoff(), $uniqueFor as needed.
Step 2: Implement handle()
- Keep focused and readable.
- Delegate complex logic to services/actions.
- Design for idempotency — retries must not create duplicates.
Step 3: Test
Bus::fake(), Queue::fake(), Event::fake().
- Test side effects, not just dispatch assertions.
Procedure: Create an Event + Listener
Step 1: Create event
- Past-tense naming:
OrderPlaced, ImportCompleted.
- Keep payload focused.
- Laravel 11+: automatic discovery — no manual registration.
Step 2: Create listener
- One responsibility per listener.
- Delegate large logic to services.
- Use
ShouldQueue on listeners that do heavy work.
Conventions
→ See guideline php/jobs.md for full conventions (serialization, idempotency, events, dispatching).
Output format
- Job/Event/Listener class(es) with proper serialization and retry config
- Event registration in EventServiceProvider if needed
Gotcha
- Without
ShouldQueue, jobs run synchronously.
- Queued jobs serialize constructor args — don't pass loaded models.
- Listener exceptions block the event chain — queue heavy listeners.
- Set
$tries and $backoff — unlimited retries overwhelm the queue.
Do NOT
- Do NOT serialize Eloquent models with loaded relations into queued jobs.
- Do NOT ignore idempotency — retries must not create duplicates.
- Do NOT hide critical business flows behind deep listener chains.
Auto-trigger keywords
- Laravel job
- queue
- event
- listener
- dispatch
- serialization
1---2name: jobs-events3description: Use when creating Laravel jobs, queued workflows, events, or listeners. Covers clear responsibilities, safe serialization, and retry/failure handling.4---56# jobs-events78## When to use910Use when creating jobs, events, listeners, or queued workflows.1112Do NOT use when:13- Artisan commands (use `artisan-commands` skill)14- Scheduling configuration (use `laravel-scheduling` skill)1516## Procedure: Create a Job1718### Step 0: Inspect19201. Check existing jobs — match naming, queue config, retry strategy, failure handling.212. Determine sync vs. async — only queue work that is slow, retryable, or non-blocking.223. Check queue driver: `.env` / `config/queue.php` (Redis, database, sync).234. Check Horizon: `config/horizon.php` for queue names, supervisors, balancing.2425### Step 1: Create the job class26271. Pass IDs or compact DTOs in constructor — not full models with relations.282. Set queue via `$this->onQueue(Queue::NAME->value)`.293. Add `tags()` for Horizon filtering.304. Set `$maxExceptions`, `backoff()`, `$uniqueFor` as needed.3132### Step 2: Implement handle()33341. Keep focused and readable.352. Delegate complex logic to services/actions.363. Design for idempotency — retries must not create duplicates.3738### Step 3: Test3940- `Bus::fake()`, `Queue::fake()`, `Event::fake()`.41- Test side effects, not just dispatch assertions.4243## Procedure: Create an Event + Listener4445### Step 1: Create event4647- Past-tense naming: `OrderPlaced`, `ImportCompleted`.48- Keep payload focused.49- Laravel 11+: automatic discovery — no manual registration.5051### Step 2: Create listener5253- One responsibility per listener.54- Delegate large logic to services.55- Use `ShouldQueue` on listeners that do heavy work.5657## Conventions5859→ See guideline `php/jobs.md` for full conventions (serialization, idempotency, events, dispatching).6061## Output format62631. Job/Event/Listener class(es) with proper serialization and retry config642. Event registration in EventServiceProvider if needed6566## Gotcha6768- Without `ShouldQueue`, jobs run synchronously.69- Queued jobs serialize constructor args — don't pass loaded models.70- Listener exceptions block the event chain — queue heavy listeners.71- Set `$tries` and `$backoff` — unlimited retries overwhelm the queue.7273## Do NOT7475- Do NOT serialize Eloquent models with loaded relations into queued jobs.76- Do NOT ignore idempotency — retries must not create duplicates.77- Do NOT hide critical business flows behind deep listener chains.7879## Auto-trigger keywords8081- Laravel job82- queue83- event84- listener85- dispatch86- serialization