Back to all articles
Laravel Insights Jan 17, 2026 โˆ™ 1 min read

Mastering Laravel Reverb for Real-Time Apps

Learn how to implement real-time WebSocket communication in Laravel using Reverb with practical examples.

An illustration showing the Laravel Reverb logo at the center, with lines connecting it to icons representing a chat bubble, a notification bell.

Mastering Laravel Reverb for Real-Time Applications

Learn how to implement real-time WebSocket communication in Laravel using Reverb with practical examples.

Modern web applications demand dynamic, interactive user experiences. Features like live notifications, real-time dashboards, and chat systems require a persistent, bidirectional connection between the client and server. For years, this meant relying on third-party services or complex, self-hosted WebSocket solutions. With the introduction of Laravel Reverb, the framework now offers a first-party, high-performance WebSocket server designed for seamless integration and scalability.

Reverb brings blazing-fast, scalable real-time communication directly into the Laravel ecosystem. Built on PHP and powered by the high-performance event loop from ReactPHP, it eliminates the need for external dependencies like Pusher or Ably for many projects. It is engineered for speed, capable of handling thousands of concurrent connections, and integrates perfectly with Laravel's existing event broadcasting system and Laravel Echo. This empowers developers to build sophisticated real-time features with familiar tools and a simplified deployment process.

This article provides a complete guide to implementing Laravel Reverb. We will cover the installation and configuration process, demonstrate how to build a real-time chat application, and discuss best practices for scaling, debugging, and securing your WebSocket connections.

What is Laravel Reverb?

Laravel Reverb is a first-party WebSocket server for Laravel applications. It acts as a bridge, allowing your Laravel backend to push updates to connected clients instantly without waiting for a new HTTP request. Unlike traditional request-response cycles, WebSockets maintain an open connection, enabling true real-time communication.

Key Features of Laravel Reverb:

  • Blazing-Fast Performance: Built for speed and efficiency, Reverb can manage thousands of connections with minimal latency.
  • Seamless Integration: It works directly with Laravel's event broadcasting system and the Laravel Echo JavaScript library.
  • Scalability: Reverb supports horizontal scaling using Redis, allowing you to distribute connections across multiple servers.
  • First-Party Solution: As an official Laravel package, it guarantees long-term support and deep integration with the framework.
  • Monitoring with Pulse: It integrates with Laravel Pulse to provide a real-time dashboard for monitoring connections and message traffic.

Installation and Configuration

Getting started with Reverb is a streamlined process. The install:broadcasting Artisan command handles the necessary setup.

Step 1: Install Reverb

Run the following command in your Laravel project's root directory. It will publish the necessary configuration files and install the Reverb package.

php artisan install:broadcasting

During installation, you will be prompted to install Reverb and its Node dependencies. Confirm these prompts. This command updates your .env file with the necessary Reverb credentials and configures Laravel Echo.

Your .env file will now contain these variables:

BROADCAST_CONNECTION=reverb
REVERB_APP_ID=your-app-id
REVERB_APP_KEY=your-app-key
REVERB_APP_SECRET=your-app-secret
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http

Step 2: Configure Laravel Echo

The installer also creates or updates the resources/js/echo.js file, which configures Laravel Echo to connect to your Reverb server. No manual changes are typically needed here.

// resources/js/echo.js
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT,
    wssPort: import.meta.env.VITE_REVERB_PORT,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
});

Step 3: Start the Reverb Server

With the configuration complete, you can start the Reverb server using its dedicated Artisan command.

php artisan reverb:start

By default, the server runs on 0.0.0.0:8080. You will also need to run your Vite development server in a separate terminal.

npm run dev

Building a Real-Time Chat Application

Let's build a simple chat room to demonstrate Reverb in action. This example will show how to broadcast an event from the server and listen for it on the client side.

Step 1: Create the Broadcast Event

An event is a class that holds the data you want to broadcast. When this event is dispatched, Laravel's broadcasting system will send it through Reverb to all listening clients.

First, create a new event.

php artisan make:event MessageSent

Next, configure the MessageSent event to implement the ShouldBroadcast interface. This tells Laravel that the event should be broadcast.

// app/Events/MessageSent.php
namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(
        public string $username,
        public string $message
    ) {}

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        // Broadcast on a public channel named 'chat'
        return [new Channel('chat')];
    }
}

In this class, we define the public properties ($username, $message) that will be sent as the event payload. The broadcastOn() method specifies which channel the event should be sent to. Here, we use a public Channel named chat.

