Skip to main content

Command Palette

Search for a command to run...

Architecting Concurrent SaaS: Real-Time State Sync with Laravel Reverb & React hooks

Updated
5 min read
Architecting Concurrent SaaS: Real-Time State Sync with Laravel Reverb & React hooks
P
Hi, I'm Paresh! I'm a full-stack developer based in Ahmedabad, India, working remotely to build scalable web and mobile applications. My core technical stack includes Laravel, Flutter, PHP, JavaScript, PostgreSQL, and MySQL. I'm passionate about the entire product lifecycle—from architecture and coding to SEO and digital marketing. Currently, I'm focused on growing smarttechdevs.in and developing impactful, real-world products

The Problem: Stale Data in B2B Decision Making

In the high-stakes world of B2B SaaS and industrial management platforms, stale data is more than an inconvenience; it is a critical bottleneck. When multiple stakeholders are viewing the same analytical dashboard, decisions must be made based on live, concurrent state. If user A updates a critical inventory metric, user B must see that change reflected instantly without a manual page refresh. Traditional polling methods (repeatedly hitting an API endpoint) are resource-intensive, introduce unacceptable latency, and fail to scale under the load required by modern enterprise applications built at Smart Tech Devs.

The Solution: Event-Driven Real-Time Architecture

To build truly interactive, collaborative environments, we must shift from a Request/Response model to an Event-Driven model. In the Laravel ecosystem of 2026, this is achieved effortlessly using Laravel Reverb—a first-party, high-performance WebSocket server designed specifically for Laravel applications. When paired with a React frontend (integrated via Inertia.js or as a decoupled client), we create a seamless synchronization layer.

Architectural Breakdown

The workflow relies on four core components:

  1. The Backend Event: A standard Laravel event that implements the ShouldBroadcast interface.

  2. The Broadcasting Driver (Reverb): The WebSocket server that accepts the event and broadcasts the payload to connected clients.

  3. Presence Channels: Specific WebSocket channels that allow us to track not just data changes, but also *who* is currently viewing or interacting with a component (creating a "Google Docs" type awareness).

  4. The Frontend Listener (React Echo): A React hook using Laravel Echo to subscribe to channels and update the component state dynamically when an event is received.

Comprehensive Code Implementation Guide

Step 1: Laravel Event Configuration ( `app/Events/InventoryUpdated.php` )

Our backend event handles the payload and defines the secure channel.


namespace App\Events;

use App\Models\Inventory;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel; // For user awareness
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

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

    public $inventory;
    public $userId;

    /**
     * Create a new event instance.
     */
    public function __construct(Inventory \(inventory, \)userId)
    {
        \(this->inventory = \)inventory;
        \(this->userId = \)userId; // Pass who made the change
    }

    /**
     * Get the channels the event should broadcast on.
     */
    public function broadcastOn(): array
    {
        // Use a presence channel for the specific warehouse dashboard
        return [
            new PresenceChannel('warehouse.' . $this->inventory->warehouse_id),
        ];
    }

    /**
     * Custom payload to send to the frontend.
     */
    public function broadcastWith(): array
    {
        return [
            'id' => $this->inventory->id,
            'stock_level' => $this->inventory->stock_level,
            'updated_by' => $this->userId,
        ];
    }
}

Step 2: Backend Trigger (A Service or Controller)

When the inventory model is updated, we dispatch the broadcast event.


// Inside app/Services/InventoryService.php

public function updateStockLevel(Inventory \(inventory, int \)newLevel)
{
    // 1. Perform complex validation and update logic...
    \(inventory->update(['stock_level' => \)newLevel]);

    // 2. Dispatch the real-time broadcast
    // Pass the user ID making the change for frontend awareness
    event(new InventoryUpdated($inventory, auth()->id()));
}

Step 3: React Frontend Hook ( `hooks/useInventoryRealtime.js` )

This hook manages the WebSocket connection, subscribes to the channel, and provides user presence data to the component.


import { useEffect, useState } from 'react';
import Echo from 'laravel-echo';
import Pusher from 'pusher-js'; // Echo requires a Pusher-compatible client

// Ensure Echo is initialized globally or inside a provider
window.Pusher = Pusher;
const echoInstance = 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,
    forceTLS: false, // For local or internal network development
    enabledTransports: ['ws', 'wss'],
});

export const useInventoryRealtime = (warehouseId) => {
    const [liveInventory, setLiveInventory] = useState([]);
    const [activeUsers, setActiveUsers] = useState([]);

    useEffect(() => {
        if (!warehouseId) return;

        // 1. Subscribe to the secure Presence Channel
        const channel = echoInstance.join(`warehouse.${warehouseId}`)
            // Track who is already here
            .here((users) => {
                setActiveUsers(users);
            })
            // Track when a new stakeholder joins
            .joining((user) => {
                setActiveUsers((prev) => [...prev, user]);
                console.log(`${user.name} joined the dashboard.`);
            })
            // Track when a stakeholder leaves
            .leaving((user) => {
                setActiveUsers((prev) => prev.filter(u => u.id !== user.id));
            })
            // 2. Listen for the InventoryUpdated event payload
            .listen('.InventoryUpdated', (eventPayload) => {
                console.log('Real-time stock update received:', eventPayload);
                // Update the local state instantly without a refresh
                setLiveInventory((prev) => 
                    prev.map(item => item.id === eventPayload.id ? { ...item, stock_level: eventPayload.stock_level } : item)
                );
            });

        // 3. Cleanup connection on component unmount
        return () => {
            echoInstance.leave(`warehouse.${warehouseId}`);
        };
    }, [warehouseId]);

    // Initial data loading would typically happen via Inertia or useQuery,
    // and setLiveInventory would be initialized there.

    return { liveInventory, setLiveInventory, activeUsers };
};

Deeper Technical Benefits

By shifting to Laravel Reverb and React for real-time synchronization, we achieve several major advantages crucial for durable B2B products:

  1. Enterprise-Grade UX: Instant data consistency across all stakeholders builds massive user trust in your platform's reliability.

  2. Highly Optimized Server Resources: Unlike continuous polling, WebSockets use a single persistent connection per client. This dramatically reduces backend API overhead and database query load, allowing you to serve thousands of concurrent B2B users on modest infrastructure.

  3. Presence Awareness: Knowing which stakeholders are currently "active" on a dashboard prevents collision errors (e.g., two admins editing the same client record simultaneously) and facilitates seamless collaboration workflows.

Conclusion

The shift from static data presentation to dynamic, event-driven collaboration is a defining requirement for any modern B2B SaaS platform. Leveraging Laravel Reverb provides a robust, native infrastructure layer that, when paired with the reactive state management of React, allows Smart Tech Devs to build world-class collaborative experiences that scale.