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.

Real-Time Laravel with Reverb and WebSockets

By Kokil Thapa | Last reviewed: August 2026

Implementing Real-Time Laravel with Reverb and WebSockets has fundamentally changed how we build interactive applications in the PHP ecosystem. For years, developers relied on external services like Pusher or complex Node.js setups, but Laravel Reverb now provides a first-party, high-performance WebSocket server directly within your application stack. This shift eliminates vendor lock-in and reduces latency for features like live notifications, chat systems, and dashboard updates.

If you are evaluating whether to adopt this for a client project or internal tool, understanding the architectural trade-offs is essential before writing code. I recently outlined broader backend considerations in my guide on hiring and working with Laravel developers in Nepal, where real-time capability is increasingly a baseline expectation for legal-tech portals and eCommerce platforms. Reverb fits squarely into modern stacks running Laravel 12.x and PHP 8.4, removing the friction that previously made WebSockets a "nice-to-have" rather than a standard feature.

How do you install and configure Real-Time Laravel with Reverb and WebSockets?

Setting up Reverb in a fresh Laravel 12 application is straightforward, but production readiness requires specific attention to environment configuration. Unlike previous community-driven packages, Reverb is officially maintained and integrates directly with Laravel's broadcasting system.

Installation Steps

  1. Install the package: Run composer require laravel/reverb. This pulls in the ReactPHP-based WebSocket server and all necessary dependencies.
  2. Publish configuration: Execute php artisan reverb:install. This command publishes the config/reverb.php file, adds the required environment variables to your .env, and sets up the broadcasting configuration automatically.
  3. Verify environment variables: Ensure your .env contains the correct keys. In 2026, the default port is typically 8080, but you should verify this against your firewall rules.
<!-- .env Configuration Example -->
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=your-app-id
REVERB_APP_KEY=your-app-key
REVERB_APP_SECRET=your-app-secret
REVERB_HOST="0.0.0.0"
REVERB_PORT=8080
REVERB_SCHEME=http

<!-- Frontend Vite Variables -->
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="ws.yourdomain.com"
VITE_REVERB_PORT="443"
VITE_REVERB_SCHEME="wss"

A common mistake I see on client projects is leaving REVERB_HOST as localhost. While fine for local development, production servers must bind to 0.0.0.0 to accept external connections through your reverse proxy. Always treat these credentials as secrets; never commit them to version control.

Browser ClientLaravel Echo + ViteWSS ConnectionNginx Reverse ProxySSL TerminationPort 443 → 8080Laravel ReverbWebSocket ServerPHP 8.4 + Event LoopReal-Time Laravel with Reverb and WebSockets Architecture
Data flow for Real-Time Laravel with Reverb and WebSockets showing SSL termination at the proxy layer

How does Reverb compare to Pusher and Socket.io for Laravel applications?

Choosing the right broadcasting driver depends on budget, compliance, and operational complexity. While Pusher remains popular for its zero-maintenance API, Reverb offers distinct advantages for teams managing their own infrastructure, particularly in regions like Nepal where data sovereignty or recurring USD costs are concerns.

FeatureLaravel ReverbPusherSocket.io (Node)
Cost ModelFree (Self-hosted)Monthly subscription (USD)Free (Self-hosted)
Data ResidencyFull control (Local/NP)US/EU/AU Regions onlyFull control
IntegrationNative Laravel BroadcastingNative Laravel BroadcastingRequires custom adapter
ProtocolPusher Protocol CompatibleProprietary / PusherSocket.io Protocol
Scaling ComplexityModerate (Redis Pub/Sub)None (Managed)High (Custom clustering)
Ecosystem FitPHP/Laravel NativeSaaS DependencySeparate Node Runtime

In practice, Reverb wins for most Laravel shops because it speaks the Pusher protocol. This means you can switch drivers by changing a single environment variable without rewriting frontend code. For legal-tech platforms handling sensitive client documents, keeping traffic on-premise is often a non-negotiable requirement that SaaS providers cannot meet. If you are building a SaaS product yourself, my article on why Laravel is ideal for SaaS in Nepal covers similar cost-benefit analyses for infrastructure decisions.

How do you integrate Laravel Echo with Vite and Reverb?

The frontend experience defines whether your real-time features feel responsive or broken. Laravel Echo is the official client library, and in 2026, it pairs exclusively with Vite for asset bundling. Getting the handshake right between Vite's dev server and Reverb's WebSocket endpoint prevents the most common debugging headaches.

