Real-Time Features with Laravel Reverb and Vue.js
Real-Time Features with Laravel Reverb and Vue.js
SaaS Development

December 30, 2025

Real-Time Features with Laravel Reverb and Vue.js

You ship a “simple” live UI: a task board that updates instantly, a notification bell that increments in real time, a status badge that flips from Processing to Complete without refresh. Then the support tickets start: “It works locally but not in staging,” “It updates twice,” “It randomly stops until I hard refresh,” “It’s fine

R
Rivu-adm
13 min read

You ship a “simple” live UI: a task board that updates instantly, a notification bell that increments in real time, a status badge that flips from Processing to Complete without refresh.

Then the support tickets start: “It works locally but not in staging,” “It updates twice,” “It randomly stops until I hard refresh,” “It’s fine for 5 users and falls over at 500.”

This is where laravel reverb real time work either becomes a clean, repeatable delivery system—or a never-ending stream of edge cases.

This post is a technical tutorial for building real-time features in a Laravel + Vue stack using Laravel Reverb, with the operational details agencies care about: predictable setup, clean auth, reliable queues, and a production path you won’t regret.

What “laravel reverb real time” Actually Means (and What It Is Not)

In Laravel, “real-time” is usually event broadcasting: your backend emits an event, and subscribed clients receive it over WebSockets.

Reverb is Laravel’s first-party WebSocket server. It plugs into Laravel’s existing broadcasting system, so you keep the mental model you already use for events, queues, and channels. (laravel.com)

It’s not “make my app faster.” It’s “stop polling, keep a connection open, and push updates as they happen.” If you need a baseline reference for the browser side of this, MDN’s overview of the WebSocket API is a solid primer. MDN’s WebSockets API overview.

The mechanism (cause → effect)

When you broadcast events consistently, your UI becomes a projection of server-side state. When you broadcast inconsistently, your UI becomes a guess.

That’s why laravel reverb real time features tend to fail in predictable ways: missing queues, wrong auth endpoint, wrong host/port, CORS/origin issues, or “worked in dev” SSL assumptions.

The Stack You’re Building (Laravel Broadcasting + Reverb + Vue)

For a typical real time Laravel Vue app, the moving parts look like this:

  • Laravel Events that implement broadcasting (server-side “what happened”).
  • Broadcast driver configured to use Reverb (server-side “where to send it”).
  • Queue worker running (server-side “deliver it without blocking requests”).
  • Reverb server running (the WebSocket server clients connect to). (laravel.com)
  • Vue client subscribing via Laravel Echo (client-side “listen and update UI”).

Laravel’s broadcasting docs explicitly call out Reverb as a supported driver, alongside hosted options. Laravel Broadcasting documentation. (laravel.com)

Real-time bugs rarely live in your Vue component. They live in the contracts between your queue, your WebSocket server, and your channel auth.

Step 1: Install Reverb the “Laravel Way”

If you want the shortest path to laravel reverb real time working, use Laravel’s installer for broadcasting. It sets up the config files and the baseline packages.

Install broadcasting with Reverb

php artisan install:broadcasting --reverb

This flow is documented in both the Reverb and Broadcasting docs. It’s also the best way to avoid a half-configured setup where you’re debugging env vars that were never created. Laravel Reverb documentation. (laravel.com)

Confirm your env variables

Your project will rely on Reverb application credentials and host/port variables. Your exact variable set may vary by Laravel version and installer prompts, but the key point is consistency between:

  • Where Laravel sends broadcast messages
  • Where clients connect via WebSockets
  • Where Reverb actually listens

In Reverb’s docs, Laravel distinguishes between the server bind address/port and the public host/port you expose via reverse proxy. That distinction is where many staging environments break. (laravel.com)

Step 2: Run the Reverb Server (Local First, Then Staging)

In development, you can run Reverb directly:

php artisan reverb:start

Reverb supports a debug mode that’s useful when you’re validating whether messages are actually flowing (and whether the client is subscribing to the channel you think it is):

php artisan reverb:start --debug

For laravel reverb real time to feel “reliable,” your dev team needs a quick triage loop: can the server see the subscription? can it see the event publish? can the client see the event?

Step 3: Make Broadcasting Predictable (Queues Are Not Optional)

Broadcasting is typically queued. If your queue worker isn’t running, “real-time” becomes “sometimes later” or “never.” Laravel’s broadcasting docs emphasize configuring and running a queue worker before you rely on events being delivered. (laravel.com)

Pick a queue driver you can operate

For agencies, the default recommendation is boring on purpose:

  • Use Redis queues if you already run Redis.
  • Use database queues only for prototypes and internal tooling.

Then run a worker:

php artisan queue:work

If you’re testing laravel reverb real time locally, this is the easiest “missing step” to forget when you’re focused on Vue.

Step 4: Create a Broadcast Event (Server-Side Contract)

Now we’ll create a concrete event that your Vue UI can react to. Example: a SaaS app where a background job imports contacts and reports progress.

Create the event

php artisan make:event ImportProgressUpdated

