[ GUIDE ]

Monitoring Laravel Reverb

WebSocket servers don't fit the request-response APM model. Here's what to actually watch for Reverb in production.

QUICK ANSWER

How do I monitor Laravel Reverb in production?

Track four signals: active WebSocket connections, broadcast throughput, memory per worker, and broadcast failure rate. Reverb exposes a /stats endpoint for Prometheus scraping. Memory growth over time is the leak signal worth watching — Reverb workers are long-running ReactPHP processes. NightOwl captures broadcast events at dispatch time; full Reverb-worker instrumentation is not yet first-class, pair with Prometheus + Grafana for now.

Updated · 2026-04-13

Why Reverb doesn't fit normal APM

Reverb is a long-running ReactPHP process serving WebSocket connections. It doesn't handle HTTP requests in the usual sense. APMs that record per-request telemetry see the HTTP-side broadcast dispatches (when your Laravel app calls broadcast()) but not the WebSocket-side message delivery, connections, or per-client state.

You need two layers:

  • HTTP side (dispatch) — your normal APM catches broadcast() calls and their context
  • Reverb worker side (delivery) — process-level monitoring: memory, connections, throughput, errors

Reverb's built-in /stats endpoint

config/reverb.php

php
'apps' => [
    [
        'app_id' => env('REVERB_APP_ID'),
        'key' => env('REVERB_APP_KEY'),
        'secret' => env('REVERB_APP_SECRET'),
        // Enable the stats endpoint
        'path' => '',
    ],
],

// Scrape stats via HTTP:
//   GET /apps/{app_id}/stats?auth_key=...&auth_signature=...

Returns JSON with active connections, messages sent, memory, channels subscribed. Prometheus-scrape this or forward to your APM periodically.

Detecting memory leaks

Reverb workers are long-lived. Leaks accumulate slowly until the process OOMs or degrades:

Supervisor config with memory cap

ini
[program:reverb]
process_name=%(program_name)s
command=php /home/forge/app.com/artisan reverb:start
autostart=true
autorestart=true
user=forge
stdout_logfile=/home/forge/.forge/reverb.log
stopwaitsecs=3600
; Kill + restart if memory exceeds 512MB
; Supervisor doesn't enforce memory directly; use a wrapper script
; or a Prometheus alert + manual restart.

Alternative: run Reverb with --max-requests=N if supported in your Reverb version, or use a cron that restarts the process nightly as a leak safety net.

Tracking broadcast dispatch from Laravel

The HTTP-side of broadcasting fires Laravel events you can hook:

app/Providers/EventServiceProvider.php

php
use Illuminate\Broadcasting\BroadcastEvent;
use Illuminate\Support\Facades\Event;

Event::listen(function (BroadcastEvent $event) {
    logger()->info('Broadcasting', [
        'event' => get_class($event->event),
        'channels' => $event->channels,
    ]);
});

Scaling Reverb horizontally

Multiple Reverb processes coordinate via Redis pub/sub. Monitor both:

  • Redis pub/sub channel subscribers (should match Reverb process count)
  • Redis memory (Reverb's in-flight message buffer lives here)
  • Per-process connection distribution (load balancer should spread evenly)

Alerting thresholds

Signal Alert threshold
Active connections per process> 80% of max_connections
Memory per process> 2x baseline, sustained 1h
Broadcast error rate> 1%
Worker crashesany, investigate
Connection reset spikes> 3x baseline

RELATED

Frequently asked questions

What is Laravel Reverb?

Reverb is the official first-party WebSocket server for Laravel broadcasting, launched in 2024. It's a drop-in replacement for Pusher / Soketi — same protocol, Laravel-native code, runs on ReactPHP. Scales horizontally across multiple servers via Redis pub/sub.

What do I need to monitor for Laravel Reverb?

Four things: (1) active WebSocket connection count — capacity planning, (2) message throughput (broadcasts per second) — load signal, (3) memory per Reverb process — detect leaks early, (4) broadcast failure rate — events that didn't reach subscribers. Reverb exposes metrics via its Prometheus exporter or internal event hooks.

How do I track WebSocket connections in Laravel?

Reverb exposes /reverb/stats (protected by your app key) with active connection count per channel, total messages sent, and memory usage. Scrape it with Prometheus or any metrics collector. For per-user connection tracking, listen to ConnectionOpened / ConnectionClosed events in a Reverb event handler.

How do I detect Reverb memory leaks?

Reverb workers are long-running ReactPHP processes, so leaks accumulate. Graph memory_get_usage per process over time — stable workers hover around a baseline; leaky ones drift upward. Common leak sources: unbounded subscriber storage, event listeners not detaching, closures holding references. Set max_memory in supervisor config so leaking workers recycle before OOM.

How is monitoring Reverb different from monitoring a normal Laravel app?

Two ways. First, Reverb workers don't serve HTTP requests — request-oriented APMs don't surface their activity. You need process-level monitoring (memory, CPU, connections). Second, broadcasts don't fit the request-response model — success means the message reached the subscriber's WebSocket, not a 200 status. Failure detection requires instrumenting the broadcast side (broadcast rejection, connection drops).

Does NightOwl support Laravel Reverb?

Partially. NightOwl captures broadcast events fired from the Laravel HTTP app (the source of broadcasts) — those show up as requests or events with context. Reverb's WebSocket worker is a separate process and NightOwl doesn't instrument it directly today. Pair with Prometheus + Grafana for Reverb-side visibility until first-class Reverb support ships.

What alerts should I set for Reverb in production?

Alert on: (1) connection count approaching capacity (max_connections per worker), (2) sustained memory growth over 1-hour window, (3) broadcast error rate > 1%, (4) worker crash rate > 0, (5) connection reset spikes (indicates client-side or network issues). Pair with uptime checks against the WebSocket endpoint.

PRICING

Flat pricing. No event caps. No per-seat fees.

14-day free trial, no credit card. Your PostgreSQL, your data.

HOBBY

$5 /month

1 app · 14 days lookback · all Laravel events

TEAM

$15 /month

Up to 3 connected apps · unlimited environments · all Laravel events

AGENCY

$69 /month

Unlimited apps · unlimited agent instances · same flat rate at any traffic

Related