Frontend Setup Checklist

  • Install dependencies: npm install --save-dev laravel-echo pusher-js. Even though you use Reverb, the pusher-js library is required because Reverb implements the Pusher protocol.
  • Configure Echo: Create or update resources/js/echo.js. Point the key and wsHost to your Vite environment variables.
  • Import in app.js: Ensure Echo is initialized before any component attempts to subscribe to channels.
// 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'],
});

During local development, Vite runs on port 5173 while Reverb runs on 8080. Cross-origin issues are common here. Ensure your config/cors.php allows the Vite dev server origin. In production, serving both the app and WebSocket traffic through the same domain (via subdomain or path) eliminates CORS entirely and simplifies cookie-based authentication for private channels.

BrowserReverb ServerLaravel App1. Subscribe Private Channel2. POST /broadcasting/auth3. Return Auth Signature4. Confirm Subscription5. Broadcast Event Payload6. Push Message to Client
Private channel authentication sequence for Real-Time Laravel with Reverb and WebSockets

How do you deploy and scale Reverb in production environments?

Running php artisan reverb:start in a terminal is not a production strategy. Reverb is a long-running process that must be managed by a process supervisor and protected behind a reverse proxy. On Ubuntu 24.04 servers, Supervisor and Nginx remain the standard combination for reliability.

Supervisor Configuration

Create a configuration file at /etc/supervisor/conf.d/reverb.conf. This ensures the WebSocket server restarts automatically after crashes or deployments.

[program:reverb]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/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

Nginx Reverse Proxy for WSS

WebSockets require persistent connections. Your Nginx config must explicitly upgrade HTTP requests to WebSocket protocol. Without these headers, clients will fail to connect or drop intermittently.

server {
    listen 443 ssl http2;
    server_name ws.yourdomain.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;
        
        # Critical for WebSocket stability
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
}

For high-traffic applications, horizontal scaling requires Redis Pub/Sub. When running multiple Reverb instances across different servers, Redis acts as the message bus to synchronize events. Enable this in config/reverb.php under the servers.reverb.scaling array. I've detailed similar scaling patterns in scaling Laravel queues for high traffic, as the Redis infrastructure overlaps significantly.

Load Balancer / NginxReverb Node APHP 8.4 WorkerReverb Node BPHP 8.4 WorkerReverb Node CPHP 8.4 WorkerRedis Pub/Sub ClusterMessage Synchronization Bus
Horizontal scaling topology for Real-Time Laravel with Reverb and WebSockets using Redis synchronization

What are common debugging strategies for WebSocket connection failures?

Even with perfect configuration, real-time systems fail silently. Browser consoles show generic "connection closed" errors that hide the root cause. After debugging dozens of production deployments, I rely on a systematic checklist to isolate issues quickly.

Diagnostic Workflow

  1. Verify the server is listening: Run sudo netstat -tulpn | grep 8080 on the server. If nothing appears, Supervisor may have crashed or the port is blocked by UFW.
  2. Test raw connectivity: Use wscat -c wss://ws.yourdomain.com/app/your-key from an external machine. This bypasses browser-specific issues and confirms SSL/proxy configuration.
  3. Check CORS and headers: Inspect the Network tab in DevTools. Failed handshakes often return 403 or 400 status codes before the upgrade occurs. Verify Access-Control-Allow-Origin matches your frontend domain exactly.
  4. Validate authentication: For private channels, inspect the /broadcasting/auth request payload. Ensure the user session is valid and the channel name matches the authorization pattern in channels.php.
  5. Review logs: Check /var/log/reverb.log and Laravel logs simultaneously. Reverb logs connection lifecycle events, while Laravel logs broadcasting failures and auth exceptions.

A frequent gotcha in Nepal and similar regions involves ISP-level filtering or corporate firewalls blocking non-standard ports. Always serve WebSockets over port 443 (WSS) through your existing SSL certificate. This not only improves security but also ensures compatibility with restrictive network environments. If you're integrating payment webhooks alongside real-time updates, ensure your webhook endpoints don't conflict with your broadcasting routes; my guide on Laravel payment integrations covers route isolation strategies.

Conclusion

Adopting Real-Time Laravel with Reverb and WebSockets in 2026 gives you full ownership of your application's interactive layer without sacrificing developer experience or performance. The combination of native Laravel integration, Pusher protocol compatibility, and self-hosted economics makes it the pragmatic choice for everything from legal-tech client portals to high-volume eCommerce notifications. Start with a single-node Supervisor setup, validate your SSL termination early, and scale horizontally with Redis only when metrics demand it.

If you need help architecting a real-time system for your Laravel application or troubleshooting an existing WebSocket deployment, contact me to discuss your project requirements.

Frequently Asked Questions