Then implement broadcasting (simplified):

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ImportProgressUpdated implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(
        public string $importId,
        public int $processed,
        public int $total
    ) {}

    public function broadcastOn(): Channel
    {
        return new Channel("imports.{$this->importId}");
    }

    public function broadcastAs(): string
    {
        return 'ImportProgressUpdated';
    }
}

Dispatch it from a job

Inside your import job:

ImportProgressUpdated::dispatch($importId, $processed, $total);

This is the core laravel reverb real time loop: backend state changes → event emitted → clients update UI.

Step 5: Configure Channel Authorization (So You Don’t Ship a Data Leak)

Public channels are easy. They’re also how teams accidentally leak customer activity across accounts.

If your SaaS is multi-tenant (most agency-built SaaS is), you’ll usually want private channels keyed to a tenant, user, or resource—and you must authorize subscriptions server-side.

Define a private channel

In your event, switch to PrivateChannel:

use Illuminate\Broadcasting\PrivateChannel;

public function broadcastOn(): PrivateChannel
{
    return new PrivateChannel("imports.{$this->importId}");
}

Authorize in routes/channels.php

use App\Models\Import;

Broadcast::channel('imports.{importId}', function ($user, $importId) {
    $import = Import::where('id', $importId)->firstOrFail();

    return $import->tenant_id === $user->tenant_id;
});

If you skip this step, laravel reverb real time becomes “real-time visibility into data you shouldn’t see.”

For security hardening beyond the Laravel layer, OWASP’s guidance on WebSocket risks (origin validation, authentication assumptions, and DoS concerns) is worth reading before you go live: OWASP WebSocket Security Cheat Sheet.

Step 6: Wire Up Vue.js with Laravel Echo (Client-Side Contract)

Most teams use Laravel Echo to subscribe to channels and listen for broadcast events. Echo is maintained by the Laravel org, and it’s designed to make Reverb, Pusher, and Ably feel consistent from the client side. Laravel Echo (GitHub). (github.com)

In a real time Laravel Vue app, you typically initialize Echo once (app bootstrap), then subscribe in the components that need live updates.

Install client dependencies

npm install laravel-echo pusher-js

Reverb uses the Pusher protocol, which is why pusher-js is commonly involved even though you’re not using Pusher hosted infrastructure. (reverb.laravel.com)

Initialize Echo (example)

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: Number(import.meta.env.VITE_REVERB_PORT || 80),
  wssPort: Number(import.meta.env.VITE_REVERB_PORT || 443),
  forceTLS: import.meta.env.VITE_REVERB_SCHEME === 'https',
  enabledTransports: ['ws', 'wss'],
});

At this point, you’ve built the basic client runtime for laravel reverb real time.

Step 7: Listen in a Vue Component (Real Time Laravel Vue in Practice)

In Vue, keep it simple: subscribe on mount, leave on unmount, and update a small reactive state object.

<script setup>
import { onMounted, onBeforeUnmount, ref, computed } from 'vue';

const props = defineProps({
  importId: { type: String, required: true }
});

const processed = ref(0);
const total = ref(0);

const percent = computed(() => {
  if (!total.value) return 0;
  return Math.round((processed.value / total.value) * 100);
});

let channel = null;

onMounted(() => {
  channel = window.Echo.private(`imports.${props.importId}`)
    .listen('.ImportProgressUpdated', (e) => {
      processed.value = e.processed;
      total.value = e.total;
    });
});

onBeforeUnmount(() => {
  if (channel) window.Echo.leave(`private-imports.${props.importId}`);
});
</script>

<template>
  <div>
    <p>Import progress: {{ percent }}% ({{ processed }}/{{ total }})</p>
  </div>
</template>

If you want to keep your front-end mental model clean, Vue’s official explanation of how reactivity works is the right reference point: Vue reactivity in depth.

This is the point where teams usually declare victory on laravel reverb real time.

Production is where the real work starts.

Productionizing “laravel reverb real time”: Scaling, Security, and Monitoring

If you’re building for internal ops tools, one Reverb process might be fine.

If you’re building a multi-tenant SaaS where clients sit in the app all day, you need to treat WebSockets like infrastructure, not a feature.

