De tijd dat “real-time” een dure luxe was, is voorbij. Gebruikers verwachten directe feedback: live notificaties, chats, dashboards die zichzelf bijwerken, of samenwerkingsfuncties die realtime aanvoelen.
Toch was real-time functionaliteit in Laravel-projecten tot voor kort vaak een gedoe. Externe services zoals Pusher, Ably of community-packages zoals BeyondCode WebSockets losten dat deels op, maar introduceerden afhankelijkheden en extra beheerlast.
Met de komst van Laravel Reverb verandert dat radicaal: een officiële WebSocket-server, ontwikkeld door het Laravel-team zelf. Volledig geïntegreerd in het framework, geoptimaliseerd voor performance en klaar voor productie.
In dit artikel duiken we diep in de architectuur, implementatie en performance-implicaties van Reverb — en wat het betekent voor het Laravel-ecosysteem.
Waarom real-time er toe doet
Webapplicaties zijn niet langer statisch.
Of het nu gaat om orderupdates, chatberichten, IoT-signalen of multiplayer-events — gebruikers willen instant feedback zonder te hoeven refreshen.
Tot voor kort losten veel teams dit op met polling of long polling:
Client: "Heb je nieuwe data?"
Server: "Nee."
Client: "En nu?"
Server: "Nee."
Niet efficiënt. WebSockets draaien dit om: er is één persistente verbinding, en de server pusht events zodra er iets verandert. Geen onnodige requests, minder latency en een meer vloeiende gebruikerservaring.
Wat zijn WebSockets (in het kort)
WebSockets bieden een bidirectionele verbinding tussen client en server via één open TCP-socket. Na de initiële connectie blijft de verbinding open, waardoor beide kanten data kunnen sturen zonder opnieuw te verbinden.
Voordelen:
- Lage latency
- Minder netwerkoverhead
- Real-time dataflows
- Persistente connecties met authenticatie
Nadelen:
- Stateful verbindingen (dus complexer in scaling)
- Meer infrastructuurkennis vereist
- Andere manier van debuggen
In moderne Laravel-applicaties gebruik je WebSockets vooral in combinatie met Laravel Echo, dat fungeert als JavaScript-client voor event-listening aan de frontend.
Voor Reverb: externe oplossingen en community packages
Laravel heeft altijd sterke ondersteuning gehad voor event broadcasting, maar geen native WebSocket-server. Diensten die hiervoor gebruikt werden
- Pusher / Ably: hosted, schaalbaar, maar kosten en vendor lock-in.
- BeyondCode Laravel WebSockets: open source alternatief, werkte goed, maar was geen onderdeel van het core-team.
De community vroeg al jaren om een officiële oplossing — vooral voor projecten waar data-soevereiniteit, kostenbeheersing en native integratie belangrijk zijn.
Laravel Reverb: de officiële WebSocket-server
Reverb is Laravel’s antwoord op die vraag.
Het is een first-party WebSocket-server, ontwikkeld door het Laravel-team zelf.
Reverb gebruikt onder water dezelfde event-architectuur als Laravel Broadcasting, maar draait als eigen proces naast je applicatie.
Belangrijkste kenmerken:
- Native integratie met Broadcasting, Echo, Octane en Horizon
- Gebouwd voor performance: non-blocking I/O via ReactPHP
- Volledige authenticatie-ondersteuning voor private/presence channels
- Redis Pub/Sub integratie voor horizontale schaalbaarheid
- Drop-in vervanging van Pusher of BeyondCode WebSockets
Architectuur en datastroom
Een typische Reverb-setup ziet er zo uit:
Frontend (Echo)
│ ▼WebSocket handshake
│ ▼Laravel Reverb Server
│ ▼Broadcast Driver (Redis / Log / Null)
│ ▼Backend Event → Broadcast
Een concrete flow:
- Een gebruiker plaatst een bestelling.
- Laravel triggert een
OrderShippedevent. - Dat event wordt “gebroadcast” via de
reverbdriver. - Alle verbonden clients op het
orderskanaal ontvangen direct het event.
Installatie & configuratie
De setup is verrassend eenvoudig:
php artisan install:broadcasting
Indien gewenst kunnen aanpassingen worden gedaan in de configuatie van reverb, maar in principe is het meteen ready to go. Het configuratie bestand vind je eventueel in config/reverb.php
Start de server:
php artisan reverb:start
Broadcasting in actie
Een backend event:
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class OrderShipped implements ShouldBroadcast
{
public $order;
public function __construct($order) {
$this->order = $order;
}
public function broadcastOn(): array {
return ['orders'];
}
}
Frontend met Laravel Echo:
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 ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
window.Echo.channel('orders')
.listen('OrderShipped', (e) => {
console.log('Order shipped:', event.order);
// Do anything with the order, like display a notification
});
En dat is het — real-time updates zonder externe service.
Schaalbaarheid en performance
Reverb gebruikt een event-loop via ReactPHP. Dat betekent dat de server niet-blocking is en duizenden connecties tegelijk aankan, mits goed geconfigureerd.
Redis pub/sub
Voor horizontale schaalvergroting kun je meerdere Reverb-nodes starten die met elkaar synchroniseren via Redis:
BROADCAST_DRIVER=redis
Elk event dat in één node gebroadcast wordt, wordt via Redis gedeeld met andere nodes — cruciaal voor horizontale schaal in containerized omgevingen.
Performance-tips
- Laat Reverb draaien als dedicated service, niet als artisan-proces op shared hosting.
- Gebruik TLS voor productie (Reverb ondersteunt wss://).
- Houd je channel-count beperkt: 1000 kleine channels schalen beter dan één massive presence channel.
Beveiliging
Private en presence channels maken gebruik van Laravel’s standaard authenticatie-flow.
De handshake verloopt via /broadcasting/auth, waar je policies of gates kunt toepassen. Een voorbeeld hoe je een channel beveiligd is als volgt:
Broadcast::channel('orders.{orderId}', function ($user, $orderId) {
return $user->id === Order::find($orderId)->user_id;
});
Zo behoud je controle over wie welke events ontvangt — essentieel voor multi-tenant SaaS of B2B-apps.
Reverb en Optimistic Updates
Wat is een Optimistic Update?
Een optimistic update is een frontend-patroon waarbij je direct de UI bijwerkt zodra de gebruiker een actie uitvoert — nog voordat de server bevestigd heeft dat alles gelukt is.
Het idee: “optimistisch aannemen dat het goed gaat”.
Bijvoorbeeld: een gebruiker klikt op “Like”, en de UI toont meteen één extra like, zonder te wachten op de serverrespons. Als de server later faalt, wordt de wijziging teruggedraaid.
Voordelen:
- Veel snellere gebruikerservaring
- Minder “wachten op server”-gevoel
- Combineert goed met real-time feedback
Nadelen:
- Complexere state handling (rollback bij fouten)
- Vereist consistentie tussen frontend en backend states
Hoe combineer je Optimistic Updates met Reverb
Reverb past hier perfect bij. Je kunt de optimistic UI-update direct uitvoeren, en daarna via een broadcast-event laten bevestigen of corrigeren door de server.
Bijvoorbeeld in een chat- of commentsysteem:
Frontend (optimistic update + realtime bevestiging):
const newMessage = {
id: tempId(),
body: messageBody,
user: currentUser,
pending: true,
};
messages.push(newMessage);
// Verstuur naar backend
axios.post('/messages', { body: messageBody })
.then(response => {
// Server bevestigt en broadcast via Reverb
// UI zal via Echo het definitieve bericht ontvangen
})
.catch(() => {
// Rollback bij foutmessages
messages.filter(m => m.id !== newMessage.id);
});
// Luister naar broadcast-event
window.Echo.channel('chat')
.listen('MessageCreated', (event) => {
const index = messages.findIndex(m => m.id === event.temp_id);
if (index >= 0) {
// Vervang tijdelijk bericht met serverversie
messages[index] = event.message;
} else {
messages.push(event.message);
}
});
Backend:
class MessageCreated implements ShouldBroadcast
{
public $message;
public $temp_id;
public function __construct(Message $message, $temp_id) {
$this->message = $message;
$this->temp_id = $temp_id;
}
public function broadcastOn(): array {
return ['chat'];
}}
...
}
Hierdoor ervaart de gebruiker instant feedback (optimistic update), maar blijft de data consistent dankzij Reverb’s broadcast zodra de backend bevestigt.
Kort gezegd:
- Reverb = betrouwbaarheid & synchronisatie
- Optimistic update = snelheid & UX
- Samen = razendsnelle en consistente real-time ervaring
Wanneer gebruik je Reverb (en wanneer niet)?
| Scenario | Reverb | Externe Service |
|---|---|---|
| Eigen infrastructuur | ✅ | ⚠️ |
| Kleine tot middelgrote apps | ✅ | ✅ |
| Grote apps met globale latency-eisen | ⚠️ (met Redis scaling) | ✅ |
| Geen devops-capaciteit | ⚠️ | ✅ |
| Privacygevoelige data | ✅ | ⚠️ |
| Kort gezegd: als je Laravel al zelf host (Forge, Vapor, Kubernetes), dan is Reverb vaak de logische keuze. |
Valkuilen en best practices
- Over-broadcasting: stuur geen events die niemand gebruikt.
- Reconnect handling: implementeer reconnect logic aan de frontend.
- Monitoring: gebruik Horizon of een externe log sink voor event-statistieken.
- Security first: authenticatie is geen nice-to-have, zeker bij presence channels.
- Local dev: gebruik
reverb --debugom realtime logging te zien tijdens ontwikkeling. - Optimistic updates: gebruik tijdelijke IDs en serverbevestiging om state te synchroniseren.
Conclusie
Laravel Reverb brengt een nieuwe fase in het framework: één waarin real-time communicatie niet meer afhankelijk is van externe partijen. Het combineert eenvoud, performance en native integratie — precies wat je verwacht van een modern framework anno 2025.
Voor ontwikkelaars die performance en controle willen behouden, is Reverb de logische volgende stap. Het is geen “nice to have” meer, maar de nieuwe standaard voor interactieve, moderne webapplicaties in Laravel.