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

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

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

  [ home ](https://www.msaied.com)    [ articles ](https://www.msaied.com/articles)    Laravel Reverb in Production: Scaling WebSockets Beyond a Single Server        On this page       1. [  The Gap Between Demo and Production ](#the-gap-between-demo-and-production)
2. [  Problem 1: Multiple App Servers, One Reverb Node ](#problem-1-multiple-app-servers-one-reverb-node)
3. [  Problem 2: Horizontal Reverb Scaling ](#problem-2-horizontal-reverb-scaling)
4. [  Problem 3: Reconnect Storms After a Deploy ](#problem-3-reconnect-storms-after-a-deploy)
5. [  Tuning Connection Limits ](#tuning-connection-limits)
6. [  Takeaways ](#takeaways)

  ![Laravel Reverb in Production: Scaling WebSockets Beyond a Single Server](https://cdn.msaied.com/580/851fec3976838708af1706f705fe70cd.png)

  #laravel   #reverb   #websockets   #broadcasting   #redis  

 Laravel Reverb in Production: Scaling WebSockets Beyond a Single Server 
=========================================================================

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

       Table of contents

1. [  01   The Gap Between Demo and Production  ](#the-gap-between-demo-and-production)
2. [  02   Problem 1: Multiple App Servers, One Reverb Node  ](#problem-1-multiple-app-servers-one-reverb-node)
3. [  03   Problem 2: Horizontal Reverb Scaling  ](#problem-2-horizontal-reverb-scaling)
4. [  04   Problem 3: Reconnect Storms After a Deploy  ](#problem-3-reconnect-storms-after-a-deploy)
5. [  05   Tuning Connection Limits  ](#tuning-connection-limits)
6. [  06   Takeaways  ](#takeaways)

 The Gap Between Demo and Production
-----------------------------------

Laravel Reverb ships with a compelling zero-dependency story: one `php artisan reverb:start` command and you have a WebSocket server. That works brilliantly on a single Forge server. The moment you add a second app server — or your connection count climbs past a few thousand — you need a deliberate scaling plan.

This article covers the three concrete problems you will face and how to solve each one.

---

Problem 1: Multiple App Servers, One Reverb Node
------------------------------------------------

Your Laravel app runs on two EC2 instances behind a load balancer. Both instances dispatch broadcast events. Only one instance runs Reverb. The instance that *doesn't* host Reverb still needs to push messages to it.

Reverb solves this with a **Redis pub/sub backend**. Configure it in `config/reverb.php`:

```php
'servers' => [
    'reverb' => [
        // ...
        'scaling' => [
            'driver' => 'redis',
            'connection' => 'default', // your Redis connection name
        ],
    ],
],

```

With this in place, every app server publishes broadcast events to Redis. The Reverb process subscribes and fans them out to connected clients. Your app servers never need a direct TCP connection to Reverb.

> **Important:** Use a dedicated Redis logical database or a separate Redis instance for Reverb pub/sub. Mixing it with your cache or queue database makes debugging latency spikes much harder.

---

Problem 2: Horizontal Reverb Scaling
------------------------------------

A single Reverb process is single-threaded by design (it runs on ReactPHP's event loop). You can scale vertically to a point, but eventually you need multiple Reverb processes.

Run multiple Reverb workers and put a **sticky-session-aware load balancer** in front of them. Nginx with `ip_hash` is the simplest option:

```nginx
upstream reverb {
    ip_hash;
    server 10.0.0.10:8080;
    server 10.0.0.11:8080;
}

server {
    listen 443 ssl;
    location / {
        proxy_pass http://reverb;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;
    }
}

```

Sticky sessions ensure a client's WebSocket upgrade and subsequent frames all hit the same Reverb worker. Because all workers share the Redis pub/sub channel, a broadcast from any app server reaches every connected client regardless of which worker they landed on.

---

Problem 3: Reconnect Storms After a Deploy
------------------------------------------

When you restart Reverb (e.g., during a deploy), every connected client disconnects simultaneously. Laravel Echo's default reconnect strategy uses a fixed 1-second delay, so thousands of clients hammer the server at once.

Override Echo's reconnect options on the client side:

```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: true,
    enabledTransports: ['ws', 'wss'],
    // Pusher-js reconnect options
    activityTimeout: 30000,
    pongTimeout: 6000,
});

```

Pusher-js uses exponential backoff internally; the key is ensuring `activityTimeout` is long enough that routine Reverb restarts (&lt; 5 s) don't trigger a reconnect at all. Pair this with a **zero-downtime Reverb restart** using Supervisor:

```ini
[program:reverb]
command=php /var/www/artisan reverb:start --host=0.0.0.0 --port=8080
autostart=true
autorestart=true
stopwaitsecs=10

```

Supervisor's `stopwaitsecs` gives Reverb time to drain existing connections before the new process starts.

---

Tuning Connection Limits
------------------------

Reverb inherits ReactPHP's file-descriptor limits. On Linux, the default is 1024 open files per process. Raise it in your Supervisor config:

```ini
[program:reverb]
; ...
minfds=65536

```

And confirm your OS-level limit:

```bash
ulimit -n 65536

```

---

Takeaways
---------

- Enable the Redis scaling driver so all app servers can publish through a single Reverb cluster.
- Use sticky-session load balancing (Nginx `ip_hash`) in front of multiple Reverb workers.
- Tune Echo's `activityTimeout` to survive short Reverb restarts without a reconnect storm.
- Raise file-descriptor limits in Supervisor and at the OS level before you hit connection ceilings.
- Keep Reverb's Redis pub/sub on a dedicated database to isolate latency from cache/queue traffic.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Flaravel-reverb-in-production-scaling-websockets-beyond-a-single-server-1&text=Laravel+Reverb+in+Production%3A+Scaling+WebSockets+Beyond+a+Single+Server) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Flaravel-reverb-in-production-scaling-websockets-beyond-a-single-server-1) 

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

  3 questions  

     Q01  Does Laravel Reverb support clustering without Redis?        No. Without the Redis scaling driver, each Reverb process maintains its own in-memory connection table. Broadcasts published by an app server that doesn't host that Reverb process will never reach clients. Redis pub/sub is required for any multi-process or multi-server setup. 

      Q02  Can I run Reverb behind AWS ALB instead of Nginx?        Yes, but ALB requires sticky sessions via a cookie (not IP hash). Enable 'Stickiness' on the ALB target group with a duration longer than your longest expected WebSocket session. Without stickiness, WebSocket upgrade requests may be routed to a different target than subsequent frames, causing immediate disconnects. 

      Q03  How do I monitor active Reverb connections in production?        Reverb exposes a built-in statistics endpoint when you enable the `reverb.apps.*.statistics` option. You can also track connection counts via the Redis pub/sub channel subscriber count, or instrument the Reverb event loop with a custom ReactPHP timer that publishes metrics to your observability stack. 

  Continue reading

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

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

 [ ![Streaming AI Responses in Laravel: Token Budgets, Structured Output, and Agent Contracts](https://cdn.msaied.com/584/3ffe135721c65ab3f9b40401dc3c41de.png) laravel ai llm 

### Streaming AI Responses in Laravel: Token Budgets, Structured Output, and Agent Contracts

Learn how to stream LLM responses in Laravel, enforce token budgets, and lock structured output to typed PHP c...

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

 23 Aug 2026     4 min read  

  Read    

 ](https://www.msaied.com/articles/streaming-ai-responses-in-laravel-token-budgets-structured-output-and-agent-contracts) [ ![Typed PHP 8.3 Enums as Eloquent Casts, Route Parameters, and Validation Rules](https://cdn.msaied.com/583/7301900aac0f2ec5d1347df11ce92188.png) laravel php8.3 enums 

### Typed PHP 8.3 Enums as Eloquent Casts, Route Parameters, and Validation Rules

Go beyond basic enum casting. Learn how to wire PHP 8.3 backed enums into Eloquent, route model binding, and c...

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

 23 Aug 2026     1 min read  

  Read    

 ](https://www.msaied.com/articles/typed-php-83-enums-as-eloquent-casts-route-parameters-and-validation-rules) [ ![Livewire v3 Lazy Components, Islands, and Deferred Loading in Practice](https://cdn.msaied.com/582/564b2d098d2b94b53d4f5319ac77d58b.png) livewire laravel performance 

### Livewire v3 Lazy Components, Islands, and Deferred Loading in Practice

Lazy components, islands, and deferred loading in Livewire v3 let you ship fast initial pages without sacrific...

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

 23 Aug 2026     1 min read  

  Read    

 ](https://www.msaied.com/articles/livewire-v3-lazy-components-islands-and-deferred-loading-in-practice-1) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.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://www.msaied.com)
- [Projects](https://www.msaied.com/projects)
- [Articles](https://www.msaied.com/articles)
- [Certificates](https://www.msaied.com/certificates)
- [Contact](https://www.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)
