// back_to_blog Laravel

Laravel Reverb: Realtime Without Leaving the Laravel Stack

Jul 17, 2026 · 4 min read · 3 tags
Laravel Reverb: Realtime Without Leaving the Laravel Stack

The old gap

If you have built Laravel apps for a while, you know the pattern: broadcasting existed, but the websocket server was often Pusher, Soketi, or a custom Node process. That worked. It also meant another moving part to deploy and monitor.

What Reverb is

Laravel Reverb is a first-party WebSocket server that speaks the Pusher protocol and plugs into Laravel Echo. For notifications, presence channels, live dashboards, and “something changed—refresh this panel” UX, it is enough for many products I ship. Product page: reverb.laravel.com.

Step 1 — Install broadcasting (includes Reverb)

On modern Laravel (11+ / 13), install with:

php artisan install:broadcasting

Behind the scenes this runs Reverb setup with sensible defaults (publishes config, sets env keys, wires broadcasting). Prefer the official docs for your exact Laravel version if the prompt options change.

Step 2 — Environment

After install you should have values similar to:

BROADCAST_CONNECTION=reverb

REVERB_APP_ID=...
REVERB_APP_KEY=...
REVERB_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}"

In production, REVERB_HOST / scheme / port should match what the browser uses (often your public domain on 443 behind a reverse proxy), while the Reverb process may listen on an internal port like 8080.

Step 3 — Start Reverb locally

php artisan reverb:start

Default listen is typically 0.0.0.0:8080. After code/config changes in a long-running process, use php artisan reverb:restart so connections drain cleanly (especially under Supervisor).

Step 4 — Broadcast an event

php artisan make:event OrderShipped --queued

Implement ShouldBroadcast (or ShouldBroadcastNow for immediate), define broadcastOn() channels, then event(new OrderShipped($order));. Keep a queue worker running if events are queued—silent “nothing broadcasts” is often a queue problem, not a websocket problem.

Step 5 — Echo on the frontend

With Vite + Laravel Echo configured for Reverb (install scaffolding usually sets this up), subscribe in JS:

Echo.private(`orders.${orderId}`)
  .listen('OrderShipped', (e) => {
    console.log(e);
  });

Authorize private/presence channels in routes/channels.php.

Production checklist

  • Run Reverb under Supervisor/systemd as a supervised long-running process
  • Reverse proxy WebSockets; Reverb expects traffic for /app (WS) and /apps (API) when proxied—see the Nginx examples in the official docs
  • Use TLS at the edge (REVERB_SCHEME=https, port 443 publicly)
  • Scale horizontally with Redis pub/sub when one server is not enough (documented scaling section)
  • Monitor connection counts; default event loops have practical connection limits—read the docs before assuming “unlimited”

Where I still respect Node

Large chat platforms, collaborative editors, game sockets, or teams already deep in Socket.io may still want a dedicated Node realtime service. Reverb is a credible first-party answer for common Laravel realtime needs—not a claim that Node stopped existing.

Troubleshooting (the failures I actually see)

  • Events never arrive: queued broadcast but no queue:work process; or ShouldBroadcastNow expected but not used.
  • Echo connects then dies in production: reverse proxy missing WebSocket upgrade headers; or public REVERB_HOST/SCHEME still point at localhost.
  • Private channel 403: routes/channels.php authorization fails; user not authenticated to the broadcasting auth endpoint.
  • Works locally, fails on HTTPS site: mixed content—page is https but Echo tries ws://.
  • Config changed but behavior did not: long-running Reverb process needs reverb:restart.

Minimal Nginx sketch (conceptual)

Proxy /app and /apps to the internal Reverb port and enable WebSocket upgrade headers. Copy the exact snippet from the current Reverb production docs for your Nginx version—proxy snippets go stale if you invent them from memory.

Supervisor sketch

[program:reverb]
command=php /var/www/app/artisan reverb:start
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/reverb.log

Adjust user/paths to your server. Pair with a queue worker program similarly.

When Reverb is the wrong tool

If the product is the realtime layer—thousands of rooms, custom binary protocols, game ticks—I evaluate dedicated Node (or other) infrastructure honestly. Reverb shines when Laravel already owns the domain and you need broadcasts, presence, and notifications without leaving the ecosystem.

Security notes for channels

Never put secrets in broadcast payloads the browser should not see. Authorize private channels every time. Treat presence channel data as public to everyone in the room.

Enjoyed this article?

Explore more posts or get in touch about a project.