Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Laravel Broadcasting with Reverb Complete Setup

By Kokil Thapa | Last reviewed: September 2026

Real-time notifications, live dashboards, and chat-style UI used to mean signing up for Pusher or running a separate Node socket server. Laravel Broadcasting with Reverb Complete Setup changes that: Reverb is Laravel’s first-party WebSocket server, and it plugs directly into the broadcasting layer you already know from events, channels, and Echo. If you run Laravel for a booking portal, client dashboard, or order tracker, this is the path that keeps your stack PHP-first without sacrificing production reliability. This guide walks through a full install on Laravel 13 with PHP 8.3+, front-end wiring with Vite 8.x, and the deployment details I use on Ubuntu servers.

What is Laravel Broadcasting with Reverb and when should you use it?

Broadcasting in Laravel lets application events reach browsers (or other clients) over WebSockets instead of polling. Reverb implements the WebSocket server side using PHP, built on Laravel’s official Reverb package and compatible with the Pusher protocol. Your app still dispatches normal Laravel events; the framework serialises them and pushes them through a connection driver—Reverb replaces Pusher, Ably, or Redis pub/sub for many teams.

You reach for Reverb when:

  • Users need instant updates: order status, booking confirmations, admin alerts, document-upload progress.
  • You want to avoid third-party WebSocket billing at scale (typical Pusher costs add up on high-traffic dashboards).
  • Your team already deploys Laravel on Ubuntu with PHP-FPM—you can run Reverb on the same box or a small sidecar VM.
  • You are building on Laravel 13.x with PHP 8.3 or 8.5 and want a supported, documented path rather than maintaining Soketi or a custom Ratchet setup.
Laravel Broadcasting with ReverbBrowserLaravel EchoReverbWebSocket serverLaravel 13Events + queuesWSHTTPBroadcast flow1. User action triggers event2. ShouldBroadcast serialises payload3. Reverb pushes to subscribed channels4. Echo listener updates the UI
Laravel Broadcasting with Reverb: Echo on the client, Reverb as the WebSocket layer, Laravel dispatching broadcastable events.

On a legal-tech portal I built, staff needed to see new client messages without refreshing. Polling every five seconds hammered the database and felt sluggish. Moving to broadcasting with private channels cut server load and made the inbox feel instant. The same pattern applies to trek booking dashboards where guide assignments change during the day.

Reverb is not a replacement for every real-time pattern. High-frequency trading ticks, collaborative CRDT editing, or million-connection fan-out still need specialised infrastructure. For typical Laravel SaaS, admin panels, and customer portals, Reverb hits the sweet spot.

How do you install and configure Laravel Reverb for broadcasting?

Start with Laravel 13.x on PHP 8.3 or higher (PHP 8.5 is the current anchor; 8.4 remains common in production). Composer 2.10 and a queue worker are assumed—you will almost always queue broadcasts in production.

Step 1: Install Reverb and publish config

composer require laravel/reverb
php artisan reverb:install
php artisan migrate

The install command adds config/reverb.php, updates .env with Reverb keys, and registers the Reverb service provider. It also prompts for broadcasting configuration.

Step 2: Environment variables

Set these in .env for local development:

BROADCAST_CONNECTION=reverb

REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret
REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

Match config/broadcasting.php—the default Reverb connection reads these values. Never commit real secrets; generate fresh keys per environment.

Step 3: Create a broadcastable event

php artisan make:event OrderStatusUpdated --broadcast

Edit the generated event:

<?php

namespace App\Events;

use App\Models\Order;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class OrderStatusUpdated implements ShouldBroadcast
{
    use Dispatchable, SerializesModels;

    public function __construct(public Order $order) {}

    public function broadcastOn(): array
    {
        return [new PrivateChannel('orders.'.$this->order->user_id)];
    }

    public function broadcastAs(): string
    {
        return 'order.status.updated';
    }

    public function broadcastWith(): array
    {
        return [
            'id' => $this->order->id,
            'status' => $this->order->status,
        ];
    }
}

Dispatch it from a controller or listener:

OrderStatusUpdated::dispatch($order);

