# Laravel Events and Listeners in 2026: Event-Driven Architecture and Interview Questions > Master Laravel events and listeners with automatic discovery, queued listeners, and event subscribers. Covers Laravel 12 patterns and common interview questions. - Published: 2026-08-20 - Updated: 2026-08-20 - Author: Anthony Fillion-Maillet - Tags: laravel, events, listeners, php, event-driven, queues - Reading time: 9 min --- Laravel events and listeners implement the [observer pattern](https://refactoring.guru/design-patterns/observer), decoupling components by letting parts of an application react to actions without direct dependencies. When a user places an order, the `OrderShipped` event fires, and separate listeners handle notifications, analytics, and inventory updates independently. > **Laravel 12 Event Discovery** > > Laravel 12 automatically discovers listeners in `app/Listeners`. Any class with a `handle` or `__invoke` method type-hinting an event class gets registered automatically, no configuration file needed. ## How Laravel Event Discovery Works in Version 12 Since Laravel 11, the `EventServiceProvider` is gone. Laravel scans the `Listeners` directory and uses reflection to determine which events each listener responds to based on the type hint in the `handle` method signature. ```php // app/Listeners/SendOrderConfirmation.php order->user } } ``` The listener above gets automatically registered for `OrderShipped` events. No manual binding in a service provider. This reduces boilerplate and keeps event-listener relationships close to the code that implements them. To verify registered listeners, run `php artisan event:list`. For production, cache the event manifest with `php artisan event:cache` to skip directory scanning on each request. ## Creating Events and Listeners with Artisan Laravel provides Artisan commands to scaffold events and listeners: ```bash # Generate an event class php artisan make:event OrderShipped # Generate a listener linked to an event php artisan make:listener SendShipmentNotification --event=OrderShipped ``` The generated event class uses three traits: `Dispatchable` for the static `dispatch()` method, `InteractsWithSockets` for broadcasting, and `SerializesModels` to serialize Eloquent models when listeners are queued. ```php // app/Events/OrderShipped.php route('orders.index'); } } ``` For conditional dispatch, use `dispatchIf()` or `dispatchUnless()`: ```php // Only dispatch if the order has a tracking number OrderShipped::dispatchIf($order->tracking_number !== null, $order); ``` ## Queued Listeners for Slow Operations Listeners that send emails, call external APIs, or perform heavy computations should run asynchronously. Implement `ShouldQueue` to push the listener onto the queue: ```php // app/Listeners/SendShipmentNotification.php order->user } } ``` Customize queue connection and name with `$connection` and `$queue` properties, or use runtime methods: ```php public function viaConnection(): string { return 'redis'; } public function viaQueue(): string { return $this->event->order->priority === 'high' ? 'high-priority' : 'default'; } ``` ### Conditional Queueing with shouldQueue Sometimes a listener should only queue based on event data: ```php public function shouldQueue(OrderShipped $event): bool { // Only queue for orders above $100 return $event->order->total >= 10000; } ``` ## Database Transactions and Event Timing Queued listeners dispatched inside a transaction may process before the transaction commits, causing missing data errors. Two solutions exist: **1. Configure globally** in `config/queue.php`: ```php 'connections' => [ 'redis' => [ 'after_commit' => true, ], ], ``` **2. Per-listener** with `ShouldQueueAfterCommit`: ```php use Illuminate\Contracts\Queue\ShouldQueueAfterCommit; class UpdateInventory implements ShouldQueueAfterCommit { public function handle(OrderShipped $event): void { // Safe to query the order, transaction is committed } } ``` For events themselves, implement `ShouldDispatchAfterCommit` on the event class: ```php use Illuminate\Contracts\Events\ShouldDispatchAfterCommit; class OrderShipped implements ShouldDispatchAfterCommit { // Event only dispatches after transaction commits } ``` ## Unique Listeners to Prevent Duplicates The `ShouldBeUnique` interface prevents duplicate listeners from queueing while one is already processing: ```php use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; class ProcessLicenseKey implements ShouldQueue, ShouldBeUnique { public $uniqueFor = 3600; // Lock expires after 1 hour public function uniqueId(LicensePurchased $event): string { return 'license:' . $event->license->id; } public function handle(LicensePurchased $event): void { // Generate and assign license key } } ``` If the same license ID triggers multiple events quickly, only the first listener processes. Subsequent attempts find the lock held and skip queueing. ## Event Subscribers for Related Events When multiple related events share common handling logic, event subscribers group handlers in a single class: ```php // app/Listeners/UserActivitySubscriber.php 'handleLogin', Logout::class => 'handleLogout', ]; } } ``` Subscribers follow automatic discovery rules. If handler methods are in the subscriber class with properly type-hinted parameters, Laravel registers them automatically. ## Listening to Multiple Events with Union Types A single listener can respond to multiple event types using PHP 8 union types: ```php public function handle(OrderShipped|OrderCancelled $event): void { match (true) { $event instanceof OrderShipped => $this->notifyShipped($event), $event instanceof OrderCancelled => $this->notifyCancelled($event), }; } ``` This pattern works well for notifications that follow similar logic across different event types. ## Deferring Events with Event::defer Laravel 12 introduced `Event::defer()` to delay event dispatch until after a code block completes. This ensures listeners have access to all related records: ```php use Illuminate\Support\Facades\Event; Event::defer(function () { $user = User::create(['name' => 'John']); $user->posts()->create(['title' => 'Welcome']); }); // Events for both User and Post creation dispatch here ``` If an exception occurs inside the closure, deferred events never dispatch. ## Interview Questions on Laravel Events and Listeners Technical interviews frequently test understanding of event-driven architecture. Here are questions that distinguish experienced Laravel developers: **Q: How does Laravel 12 register event listeners without EventServiceProvider?** Laravel scans `app/Listeners` using reflection. It reads the type hint on `handle()` or `__invoke()` methods to determine which event each listener responds to. Cache the manifest in production with `php artisan event:cache`. **Q: When should a listener implement ShouldQueue?** Whenever the operation takes more than a few milliseconds: sending emails, calling external APIs, generating reports, or processing files. Synchronous listeners block the HTTP response. **Q: What problem does ShouldQueueAfterCommit solve?** Queued listeners may process before the database transaction commits. If the listener queries for a just-created record, it fails because the data is not yet committed. `ShouldQueueAfterCommit` delays queue dispatch until the transaction completes. **Q: How do you prevent duplicate processing for the same event?** Implement `ShouldBeUnique`. Define `uniqueId()` to return a cache key based on event data. The listener acquires an atomic lock, and duplicate dispatches skip if the lock is held. **Q: What is the difference between an event listener and an event subscriber?** A listener handles one event type. A subscriber is a class that registers handlers for multiple related events in a single place, useful for grouping authentication events or audit logging. ## What Laravel Events Mean for Scalable Applications - Events decouple components, letting features like notifications and analytics evolve independently - Queued listeners offload slow operations, keeping HTTP responses fast - `ShouldQueueAfterCommit` prevents race conditions between queue workers and database transactions - Automatic discovery in Laravel 12 removes configuration overhead, keeping listener logic close to implementation - Event subscribers consolidate related event handling, reducing file sprawl for common patterns like user activity tracking - The `/technologies/laravel/interview-questions/events-listeners` module on [SharpSkill](/technologies/laravel/interview-questions/events-listeners) covers these patterns with interactive questions --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/en/blog/laravel/laravel-events-listeners-event-driven-architecture