
August 18, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Your users expect live updates, but polling adds latency and server load. A laravel reverb websocket stack solves that by pushing events from your app to browsers over a persistent connection. Laravel Reverb is the first-party WebSocket server for Laravel 13.x. It replaces paid SaaS drivers and separate Node.js daemons while staying compatible with Laravel Echo and the Pusher protocol. If you run Laravel applications in production, Reverb is now the default path for chat, notifications, booking status, and dashboard counters.
composer require laravel/reverb, sets BROADCAST_CONNECTION=reverb, runs php artisan reverb:start behind Nginx with WSS on port 443, and connects the browser through Laravel Echo with Vite environment variables.This guide walks through install, frontend wiring, production deployment, scaling, and debugging. It assumes PHP 8.3 or higher, Laravel 12 or 13, and a reverse proxy you control. For broader backend context, see my notes on building SaaS products with Laravel in Nepal and when real-time features belong in the MVP versus a later phase.
How do you install and configure Laravel Reverb for WebSocket broadcasting?
Reverb ships as a Composer package and hooks into Laravel's existing broadcasting layer. You do not rewrite event classes or channel definitions when moving from Pusher. The install command publishes config and environment keys in one step.
Backend install steps
- Require the package:
composer require laravel/reverbusing Composer 2.10 on PHP 8.3 or higher. - Run the installer:
php artisan reverb:install. This publishesconfig/reverb.php, updatesconfig/broadcasting.php, and adds keys to.env. - Set the driver:
BROADCAST_CONNECTION=reverbin.env. - Create a broadcastable event that implements
ShouldBroadcastand dispatch it from a controller, job, or observer. - Start the server locally:
php artisan reverb:start. Production uses Supervisor instead of a terminal session.
# .env — backend Reverb settings
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret
REVERB_HOST=0.0.0.0
REVERB_PORT=8080
REVERB_SCHEME=http
# Vite exposes these to the browser bundle
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="ws.example.com"
VITE_REVERB_PORT="443"
VITE_REVERB_SCHEME="https" Bind REVERB_HOST to 0.0.0.0 on the server, not localhost. Localhost accepts only loopback traffic and breaks connections through Nginx. Treat REVERB_APP_SECRET like any API secret. Never commit it to Git.
Define channels in routes/channels.php. Public channels need no auth. Private and presence channels call /broadcasting/auth before Reverb accepts the subscription. That endpoint must share session cookies with your main app domain or subdomain.
Official docs live at Laravel Broadcasting and the Reverb server documentation. Read both before changing production config.
How does Laravel Reverb compare to Pusher and Socket.io?
Reverb is not the only option. Pusher remains the fastest path if you want zero ops. Socket.io fits teams already running Node.js. For most Laravel shops, Reverb hits the sweet spot between cost and control.
| Criteria | Laravel Reverb | Pusher | Socket.io (Node) |
|---|---|---|---|
| Monthly cost | Self-hosted (Rs 0 beyond VPS) | USD subscription tiers | Self-hosted |
| Laravel integration | Native driver, same events | Native driver | Custom bridge required |
| Protocol | Pusher-compatible | Pusher proprietary | Socket.io protocol |
| Data residency | Your server, your region | Vendor regions only | Your server |
| Ops burden | Supervisor + Nginx + Redis at scale | None | Node cluster + adapter |
| Frontend client | Laravel Echo + pusher-js | Laravel Echo + pusher-js | socket.io-client |
Reverb speaks the Pusher protocol. Switch drivers by changing BROADCAST_CONNECTION and env keys. Frontend Echo config stays the same. That matters when you prototype on Pusher and move to self-hosted Reverb later.
For legal-tech and client portals, keeping WebSocket traffic on your own VPS is often a hard requirement. SaaS broadcasters may not meet data-handling policies. On booking systems like those I have shipped with Livewire, live seat counts and status badges are low-risk wins for Reverb. See Adventure Third Pole Trek for the kind of operational dashboard that benefits from push updates.
If you only need one-way server pushes without bidirectional chat, read Server-Sent Events versus WebSockets before committing to a full WebSocket stack.
How do you connect Laravel Echo and Vite to Reverb?
The browser side defines whether real-time features feel instant or broken. Laravel Echo is the official client. Vite 8.x bundles it in modern Laravel apps. Reverb still requires pusher-js because it implements the Pusher wire format.
Frontend setup checklist
- Install packages:
npm install laravel-echo pusher-jsusing npm 12 with Node.js 26 LTS. - Create
resources/js/echo.jsand import it fromresources/js/app.jsbefore any channel subscriptions. - Match
VITE_REVERB_*values to your public WebSocket hostname, not the internal server IP. - Use
wsson port 443 in production so corporate firewalls do not block the connection. - Test with a public channel first, then private channels that hit
/broadcasting/auth.
// 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 ?? 8080,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
// Subscribe example
Echo.channel('orders')
.listen('OrderStatusUpdated', (e) => {
console.log(e.orderId, e.status);
}); During local dev, Vite serves assets on port 5173 while Reverb listens on 8080. Add the Vite origin to config/cors.php if auth requests fail. In production, serve the app and WebSocket under the same registrable domain. A subdomain like ws.example.com works when cookies use .example.com.
Blade-only apps can load Echo from Vite without a SPA framework. Livewire can react to Echo events in Alpine listeners. For heavier client state, compare Livewire 3 versus Inertia and Vue with Laravel before adding a second frontend architecture.
Validate event payloads with a JSON formatter when debugging shape mismatches between PHP and JavaScript.
How do you deploy and scale Laravel Reverb in production?
Running Reverb in a SSH session is fine for local work. Production needs a process supervisor, TLS, and a plan for restarts after deploy. I use Supervisor on Ubuntu 22 or 24 with Nginx in front, the same pattern as deploying Laravel on Ubuntu with Nginx.
Supervisor unit
[program:reverb]
process_name=%(program_name)s
command=php /var/www/current/artisan reverb:start --host=0.0.0.0 --port=8080
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/reverb.log
stopwaitsecs=3600 Reload Supervisor after deploy: sudo supervisorctl reread && sudo supervisorctl update. Pair this with zero-downtime Deployer releases so PHP-FPM and Reverb restart in the right order.
Nginx WebSocket proxy
server {
listen 443 ssl http2;
server_name ws.example.com;
location / {
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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
} Long proxy_read_timeout values prevent idle chat connections from dropping at the proxy layer. See Nginx reverse proxy setup for TLS certificate basics with Certbot.
Horizontal scaling needs Redis 8.10 pub/sub so every Reverb node receives the same broadcast. Enable scaling in config/reverb.php under servers.reverb.scaling. The Redis footprint overlaps with queue workers. Read scaling Laravel queues for high traffic and Redis queue production setup before sizing one Redis instance for both jobs and Reverb.
Multi-server Laravel apps also need shared sessions for private channel auth. Review Laravel session config for multi-server and Redis caching patterns so auth cookies resolve on every node.
Need help sizing infrastructure for real-time features? Enterprise application development services cover architecture, deploy pipelines, and production hardening for Laravel stacks in Nepal and abroad.
What causes WebSocket connection failures with Laravel Reverb?
Real-time bugs fail quietly. The browser console shows "WebSocket closed" without naming the root cause. A fixed checklist saves hours on client projects.
Diagnostic workflow
- Confirm Reverb is listening:
ss -tulpn | grep 8080on the server. If empty, check Supervisor status and UFW rules. - Test outside the browser with
wscat -c wss://ws.example.com/app/your-key. This isolates TLS and proxy issues from JavaScript bugs. - Inspect the Network tab for failed
/broadcasting/authresponses on private channels. 403 usually means session or channel policy mismatch. - Compare
VITE_REVERB_*build-time values to the hostname users actually load. Stale assets after deploy are a common miss. - Read
/var/log/reverb.logandstorage/logs/laravel.logtogether. Reverb logs connections; Laravel logs broadcast exceptions.
Always terminate TLS at Nginx and expose WSS on port 443. Many ISPs and office networks in Nepal block non-standard ports. Port 443 looks like normal HTTPS traffic and passes through most filters.
Queue synchronous broadcasts during heavy traffic. Use ShouldBroadcastNow only when latency demands it. Otherwise let ShouldBroadcast events run through your queue worker so HTTP requests stay fast. Follow patterns in building real-time Laravel features with Redis and realtime APIs with Reverb for event design.
Isolate payment webhooks from broadcast routes. Callback URLs and WebSocket paths should not share fragile middleware stacks. See Laravel payment integrations for route and CSRF boundaries with Khalti, eSewa, and Stripe.
Harden auth endpoints per OWASP practices for Laravel. Rate-limit /broadcasting/auth if bots probe channel names. Run through the Laravel production deployment checklist before go-live.
The Pusher protocol spec is documented at Pusher channel authentication. Reverb follows the same signing rules for private channels.
Key Takeaways
- Install Reverb with
composer require laravel/reverband setBROADCAST_CONNECTION=reverbon Laravel 12 or 13 with PHP 8.3+. - Terminate WSS on port 443 through Nginx; bind Reverb to
0.0.0.0internally and never expose raw port 8080 publicly. - Wire Laravel Echo with
pusher-jsand matchingVITE_REVERB_*variables built through Vite 8.x. - Run Reverb under Supervisor, restart after deploy, and add Redis pub/sub before adding a second Reverb node.
- Debug from server port → proxy headers → Vite env →
/broadcasting/authin that order. - Start with public channels in staging; add private channels only after session and cookie domains are correct.
People Also Ask
Does Laravel Reverb require Pusher subscription?
No. Reverb is self-hosted and free to run on your own hardware. You still install pusher-js on the frontend because Reverb implements the Pusher wire protocol. Laravel Echo talks to Reverb through that client library without a Pusher account.
Can Laravel Reverb run on shared hosting?
Generally no. Reverb is a long-running WebSocket process. Shared hosting blocks persistent daemons and custom ports. You need a VPS or cloud instance with Supervisor, plus Nginx for WSS proxying.
What is the difference between Reverb and Laravel Echo?
Reverb is the server that maintains WebSocket connections and delivers events. Laravel Echo is the JavaScript client that subscribes to channels in the browser. Your Laravel app broadcasts events; Reverb pushes them; Echo receives them.
Do I need Redis for a single-server Reverb setup?
Not for basic use on one machine. Redis becomes required when you run multiple Reverb instances or need pub/sub sync across nodes. Many teams already run Redis for queues and cache, so enabling Reverb scaling reuses existing infrastructure.
Ship real-time Laravel without vendor lock-in
A production laravel reverb websocket stack gives you native broadcasting, Pusher-compatible clients, and full data control on your own VPS. Start with one Supervisor-managed node, validate WSS early, and scale with Redis only when connection counts justify it. The payoff shows up fast in booking dashboards, order tracking, and client portals where stale pages erode trust.
For architecture review, deploy automation, or troubleshooting an existing WebSocket setup, contact me or explore web development services to plan your real-time rollout.
Frequently Asked Questions
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.