Step 4: Define channel authorisation

In routes/channels.php:

use Illuminate\Support\Facades\Broadcast;

Broadcast::channel('orders.{userId}', function ($user, int $userId) {
    return (int) $user->id === $userId;
});

Private and presence channels require this callback. A common mistake is authorising too loosely—always tie channels to authenticated user IDs or team membership, especially on enterprise client portals.

Step 5: Enable broadcasting routes

Ensure bootstrap/app.php (Laravel 13) or your route service provider loads channel routes. Laravel 13 typically includes:

->withBroadcasting(__DIR__.'/../routes/channels.php')

Step 6: Start Reverb and the queue worker

php artisan reverb:start
php artisan queue:work

In production, run both under Supervisor or systemd—not in a foreground terminal. Broadcast events that implement ShouldBroadcast are queued by default; without a worker, nothing reaches Reverb.

Reverb Complete Setup StepsInstallConfigure.env keysEventschannelsEchofrontendRunProduction checklistSupervisor: reverb:start + queue:workNginx reverse proxy with SSL on wss://Redis 8.10 for queue + optional scalingHorizon for queue monitoringDebug with php artisan reverb:restart
End-to-end Laravel Reverb setup: install, configure, authorise channels, wire Echo, then run Reverb with a queue worker.

How do you connect Laravel Echo and Vite to Reverb on the frontend?

Reverb speaks the Pusher protocol, so Laravel Echo with the Pusher client library is the standard front-end stack. Use Node.js 26 LTS and npm 12 locally; production servers often skip Node entirely if you commit built assets—same pattern as Vite config for Laravel projects.

Install JavaScript dependencies

npm install --save-dev laravel-echo pusher-js

In resources/js/bootstrap.js (or your main JS entry):

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 ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
    authEndpoint: '/broadcasting/auth',
    auth: {
        headers: {
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content,
        },
    },
});

Import bootstrap from resources/js/app.js, then build:

npm run build

Subscribe to a private channel

Echo.private(`orders.${userId}`)
    .listen('.order.status.updated', (payload) => {
        console.log('Order updated:', payload);
        updateOrderBadge(payload);
    });

Note the leading dot before the event name when you use broadcastAs(). Without it, Echo listens for the wrong event class name.

Blade + Alpine pattern

For Livewire-heavy apps, you can still use Echo in Alpine components:

<div x-data="notificationListener()" x-init="init()">
    <span x-text="message"></span>
</div>

<script>
function notificationListener() {
    return {
        message: '',
        init() {
            Echo.private(`orders.${this.$el.dataset.userId}`)
                .listen('.order.status.updated', (e) => {
                    this.message = `Order #${e.id} is now ${e.status}`;
                });
        }
    };
}
</script>

If you prefer Livewire’s built-in polling or wire:poll, compare complexity first—broadcasting shines when updates are frequent or latency-sensitive. See Laravel Livewire for beginners for when polling is enough.

Vue integration

On Vue + Laravel stacks, initialise Echo once in app.js and inject it or attach to window.Echo. A composable can wrap channel subscription and cleanup on unmount—critical to avoid duplicate listeners during SPA navigation. The Vue with Laravel setup guide covers the Vite side; add Echo after Sanctum or session auth is wired.

Testing locally

Open two browser sessions: trigger the event from one, confirm the listener fires in the other. Use php artisan tinker to dispatch:

event(new \App\Events\OrderStatusUpdated(\App\Models\Order::first()));

Check Reverb logs in the terminal running reverb:start. If nothing appears, verify the queue worker processed the job and that BROADCAST_CONNECTION is not still set to log or null.

How does Laravel Reverb compare to Pusher, Soketi, and Redis broadcasting?

Pick your WebSocket backend based on ops capacity, budget, and scale—not hype.

OptionHostingProtocolBest forTrade-offs
Laravel ReverbSelf-hosted PHP processPusher-compatibleLaravel 13 teams wanting first-party supportYou manage process supervision, SSL, scaling
PusherManaged SaaSNative PusherFastest launch, minimal DevOpsCost scales with connections/messages
SoketiSelf-hosted NodePusher-compatibleTeams already running Node servicesExtra runtime beside PHP
Redis + socket serverSelf-hostedCustom / Laravel WebSockets legacyExisting Redis 8.10 infraMore moving parts, older packages deprecated