The Reverb Production Checklist (agency-friendly)

  • Run Reverb under a process manager (so it restarts cleanly).
  • Put it behind a reverse proxy (terminate TLS at the edge, speak WSS publicly).
  • Use WSS in production (don’t ship ws:// beyond localhost). See OWASP guidance for why. OWASP WebSocket Security.
  • Set allowed origins (avoid cross-site WebSocket hijacking patterns).
  • Watch open file limits (WebSockets are persistent connections; concurrency is a ulimit problem as much as a code problem). (laravel.com)

Scaling Reverb horizontally with Redis

Reverb supports horizontal scaling using Redis pub/sub, so multiple Reverb nodes can share messages and client subscriptions across instances. (laravel.com)

This is the operational “unlock” when your client wants laravel reverb real time and also wants 10,000 concurrent users on a marketing day.

If you want a reference for Redis pub/sub behavior and constraints, Redis’ own docs are the safest source: Redis Pub/Sub documentation.

Monitoring: don’t wait for “it feels slow”

Reverb can be monitored via Laravel Pulse integration (connections and messages), which is exactly what you want in an agency environment where you need evidence before you change infrastructure. (laravel.com)

Your goal isn’t perfect observability. It’s early detection of drift: queue delays, reconnect storms, and message spikes that show up as “the UI is glitchy.”

A Practical Decision Matrix: Reverb vs Hosted “Laravel WebSockets” Options

MoFu reality: you’re choosing a real-time approach that you can both build and operate.

Decision Factor Laravel Reverb (self/infra you control) Hosted provider (Pusher/Ably)
Time to first demo Fast (especially with install:broadcasting) Fast (vendor dashboard + keys)
Ongoing ops You own uptime, scaling, WSS, limits Vendor owns infra; you own integration
Cost profile at scale Infra cost grows with your usage Bill grows with messages/connections
Compliance / data locality Strong control (depends on your hosting) Depends on vendor plan and regions

If your team is comfortable operating queues + Redis + reverse proxies, laravel reverb real time is usually a clean default. If your team is not, you’ll spend the savings in engineering hours.

Common Failure Modes (and the Fastest Fixes)

1) “Events dispatch, but Vue never receives them”

  • Verify the queue worker is running (most common).
  • Confirm the client is subscribing to the exact channel name.
  • Run Reverb with --debug and watch for subscribe + message events.

2) “It works on localhost but not on staging”

  • Staging usually introduces TLS, a reverse proxy, and a different host/port.
  • Align REVERB_HOST/REVERB_PORT with what the browser can reach.
  • Use WSS publicly; don’t leak ws:// assumptions into staging.

3) “Private channels 403 on /broadcasting/auth”

  • Confirm the user is authenticated in the same context (cookies, session domain, CSRF if applicable).
  • Confirm your Broadcast::channel() callback returns true for that user and resource.

4) “Duplicate events”

  • Leaving channels incorrectly in Vue can cause stacked listeners.
  • Be deliberate about mount/unmount, and ensure you aren’t initializing Echo multiple times.

These are the “agency tax” issues: they don’t announce themselves, but they quietly travel downstream into QA, timelines, and client trust.

Where Rivulet IQ Fits (Real-Time Dev Without Derailing Your Team)

If you’re an agency leader, the blocker usually isn’t “can we build it?” It’s “can we ship laravel reverb real time reliably while still delivering everything else on the roadmap?”

Rivulet IQ can implement Reverb + Vue real-time features as a white-label delivery partner—events, channels, auth, queues, and production hardening—so your internal team stays focused on client-facing priorities.

If you want help scoping it, the fastest starting point is: which UI moments must update live, and what’s the source of truth for each?

The Takeaway

laravel reverb real time succeeds when you treat it like a system: event contracts, channel governance, queue discipline, and production-grade connectivity.

Laravel makes the “happy path” fast. The differentiator is whether you also ship the boring parts: WSS, origin rules, process managers, and scaling with Redis when the app outgrows a single node.

If you build those decisions in early, your real time Laravel Vue features stop being fragile demos and start being dependable product behavior.

FAQs

Do I need Redis for laravel reverb real time?

Not for local development or small deployments. You’ll want Redis if you’re using Redis queues and if you plan to scale Reverb horizontally (Reverb can use Redis pub/sub for that). (laravel.com)

Is Reverb replacing “laravel websockets” packages?

In many stacks, yes. Reverb is first-party and designed to integrate directly with Laravel broadcasting and Echo. If you’ve been using older community or Node-based options, Reverb is often the cleaner long-term path. (laravel.com)

Can I use laravel reverb real time with Vue without Laravel Echo?

You can, but you’ll be rebuilding subscription management, auth flows, and event handling that Echo already standardizes. Echo exists to reduce client-side complexity for broadcasting. Laravel Echo. (github.com)

What’s the biggest security mistake in real time Laravel Vue apps?

Treating channels as “just frontend.” Private/presence channels require server-side authorization, and WebSocket deployments need origin and TLS discipline. OWASP’s WebSocket cheat sheet is a strong baseline for common pitfalls. OWASP WebSocket Security Cheat Sheet. (cheatsheetseries.owasp.org)

Why does it work locally but fail in staging?

Staging introduces reverse proxies, TLS termination, different ports, and stricter CORS/origin behavior. The fix is usually aligning the public host/port/scheme the browser uses with how Reverb is actually exposed. (laravel.com)

How do I know if my issue is Reverb vs queues vs Vue?

Triangulate in this order: (1) confirm the queue worker is processing broadcasts, (2) run Reverb with debug logs to see connections/subscriptions/messages, (3) confirm Vue is subscribing once and leaving correctly. That sequence isolates the layer that’s actually failing.

Over to You

When you ship laravel reverb real time features, what’s your team’s standard “production readiness” checklist (WSS, origins, queues, monitoring, scaling)—and which item tends to get missed first?