Contents
Most web apps lie to their users. Not intentionally — they just show data from the last time the page loaded. The user submits an order, then hits refresh to see if it moved. They wait on a form submission, then reload to check. It works, but it feels broken.
Real-time updates fix this. And with Laravel Reverb, adding WebSocket support to a Laravel app is no longer a third-party integration problem.
What Reverb Is
Laravel Reverb is a first-party WebSocket server for Laravel, shipped in Laravel 11. Before Reverb, the standard path was to pay for Pusher or run a Node.js process alongside your PHP app. Both options work, but both add external dependencies and operational overhead.
Reverb runs as a native PHP process. It integrates directly with Laravel's event broadcasting system — the same system that's been in the framework for years. If you've used broadcast() before, Reverb is a drop-in server that handles the WebSocket layer.
The Business Case for Real-Time
Refreshing to see updates is friction. Friction kills engagement. Every extra step between "something happened" and "the user sees it" is a moment where they might give up, submit a duplicate request, or open a support ticket asking what's going on.
The support ticket angle is underrated. A significant portion of "where is my order" and "did my payment go through" tickets exist because the UI didn't confirm the outcome. Real-time feedback — a status badge that updates, a notification that pops — answers the question before it becomes a ticket.
For admin dashboards, the impact is even clearer. A team managing orders, approvals, or support queues shouldn't need to manually refresh to see new items. That wasted time compounds across every person on the team, every day.
How Broadcasting Works in Laravel
Laravel's broadcasting model is event-driven. You fire an event, mark it as broadcastable, and the framework pushes it to connected clients via whatever driver you've configured. With Reverb as the driver, here's the shape of it:
class OrderStatusUpdated implements ShouldBroadcast
{
public function __construct(public Order $order) {}
public function broadcastOn(): Channel
{
return new PrivateChannel("orders.{$this->order->id}");
}
}
When that event fires — say, when a webhook from your payment processor comes in — Reverb pushes the update to any browser listening on that channel. On the frontend, Laravel Echo handles the subscription:
Echo.private(`orders.${orderId}`)
.listen('OrderStatusUpdated', (e) => {
updateStatusBadge(e.order.status);
});
The user sees their order status change without refreshing. No polling. No page reload. The UI is just accurate.
Private vs. Public Channels
The example above uses a private channel. That means the framework verifies the user is authorized to listen before the subscription is accepted. You define that authorization in your channel routes file, the same way you'd write a policy.
Public channels — for things like a live sports score or a site-wide announcement — skip the authorization check. Most business applications want private channels to ensure users only receive their own data.
Presence Channels: Knowing Who's Online
Reverb also supports presence channels, which track who is currently subscribed. This is the foundation for features like "3 people are viewing this document" or a live support chat where both parties can see each other's status.
Echo.join('support-chat.123')
.here((users) => { /* currently online */ })
.joining((user) => { /* someone joined */ })
.leaving((user) => { /* someone left */ });
That kind of live awareness — knowing a human is on the other end right now — changes how users interact with an application.
Running Reverb in Production
Reverb runs as a long-lived process alongside your web server. In production, you'd manage it with Supervisor the same way you'd manage a queue worker:
[program:reverb]
command=php /var/www/artisan reverb:start
autostart=true
autorestart=true
Laravel Forge and Ploi both support Reverb configuration out of the box, so if you're already using either for deployments, adding Reverb is a few clicks.
The Upgrade It Represents
Real-time UI isn't a luxury feature anymore. Users have been trained by chat apps, delivery trackers, and live dashboards to expect accurate, up-to-date information. An app that requires manual refreshing to see current state feels dated by comparison.
Laravel Reverb makes this a first-class Laravel feature — no Pusher account, no Node process, no separate billing. If your app has any status that changes after a user action, showing it live is worth building.
Want to add real-time updates to your application? Let's talk about what that looks like for your specific use case.