laravel/reverb
Laravel Reverb is a first-party WebSocket server that brings real-time communication to Laravel apps. It integrates with Laravel broadcasting, supports horizontal scaling via Redis, and can replace external services like Pusher.
Architecture fit. Reverb is a first-party, MIT-licensed WebSocket server that speaks the Pusher wire protocol and is consumed through Laravel's existing broadcasting abstraction. For any application already on Laravel's broadcasting system with Echo on the client, it is a configuration-level substitution rather than an architectural change: the broadcaster driver, channel authorization, and client library (pusher-js) all remain the same. The material architectural difference is that Reverb runs as a long-lived, stateful process outside the request lifecycle (php artisan reverb:start). That introduces a new deployable unit with its own port, its own process supervisor, its own TLS/upgrade-handling reverse proxy, and its own scaling topology. Teams whose operational model is strictly "PHP-FPM behind Nginx, deploy = replace code" are adding a genuinely new class of workload, not just a package.
Integration feasibility. High. Installation is scaffolded (reverb:install) and configuration is environment-driven (REVERB_APP_ID/KEY/SECRET, host/port, allowed origins, REVERB_SCALING_ENABLED). Private and presence channel authorization reuses Laravel's broadcasting auth routes, so existing authorization logic carries over. Frontend change is limited to the Echo connection block. Because the protocol is Pusher-compatible, there is a credible rollback path back to a managed provider, which materially de-risks the decision.
Technical risk.
toOthers via socket-id propagation only landed in v1.11.0, and rate limiting (v1.9.0) and per-app connection limits (v1.6.0) are also recent. These are exactly the controls a production rollout depends on, so pinning to a current 1.11.x is non-negotiable.Key questions for the team.
Stack fit. Requires a Laravel application on a version supported by the installed Reverb release (Laravel 12 and 13 are both covered per changelog; PHP 8.4/8.5 are in the test matrix). Production topology: reverse proxy terminating TLS and forwarding WebSocket upgrades → one or more reverb:start processes under Supervisor/systemd → Redis pub/sub when more than one node. Client: Echo + pusher-js. Reverb is independent of Octane; it does not require or conflict with it.
Migration path. Treat it as a phased provider swap, not a rewrite.
pusher-js unchanged.Compatibility. Confirm: application Laravel/PHP version against the pinned Reverb minor; whether a path-prefixed server URL is needed behind the proxy (supported since v1.4.7); allowed-origins configuration for every first-party and partner origin, including wildcard subdomains if used; and whether any consuming client is a non-pusher-js SDK whose protocol assumptions we have not tested.
Sequencing.
Maintenance. Actively maintained first-party package with a frequent minor cadence, Dependabot automation, and a published security policy — low ongoing engineering cost, but non-zero release-tracking cost. Upgrades require process restarts, which means every upgrade is a visible client-reconnect event; treat upgrades as scheduled changes with a maintenance note, and use the reload command rather than a hard kill where possible. Because minors ship frequently, pin and upgrade deliberately rather than floating.
Support. MIT with community plus Laravel-maintainer involvement; there is no commercial SLA attached to the package itself. Escalation is GitHub issues. If real-time is revenue-critical, that gap must be explicitly accepted by the business or backstopped by commercial Laravel support.
Scaling. Start vertical: the event loop is effectively single-core, so a single node's ceiling is bounded by one CPU and by per-connection memory — measure RSS per connection rather than assuming published benchmarks. Horizontal scale is Redis pub/sub, which removes the need for sticky sessions but makes Redis a single point of failure for cross-node delivery and presence coherence. Capacity plan on: connections × memory, messages/sec × fan-out, and presence channel size. Enable the per-app connection limit and rate limiting as guardrails before launch, not after the first incident.
Failure modes to instrument. Process crash → supervisor restart → mass reconnect thundering herd (verify client backoff and jitter); Redis outage → cross-node delivery and presence break while single-node traffic may still work; deploy/restart → connection drop, requiring client-side state reconciliation over HTTP; slow memory growth over multi-day uptime → planned recycling; proxy stripping Upgrade → silent degradation or 400s with no application-level error; origin/signature mismatch → connection refused with a confusing client-side message; abusive clients → mitigated only if rate limiting and payload validation are configured. Note the absence of any replay/persistence layer as a designed limitation: the product must tolerate lost in-flight messages and recover state on reconnect.
Ramp-up. Expect roughly one to two weeks for a mid-level Laravel team to reach production confidence, dominated by the ops work (supervisor, proxy upgrade handling, Redis scaling, observability) rather than the application integration. Add explicit load-testing time before committing to a peak-connection SLO. The primary skill gap to close is operating stateful PHP processes with graceful restarts — that is the capability that determines whether this succeeds, more than any property of the package.
How can I help you explore Laravel packages today?