Step 2: Create the Frontend

Now, let's create a simple Blade view to send and display chat messages. We'll use JavaScript to listen for the MessageSent event with Laravel Echo.

<!-- resources/views/chat.blade.php -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Real-Time Chat</title>
    @vite(['resources/js/app.js'])
</head>
<body>
    <div id="messages"></div>
    <form id="message-form">
        <input type="text" id="username" placeholder="Your Name" required>
        <input type="text" id="message" placeholder="Enter message" required>
        <button type="submit">Send</button>
    </form>

    <script type="module">
        // Listen for new messages
        window.Echo.channel('chat')
            .listen('MessageSent', (e) => {
                const messagesEl = document.getElementById('messages');
                messagesEl.innerHTML += `<div><strong>${e.username}:</strong> ${e.message}</div>`;
            });
        
        // Send a message
        document.getElementById('message-form').addEventListener('submit', (e) => {
            e.preventDefault();
            const username = document.getElementById('username').value;
            const message = document.getElementById('message').value;

            fetch('/api/send-message', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
                },
                body: JSON.stringify({ username, message })
            });

            document.getElementById('message').value = '';
        });
    </script>
</body>
</html>

Step 3: Create the API Endpoint to Dispatch the Event

We need an API endpoint that receives the message from the form and dispatches our MessageSent event.

Add the following to your routes/api.php file:

// routes/api.php
use Illuminate\Http\Request;
use App\Events\MessageSent;

Route::post('/send-message', function (Request $request) {
    MessageSent::dispatch($request->username, $request->message);
    return response()->json(['status' => 'Message Sent!']);
});

With the Reverb and Vite servers running, open two browser windows to your chat page. When you send a message from one window, it will instantly appear in the other.

Securing Channels

Public channels are open to anyone. For sensitive data, you need private or presence channels, which require authorization.

Private Channels

To make our chat channel private, change Channel to PrivateChannel in the MessageSent event.

// app/Events/MessageSent.php
use Illuminate\Broadcasting\PrivateChannel;

public function broadcastOn(): array
{
    // Note the change to PrivateChannel
    return [new PrivateChannel('chat')];
}

Next, you must define an authorization callback in routes/channels.php. This callback determines if the currently authenticated user can listen to the channel.

// routes/channels.php
use Illuminate\Support\Facades\Broadcast;

Broadcast::channel('chat', function ($user) {
    // Only allow authenticated users to join
    return Auth::check();
});

Finally, update your JavaScript to listen on the private channel.

// Change .channel('chat') to .private('chat')
window.Echo.private('chat')
    .listen('MessageSent', (e) => {
        // ...
    });

Now, only authenticated users can subscribe to and receive messages on the chat channel.

Best Practices for Reverb

  1. Use Queues for Broadcasting: By default, broadcast events are dispatched synchronously. For high-traffic applications, this can slow down your HTTP responses. You should configure your broadcast events to be queued by implementing the ShouldQueue interface. This offloads the work to a queue worker, ensuring your application remains responsive.
  2. class MessageSent implements ShouldBroadcast, ShouldQueue
    {
        // ...
    }
  3. Debugging: When troubleshooting, the --debug flag is invaluable. It provides a real-time log of all connections, subscriptions, and messages passing through the server.
  4. php artisan reverb:start --debug
  5. Scaling with Redis: For applications requiring high availability or needing to handle more connections than a single server can manage, Reverb supports horizontal scaling. By enabling scaling in your reverb.php config and configuring a central Redis server, Reverb will use Redis's publish/subscribe system to broadcast messages across all server instances.

Conclusion

Laravel Reverb provides a powerful, first-party solution for building real-time applications. Its seamless integration with Laravel's broadcasting system and Echo makes it remarkably simple to add interactive features like live chats, notifications, and dashboards. By centralizing real-time infrastructure within the Laravel ecosystem, Reverb streamlines both development and deployment, removing the complexity associated with managing external WebSocket services.

By following the patterns outlined in this guide—using broadcastable events, securing channels, and offloading work to queues—you can build scalable and resilient real-time systems efficiently. Reverb is a significant step forward for the framework, empowering developers to create the engaging, dynamic experiences that users expect from modern web applications.


Related articles

Continue exploring Laravel insights and practical delivery strategies.

Laravel consulting

Need senior Laravel help for this topic?

Let's adapt these practices to your product and deliver the next milestone.