Laravel Reverb landed as a first-party WebSocket server in Laravel 11, and it changed the real-time game for the Laravel ecosystem. But should you use it over Pusher, Soketi, or raw WebSockets? I tested all four in production scenarios. Here's what I found.
The Contenders
| Solution | Type | Cost | Setup Complexity | Scalability |
| **Laravel Reverb** | First-party, self-hosted | Free (server cost only) | Low | High (horizontal scaling) |
| **Pusher** | Managed SaaS | Paid (free tier limited) | Minimal | Very High |
| **Soketi** | Open-source, self-hosted | Free (server cost only) | Medium | High |
| **Native WebSockets (Ratchet/ReactPHP)** | Library | Free | High | Moderate |
Laravel Reverb — The New Default
Reverb is Laravel's official WebSocket server, built on top of ReactPHP and PHP 8.2+. It's designed specifically for Laravel Broadcasting:
composer require laravel/reverb
php artisan reverb:install
php artisan reverb:startThat's it. Three commands and you have a production-ready WebSocket server. The configuration lives in your Laravel app:
// config/reverb.php
'app' => [
'apps' => [
[
'app_id' => env('REVERB_APP_ID'),
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
],
],
],
'scaling' => [
'enabled' => env('REVERB_SCALING_ENABLED', false),
'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
'server' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', 6379),
],
],Benchmarks
I ran Reverb on a $20/month VPS (2 vCPU, 4GB RAM) simulating 10,000 concurrent connections:
For a self-hosted solution running on PHP, these numbers are impressive. The secret is ReactPHP's event loop — it handles I/O asynchronously without spawning a process per connection.
Pusher — The Set-and-Forget Option
Pusher is the incumbent. It's managed, so you don't think about servers, scaling, or uptime:
// config/broadcasting.php
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
],
],The Cost Reality
Pusher's free tier gives you 200,000 messages/day and 100 concurrent connections. For a production app handling 500,000 messages/day with 5,000 concurrent connections, you're looking at **$199/month** on their Scale plan.
For comparison, running Reverb on a $20/month VPS handles that same load without breaking a sweat. Over a year, that's **$2,148 saved**.
When Pusher Still Wins
Soketi — The Open-Source Middle Ground
Soketi is a Pusher-compatible WebSocket server written in Node.js. It speaks the Pusher protocol, so you swap the URL and keep your client code:
# Deploy with Docker
docker run -p 6001:6001 -e SOKETI_DEFAULT_APP_ID=app-id \
-e SOKETI_DEFAULT_APP_KEY=app-key \
-e SOKETI_DEFAULT_APP_SECRET=app-secret \
quay.io/soketi/soketi:latestYour Laravel config stays identical to Pusher — just change the host:
'options' => [
'host' => env('SOKETI_HOST', '127.0.0.1'),
'port' => env('SOKETI_PORT', 6001),
'useTLS' => false,
],Soketi vs Reverb
Soketi edges ahead in raw throughput (Node.js event loop is faster than ReactPHP), but Reverb wins in operational simplicity because:
Native WebSockets (Ratchet)
You can build a WebSocket server from scratch with Ratchet or ReactPHP:
use RatchetServerIoServer;
use RatchetHttpHttpServer;
use RatchetWebSocketWsServer;
$server = IoServer::factory(
new HttpServer(
new WsServer(
new YourMessageHandler()
)
),
8080
);
$server->run();This gives maximum flexibility but requires you to implement broadcasting, presence channels, authentication, and reconnection logic yourself. In practice, the engineering cost rarely justifies it unless you have very specific requirements.
My Recommendation
| Use Case | Best Choice |
| New Laravel project, self-hosted | **Laravel Reverb** |
| Managed, no ops overhead | **Pusher** (budget permitting) |
| Cost-sensitive, Pusher-compatible | **Soketi** |
| Custom protocol or niche requirement | **Ratchet** |
For most Laravel projects starting today, **Reverb is the default**. It's free, first-party, PHP-native, and performs well enough for all but the highest-throughput applications. Start with Reverb. If you outgrow it, the Pusher protocol is a standard — your client code won't change.