Laravel Reverb is a first-party WebSocket server introduced in Laravel 11 that runs directly on your own infrastructure. It eliminates third-party SaaS fees for real-time features while maintaining full compatibility with the existing Laravel Echo client API and broadcasting drivers.

Self-hosting Reverb costs only your VPS expense, typically Rs 1,500 to Rs 3,000 monthly (USD 11–22) for a standard 2GB RAM instance. Pusher charges usage-based fees starting around USD 50/month for moderate traffic, making Reverb significantly cheaper for Nepali businesses at scale.

Yes. Laravel Reverb supports Laravel 11 and 12, requiring PHP 8.2 minimum. It runs stably on PHP 8.3 and 8.4 in production. Ensure your composer.json allows laravel/reverb ^1.0 and run php artisan reverb:install to configure credentials automatically.

Run composer require laravel/reverb followed by php artisan reverb:install. This publishes the config/reverb.php file, adds REVERB_APP_ID, REVERB_APP_KEY, REVERB_APP_SECRET, and REVERB_HOST variables to your .env, and registers the reverb:serve Artisan command. Update your broadcasting.php driver to reverb and rebuild frontend assets.

Absolutely. Reverb works with any frontend consuming Laravel Echo. Install laravel-echo and pusher-js via npm, configure Echo to use the reverb broadcaster with your self-hosted host and port, and listen to channels in Vue components or Alpine x-data blocks exactly as you would with Pusher.

Use Supervisor to manage the php artisan reverb:serve process persistently. Create /etc/supervisor/conf.d/reverb.conf pointing to your release path, set numprocs=1, autostart=true, and autorestart=true. On Deployer 7 setups, add a post-deploy task to restart supervisorctl reload reverb:* to pick up new code without downtime.

Reverb transmits over WSS when behind a reverse proxy terminating SSL. Authorize channels using Laravel Policies or Gate checks in routes/channels.php to prevent unauthorized listeners. Never broadcast PII directly; send only resource IDs and fetch sensitive details via authenticated REST endpoints. In my experience building legal-tech portals like Mijar Law Associates, this pattern satisfies client confidentiality requirements.

Reverb uses the same /broadcasting/auth endpoint as Pusher. Laravel validates the authenticated user against channel authorization rules defined in routes/channels.php before granting access. For API-only apps using Sanctum, ensure your frontend sends the session cookie or bearer token with the auth request so Reverb can verify permissions server-side.

Plan for 2GB RAM and 2 CPU cores minimum for 1,000 concurrent WebSocket connections. Reverb uses ReactPHP's event loop, so memory stays relatively flat per connection. Monitor with htop and Supervisor logs. On shared EC2 instances running multiple sister sites, I allocate dedicated resources to avoid contention during peak hours.

Check browser DevTools Network tab for failed ws:// or wss:// handshakes. Verify REVERB_HOST matches your local or dev domain, not localhost if accessing remotely. Run php artisan reverb:serve --debug to see verbose server logs. Confirm .env variables match config/reverb.php values after caching with php artisan config:clear.

Yes. Run Reverb on a non-standard port like 6001 and configure Nginx or Apache as a reverse proxy forwarding /app/websocket traffic to localhost:6001. This lets your main site serve HTTP on 443 while Reverb handles WebSocket upgrades separately. Always terminate SSL at the web server layer, not inside Reverb itself.

Use Redis Pub/Sub as the scaling driver by setting REVERB_SCALING_ENABLED=true and configuring a shared Redis instance. Each Reverb node subscribes to the same Redis channel, broadcasting messages across all connected clients regardless of which server they hit. This requires sticky sessions or consistent hashing at the load balancer level.

Common causes include insufficient Supervisor workers, PHP memory limits, or missing opcache preload. Increase max_execution_time and memory_limit in php.ini for the CLI SAPI. Add more Supervisor processes if CPU allows. In production deployments I maintain, enabling JIT compilation on PHP 8.3+ reduced event latency noticeably during high-throughput periods.

Yes. Presence channels work identically to Pusher, returning member lists via the auth endpoint. Client events are supported but must be explicitly allowed in channel authorization logic. Note that client events bypass your backend entirely between peers, so validate trust boundaries carefully before enabling them in multi-tenant applications.

Choose Reverb when already invested in the Laravel ecosystem and wanting zero vendor lock-in with familiar Echo syntax. Prefer Socket.io for complex room/namespace logic outside Laravel. Mercure excels for Symfony or async PHP projects. For most Laravel shops in Nepal, Reverb reduces operational complexity and cost versus maintaining separate real-time infrastructure.

Share this article

Quick Contact Options
Choose how you want to connect me: