Laravel Reverb: Channels, Auth &amp; Scaling in Production | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Laravel Reverb WebSocket Broadcasting: Real-Time Channels, Auth, and Scaling Patterns        On this page       1. [  Beyond the Hello-World: Laravel Reverb in Production ](#beyond-the-hello-world-laravel-reverb-in-production)
2. [  Channel Types and When to Use Each ](#channel-types-and-when-to-use-each)
3. [  Defining Private and Presence Channels ](#defining-private-and-presence-channels)
4. [  Broadcasting an Event on a Presence Channel ](#broadcasting-an-event-on-a-presence-channel)
5. [  Tuning the Reverb Server ](#tuning-the-reverb-server)
6. [  Horizontal Scaling with Redis Pub/Sub ](#horizontal-scaling-with-redis-pubsub)
7. [  Client-Side Authentication Flow ](#client-side-authentication-flow)
8. [  Key Takeaways ](#key-takeaways)

  ![Laravel Reverb WebSocket Broadcasting: Real-Time Channels, Auth, and Scaling Patterns](https://cdn.msaied.com/345/e17d357902124a7017fb076e5e19fb14.png)

  #laravel   #reverb   #websockets   #broadcasting   #real-time  

 Laravel Reverb WebSocket Broadcasting: Real-Time Channels, Auth, and Scaling Patterns 
=======================================================================================

     2 Jul 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   Beyond the Hello-World: Laravel Reverb in Production  ](#beyond-the-hello-world-laravel-reverb-in-production)
2. [  02   Channel Types and When to Use Each  ](#channel-types-and-when-to-use-each)
3. [  03   Defining Private and Presence Channels  ](#defining-private-and-presence-channels)
4. [  04   Broadcasting an Event on a Presence Channel  ](#broadcasting-an-event-on-a-presence-channel)
5. [  05   Tuning the Reverb Server  ](#tuning-the-reverb-server)
6. [  06   Horizontal Scaling with Redis Pub/Sub  ](#horizontal-scaling-with-redis-pubsub)
7. [  07   Client-Side Authentication Flow  ](#client-side-authentication-flow)
8. [  08   Key Takeaways  ](#key-takeaways)

 Beyond the Hello-World: Laravel Reverb in Production
----------------------------------------------------

Laravel Reverb ships as a first-party WebSocket server, but most tutorials stop at `php artisan reverb:start` and a public channel. Real applications need private channels with proper authorization, presence channels for collaborative UIs, and a deployment story that survives more than one server.

### Channel Types and When to Use Each

| Channel | Auth required | Presence data | Typical use | |---------|--------------|---------------|-------------| | Public | No | No | Public feeds, announcements | | Private | Yes | No | Per-user notifications, order updates | | Presence| Yes | Yes | Collaborative editors, live cursors |

### Defining Private and Presence Channels

Channel routes live in `routes/channels.php`. Return `true`/`false` for private channels; return an array of user metadata for presence channels — Reverb forwards that payload to every subscriber.

```php
// routes/channels.php

use App\Models\Project;
use Illuminate\Support\Facades\Broadcast;

// Private: only the owning user may subscribe
Broadcast::channel('orders.{orderId}', function ($user, int $orderId) {
    return $user->orders()->where('id', $orderId)->exists();
});

// Presence: return metadata so the UI knows who is online
Broadcast::channel('projects.{projectId}', function ($user, int $projectId) {
    $project = Project::find($projectId);

    if (! $project?->members()->where('user_id', $user->id)->exists()) {
        return false;
    }

    return [
        'id'     => $user->id,
        'name'   => $user->name,
        'avatar' => $user->avatar_url,
    ];
});

```

### Broadcasting an Event on a Presence Channel

```php
// app/Events/CursorMoved.php

use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class CursorMoved implements ShouldBroadcast
{
    public function __construct(
        public readonly int   $projectId,
        public readonly int   $userId,
        public readonly float $x,
        public readonly float $y,
    ) {}

    public function broadcastOn(): array
    {
        return [new PresenceChannel("projects.{$this->projectId}")];
    }

    // Only broadcast the payload the client actually needs
    public function broadcastWith(): array
    {
        return ['user_id' => $this->userId, 'x' => $this->x, 'y' => $this->y];
    }

    // Throttle: drop duplicate events within the same second
    public function broadcastWhen(): bool
    {
        return true; // add cache-based throttle here if needed
    }
}

```

### Tuning the Reverb Server

Reverb's config lives in `config/reverb.php`. The most impactful knobs for production:

```php
'servers' => [
    'reverb' => [
        'host'    => env('REVERB_SERVER_HOST', '0.0.0.0'),
        'port'    => env('REVERB_SERVER_PORT', 8080),
        'options' => [
            // Raise open-file limits before touching this
            'max_connections'  => 10_000,
            // Keep idle connections alive; lower = faster cleanup
            'max_request_size' => 10_000, // bytes
        ],
    ],
],

```

Pair this with a systemd unit that sets `LimitNOFILE=65535` so the OS doesn't cap you first.

### Horizontal Scaling with Redis Pub/Sub

A single Reverb process is a single point of failure. Run multiple workers behind a load balancer and let Redis fan out messages between them:

```php
// config/reverb.php  (scaling section)
'scaling' => [
    'enabled' => true,
    'driver'  => 'redis',
    'connection' => env('REVERB_SCALING_CONNECTION', 'default'),
],

```

Each Reverb worker subscribes to the same Redis channel. When worker A receives a broadcast, Redis delivers it to workers B and C so their connected clients all receive the event — no sticky sessions required.

> **Tip:** Use a dedicated Redis connection for Reverb scaling, separate from your cache and queue connections, to avoid head-of-line blocking under load.

### Client-Side Authentication Flow

Echo's auth endpoint hits `/broadcasting/auth` by default. Ensure your API middleware group includes `auth:sanctum` (or your guard of choice) and that CORS allows the origin your frontend runs on:

```javascript
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

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,
    forceTLS: false,
    enabledTransports: ['ws'],
    authEndpoint: '/broadcasting/auth',
});

window.Echo
    .join(`projects.${projectId}`)
    .here(members  => console.log('online:', members))
    .joining(member => console.log('joined:', member))
    .leaving(member => console.log('left:',   member))
    .listen('CursorMoved', e => moveCursor(e));

```

### Key Takeaways

- **Private channels** return a boolean; **presence channels** return a metadata array — both go through `routes/channels.php`.
- Keep `broadcastWith()` lean; every connected client receives the full payload.
- Enable Redis scaling before you need it — retrofitting under load is painful.
- Separate the Reverb Redis connection from cache/queue to prevent contention.
- Set OS-level file descriptor limits (`LimitNOFILE`) before raising `max_connections`.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-reverb-websocket-broadcasting-real-time-channels-auth-and-scaling-patterns&text=Laravel+Reverb+WebSocket+Broadcasting%3A+Real-Time+Channels%2C+Auth%2C+and+Scaling+Patterns) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-reverb-websocket-broadcasting-real-time-channels-auth-and-scaling-patterns) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Do I need sticky sessions when running multiple Reverb workers behind a load balancer?        No. With Redis scaling enabled, each worker subscribes to a shared Redis pub/sub channel. A broadcast published to any worker is fanned out to all workers, so any client can connect to any worker without session affinity. 

      Q02  How does Reverb's channel authorization differ from a standard HTTP middleware check?        Channel authorization runs through the `/broadcasting/auth` endpoint, which invokes the closure registered in `routes/channels.php`. The closure receives the authenticated user and any route parameters extracted from the channel name, letting you perform Eloquent queries or policy checks just as you would in a controller. 

      Q03  What is the practical difference between ShouldBroadcast and ShouldBroadcastNow?        ShouldBroadcast dispatches the broadcast through your queue, so it respects queue workers and backpressure. ShouldBroadcastNow bypasses the queue and broadcasts synchronously during the HTTP request — useful for low-latency events where queue delay is unacceptable, but it adds latency to the originating request. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Commune: A Private Community for Laravel Founders and Builders](https://cdn.msaied.com/346/a188e82cf37740fad2be5b4f70efaad1.png) community founders indie makers 

### Commune: A Private Community for Laravel Founders and Builders

Commune is a private community built for founders, makers, and developers to share progress, get feedback, fin...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 2 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/commune-a-private-community-for-laravel-founders-and-builders) [ ![Laravel AI Tasks: AI Orchestration with Queues, Logging, and Cost Control](https://cdn.msaied.com/347/4274eb6d6025d184daaaba35cc79c1f9.png) Laravel AI Packages 

### Laravel AI Tasks: AI Orchestration with Queues, Logging, and Cost Control

Laravel AI Tasks is a package that wraps the Laravel AI SDK with reusable task classes, three execution modes,...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 2 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/laravel-ai-tasks-ai-orchestration-with-queues-logging-and-cost-control) [ ![PHP 8.3+ Typed Enums, Backed Casts, and Readonly Properties in Modern Laravel](https://cdn.msaied.com/344/0e6a808cf916b40631d3d362a687baa8.png) laravel php8.3 enums 

### PHP 8.3+ Typed Enums, Backed Casts, and Readonly Properties in Modern Laravel

PHP 8.3 and Laravel's native enum support unlock expressive, type-safe domain models. Learn how to combine bac...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 2 Jul 2026     1 min read  

  Read    

 ](https://msaied.com/articles/php-83-typed-enums-backed-casts-and-readonly-properties-in-modern-laravel) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