Reverb’s advantage is alignment: same vendor docs, php artisan commands, and upgrade path as the framework. Pusher remains valid when you have zero appetite for WebSocket ops—paying roughly USD 49–299/month (~Rs 6,500–39,000) for managed tiers can be cheaper than engineer time on a small project.

For related background on event-driven design, read modern Laravel architecture best practices and real-time Laravel with Reverb and WebSockets.

Reverb vs Pusher DecisionChoose ReverbOwn Ubuntu serverLaravel-only stackPredictable trafficChoose PusherNo DevOps timeSpiky global scaleManaged SLA neededHybrid patternReverb staging + Pusher prod until SSL readySame Echo code — swap .env driverUse /tools/json-formatter to debug payloads
Decision guide: self-hosted Reverb for Laravel-centric teams; managed Pusher when operations bandwidth is limited.

How do you deploy Laravel Reverb in production on Ubuntu?

In my experience working on production Laravel applications, Reverb fails in production for predictable reasons: no queue worker, wrong REVERB_HOST behind a proxy, or WebSocket connections blocked by Cloudflare orange-cloud settings. Treat Reverb like any long-running service—same discipline as Ubuntu server setup and Linux system administration.

Supervisor configuration

Create /etc/supervisor/conf.d/reverb.conf:

[program:reverb]
process_name=%(program_name)s
command=php /var/www/myapp/current/artisan reverb:start --host=0.0.0.0 --port=8080
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/myapp/shared/storage/logs/reverb.log
stopwaitsecs=3600

Reload Supervisor:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start reverb

Run a separate Supervisor program for queue:work or Laravel Horizon. Use Redis 8.10 as your queue backend for reliability under broadcast bursts.

Nginx reverse proxy with SSL

Terminate TLS at Nginx and proxy WebSocket upgrades to Reverb:

location /app {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 60s;
}

Production .env:

REVERB_HOST=ws.example.com
REVERB_PORT=443
REVERB_SCHEME=https

VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

Rebuild front-end assets after changing Vite variables. A classic post-deploy bug is stale JavaScript still pointing at localhost:8080.

Scaling Reverb horizontally

Reverb supports scaling via Redis pub/sub when multiple Reverb instances share message state. Set in config/reverb.php:

'scaling' => [
    'enabled' => env('REVERB_SCALING_ENABLED', false),
    'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
    'server' => [
        'url' => env('REDIS_URL'),
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'port' => env('REDIS_PORT', '6379'),
    ],
],

Enable only when a single Reverb process becomes a bottleneck—most SMB Laravel apps never need this on day one.

Security hardening

  1. Restrict Reverb port 8080 to localhost; expose only Nginx 443 publicly.
  2. Use strong REVERB_APP_SECRET and rotate on deploy if compromised.
  3. Authorise every private and presence channel in routes/channels.php—never trust client-side channel names alone.
  4. Rate-limit /broadcasting/auth to prevent channel enumeration.
  5. Keep PHP 8.3+ and Laravel 13 patched; Reverb inherits your app’s attack surface.

For API-only backends that also broadcast to mobile clients, align auth with Sanctum tokens—see Laravel API best practices and building RESTful APIs with Laravel.

Production Reverb TopologyClientswss://NginxSSL proxyReverb:8080 localLaravelPHP-FPMSupervisor manages reverb:startQueue worker + Redis 8.10 belowCommon production gotchasStale Vite build, missing queue workerCloudflare blocking WebSocket upgrade
Production Laravel Reverb: Nginx terminates SSL, Supervisor keeps Reverb alive, Laravel dispatches via Redis-backed queues.

Monitoring and debugging

Log Reverb stdout to a dedicated file and ship it to your log aggregator. Watch queue latency—broadcast jobs piling up means users see delayed updates even when WebSockets are healthy. Use php artisan reverb:restart after deploys; pair with PHP-FPM reload for opcache invalidation on the same release cycle I run via Deployer 7.

On client portals with document uploads, I log broadcast payload sizes. Large Eloquent models serialised by mistake can bloat messages—always use broadcastWith() to send only what the UI needs. Validate payloads with the JSON formatter tool during development.

What are advanced Laravel broadcasting patterns with Reverb?

Once basic private channels work, these patterns cover most production apps.

Presence channels for “who is online”

public function broadcastOn(): array
{
    return [new PresenceChannel('chat.'.$this->roomId)];
}

Authorise in routes/channels.php and return user data Echo exposes to .join(), .here(), and .leaving() callbacks.

ShouldBroadcastNow for synchronous push

Implement Illuminate\Contracts\Broadcasting\ShouldBroadcastNow when latency under ~100ms matters and the payload is tiny—admin “payment received” toasts, for example. Default queued broadcasting is safer for DB-heavy serialisation.

Notification broadcasting

Laravel notifications can use the broadcast channel. Combine with Reverb so users see bell icons update without polling—useful on digital commerce dashboards.

Testing with Pest or PHPUnit

use Illuminate\Support\Facades\Event;

Event::fake();

// action that should broadcast

Event::assertDispatched(OrderStatusUpdated::class);

For integration tests, BROADCAST_CONNECTION=log avoids needing a live Reverb process in CI. Switch to reverb only in staging.

Database and performance notes

Broadcasting does not replace database design. If your event loads heavy relationships, fix the query first—PostgreSQL for Laravel developers covers indexing patterns that keep dispatch fast. Pair with testing and optimization before load-testing WebSockets.

For payment status updates after Khalti or Stripe callbacks, broadcast only after the transaction commits—dispatch from a queued listener registered after DB::commit() to prevent ghost notifications.

Key Takeaways

  • Install laravel/reverb, set BROADCAST_CONNECTION=reverb, and run both reverb:start and a queue worker—broadcasts are queued by default.
  • Wire Laravel Echo with Vite env vars; rebuild assets after every production env change to WebSocket host or port.
  • Authorise every private and presence channel in routes/channels.php; use broadcastWith() to limit payload size.
  • Terminate SSL at Nginx, proxy WebSocket upgrades to localhost Reverb, and manage the process with Supervisor.
  • Choose Reverb over Pusher when you already operate Laravel on Ubuntu; choose Pusher when managed ops beats self-hosting cost.
  • Debug with Reverb logs, queue metrics, and Event::fake() in tests— not by leaving BROADCAST_CONNECTION=log in staging.

People Also Ask

Does Laravel Reverb require Pusher?

No. Reverb is a self-hosted WebSocket server that uses the Pusher protocol for compatibility with Laravel Echo. You do not need a Pusher account or API key from Pusher’s SaaS—only the REVERB_APP_* credentials generated during reverb:install.

Can Laravel Reverb run on shared hosting?

Generally no. Shared hosting rarely allows long-running daemons or custom WebSocket ports. You need a VPS or cloud VM where Supervisor can keep reverb:start alive—typical setups start around Rs 1,500/month (~USD 11) for a small DigitalOcean or local Nepali VPS droplet.

Do I need Redis for Laravel Reverb?

Redis is not mandatory for a single-server Reverb install, but you need a queue driver—Redis 8.10 is the practical choice. Redis becomes required when you enable Reverb horizontal scaling or run multiple Reverb nodes behind a load balancer.

Is Laravel 12 supported with Reverb?

Yes. Reverb works on Laravel 12 (PHP 8.2+) and Laravel 13 (PHP 8.3+). Laravel 11 reached end-of-life in March 2026, so plan upgrades before greenfield Reverb work. Official docs live in the Laravel broadcasting documentation.

Ship real-time features with confidence

Laravel Broadcasting with Reverb Complete Setup gives you a maintainable, PHP-native WebSocket stack without renting external realtime infrastructure—provided you treat Reverb as production infrastructure: Supervisor, SSL, queues, and tight channel authorisation. Start with one private channel and a single Echo listener, prove the flow in staging, then expand to presence rooms and notification streams. If you want help wiring Reverb into a booking system, client portal, or custom Laravel application, contact us and we can map the architecture to your hosting reality.

Frequently Asked Questions

Laravel Broadcasting with Reverb sends application events to browsers over WebSockets using Laravel's first-party PHP server. It replaces Pusher or separate Node socket servers while keeping your stack PHP-first.

Reach for Reverb when users need instant updates such as order status, booking confirmations, admin alerts, or upload progress, and polling hammers your database. On a legal-tech portal I built, five-second polling felt sluggish and loaded the server; private channels made the inbox instant. The same pattern suits trek booking dashboards where guide assignments change during the day. Reverb is not for high-frequency trading, collaborative CRDT editing, or million-connection fan-out. For typical Laravel SaaS, admin panels, and customer portals on Laravel 13.x with PHP 8.3+, it hits the sweet spot.

Start on Laravel 13.x with PHP 8.3 or higher and Composer 2.10. Run composer require laravel/reverb, then php artisan reverb:install and php artisan migrate. The install publishes config/reverb.php, updates .env with Reverb keys, and registers the service provider. Set BROADCAST_CONNECTION=reverb plus REVERB_APP_ID, REVERB_APP_KEY, REVERB_APP_SECRET, REVERB_HOST, REVERB_PORT, and REVERB_SCHEME. Mirror those values into VITE_REVERB_* variables for the front end. Create a broadcastable event with php artisan make:event --broadcast, define channel authorisation in routes/channels.php, ensure bootstrap/app.php loads withBroadcasting, then start php artisan reverb:start alongside a queue worker.

For local development, set BROADCAST_CONNECTION=reverb, REVERB_APP_ID, REVERB_APP_KEY, REVERB_APP_SECRET, REVERB_HOST (typically localhost), REVERB_PORT (8080), and REVERB_SCHEME (http). Expose matching front-end values via VITE_REVERB_APP_KEY, VITE_REVERB_HOST, VITE_REVERB_PORT, and VITE_REVERB_SCHEME, often referencing the Reverb variables with interpolation. config/broadcasting.php reads these for the default Reverb connection. Generate fresh keys per environment and never commit real secrets. In production behind Nginx, switch to REVERB_HOST=ws.example.com, REVERB_PORT=443, REVERB_SCHEME=https, rebuild Vite assets, and verify JavaScript no longer points at localhost:8080.

Reverb is self-hosted and free beyond server costs. Managed Pusher tiers run roughly USD 49–299/month (~Rs 6,500–39,000), which can beat engineer time on small projects.

Yes. Events implementing ShouldBroadcast are queued by default. Without php artisan queue:work running, dispatched events never reach Reverb and browsers see no updates.

Install laravel-echo and pusher-js with npm 12 under Node.js 26 LTS. In resources/js/bootstrap.js, import Echo and Pusher, set window.Pusher, then initialise Echo with broadcaster reverb, VITE_REVERB_APP_KEY, wsHost, wsPort, wssPort, forceTLS from VITE_REVERB_SCHEME, enabledTransports ws and wss, authEndpoint /broadcasting/auth, and CSRF headers. Import bootstrap from app.js and run npm run build. Subscribe with Echo.private and listen using a leading dot before broadcastAs event names, for example .order.status.updated. Test by opening two browser sessions and dispatching from php artisan tinker while watching Reverb logs and queue worker output.

The most common causes are a missing queue worker, BROADCAST_CONNECTION still set to log or null, or a queue job that failed silently. ShouldBroadcast events queue by default, so php artisan queue:work must run alongside php artisan reverb:start. If Reverb logs stay quiet after dispatch, confirm the worker processed the job. Locally, dispatch via tinker and check both terminals. Also verify Echo listens with the leading dot when using broadcastAs(), that private channel names match routes/channels.php authorisation, and that VITE_REVERB_* values match your running Reverb host and port after the last npm run build.

Define callbacks in routes/channels.php and ensure Laravel 13 loads them via withBroadcasting in bootstrap/app.php. For private channels, return true only when the authenticated user matches the channel parameter, such as orders.{userId} where user id equals userId. Presence channels need similar strict checks and can return user data Echo exposes to join, here, and leaving callbacks. Echo calls /broadcasting/auth with CSRF headers for subscription approval. A common mistake is authorising too loosely on enterprise client portals. Never trust client-side channel names alone, and rate-limit /broadcasting/auth to reduce channel enumeration attempts.

Reverb is a self-hosted PHP process speaking the Pusher protocol, aligned with Laravel 13 docs and artisan commands but requiring you to manage supervision, SSL, and scaling. Pusher is managed SaaS with fastest launch and minimal DevOps, but cost scales with connections and messages. Soketi is self-hosted Node, Pusher-compatible, suited to teams already running Node beside PHP. Redis plus a legacy socket server fits existing Redis 8.10 infrastructure but adds moving parts and older packages are deprecated. Pick based on ops capacity and budget: self-hosted Reverb for Laravel-centric teams, managed Pusher when operations bandwidth is limited.

Run Reverb and queue:work under Supervisor or systemd, not a foreground terminal. Create a Supervisor program pointing to php artisan reverb:start --host=0.0.0.0 --port=8080 as www-data, with logs in storage/logs/reverb.log. Use Redis 8.10 as the queue backend for broadcast bursts. Terminate TLS at Nginx, proxy WebSocket upgrades on location /app to 127.0.0.1:8080 with Upgrade and Connection headers, set production REVERB_HOST, PORT 443, SCHEME https, rebuild assets, and restrict port 8080 to localhost. After deploys, run php artisan reverb:restart and reload PHP-FPM for opcache, the same release cycle I use with Deployer 7.

Terminate SSL at Nginx and proxy WebSocket traffic to the Reverb process on 127.0.0.1:8080. A typical location /app block sets proxy_pass to the Reverb port, proxy_http_version 1.1, Upgrade and Connection Upgrade headers, Host, X-Real-IP, and proxy_read_timeout around 60 seconds. Keep Reverb bound internally while only Nginx port 443 is public. Update production .env so REVERB_HOST matches your public WebSocket hostname, REVERB_PORT is 443, REVERB_SCHEME is https, and VITE_REVERB_* mirrors those values. Rebuild front-end assets after changing Vite variables. Stale JavaScript still pointing at localhost:8080 is a classic post-deploy bug behind proxies or Cloudflare.

Enable scaling in config/reverb.php when a single Reverb process becomes a bottleneck. Set scaling enabled via REVERB_SCALING_ENABLED, define a channel such as reverb, and point the server block at your Redis URL, host, and port. Multiple Reverb instances then share message state through Redis pub/sub. Most SMB Laravel apps never need this on day one. Enable it only after monitoring shows one process cannot keep up with connection or message volume. Pair horizontal Reverb scaling with Redis 8.10 as your queue backend so broadcast jobs and WebSocket fan-out both stay reliable under load spikes.

In production, Reverb fails for predictable reasons: no queue worker, wrong REVERB_HOST behind a proxy, or WebSocket connections blocked by Cloudflare orange-cloud settings. Treat Reverb like any long-running service with the same discipline as other Ubuntu services. Watch queue latency because broadcast jobs piling up delay updates even when WebSockets look healthy. Log Reverb stdout to a dedicated file and monitor payload sizes; large Eloquent models serialised by mistake bloat messages, so always use broadcastWith() for only what the UI needs. After deploys, run php artisan reverb:restart. Validate JSON payloads during development before shipping to client portals with document uploads.

Restrict Reverb port 8080 to localhost and expose only Nginx 443 publicly. Use strong REVERB_APP_SECRET values and rotate them if compromised. Authorise every private and presence channel in routes/channels.php, tying subscriptions to authenticated user IDs or team membership. Rate-limit /broadcasting/auth to prevent channel enumeration. Keep PHP 8.3+ and Laravel 13 patched because Reverb inherits your application attack surface. For API backends broadcasting to mobile clients, align auth with Sanctum tokens. Never commit real keys to version control, and generate fresh credentials per environment rather than reusing development secrets in production.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: