SAYED.DEV
May 05, 20264 min read

Real-Time WebSocket Optimization for Fleet Systems

Solving coordinate update bottlenecks, marker clustering, and UI viewport optimizations.

Real-Time Fleet Tracking at Scale

In fleet management platforms (like Routz), tracking hundreds of active vehicles in real-time requires continuous data syncing. When raw coordinate updates stream in via WebSockets at sub-second intervals, the naive approach of re-rendering map markers instantly will bring the browser's main thread to a complete crawl. To achieve smooth 60fps movement, we implemented three coordinate-culling optimization techniques:

1. Viewport Culling (Marker Pruning)

Instead of updating all vehicle markers globally, we check if the vehicle falls within the user's active map bounding box before dispatching DOM updates:
// src/utils/map.ts
export function updateVisibleMarkers(map, vehiclesData) {
    const bounds = map.getBounds();
    
    vehiclesData.forEach(vehicle => {
        const position = [vehicle.lat, vehicle.lng];
        
        if (bounds.contains(position)) {
            // Render or update marker coordinates
            updateVehicleMarker(vehicle.id, position);
        } else {
            // Prune off-screen marker from the DOM to reduce nodes
            removeVehicleMarker(vehicle.id);
        }
    });
}

2. Haversine Distance Thresholding

WebSockets often broadcast coordinate updates even when a vehicle is idling at a red light or stuck in heavy traffic. To avoid redundant updates, we calculate the Haversine distance from the previous coordinate and ignore changes below a 5-meter threshold:
// src/utils/haversine.ts
export function getDistanceMeters(lat1, lon1, lat2, lon2) {
    const R = 6371e3; // Earth radius in meters
    const phi1 = lat1 * Math.PI / 180;
    const phi2 = lat2 * Math.PI / 180;
    const deltaPhi = (lat2 - lat1) * Math.PI / 180;
    const deltaLambda = (lon2 - lon1) * Math.PI / 180;

    const a = Math.sin(deltaPhi/2) * Math.sin(deltaPhi/2) +
              Math.cos(phi1) * Math.cos(phi2) *
              Math.sin(deltaLambda/2) * Math.sin(deltaLambda/2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

    return R * c; // returns distance in meters
}

3. Coordinate Debouncing (Interpolation)

Instead of snapping the marker immediately to the new coordinate, we smooth the transitions using linear interpolation (lerp). This reduces visual jitter and creates a smooth moving effect even when WebSocket packets arrive asynchronously. Implementing these constraints reduced overall main-thread scripting overhead by ~70%, enabling a highly performant real-time visualization dashboard.

About the author

Written by Sayed Esmail

Senior Frontend Engineer specializing in Vue & React SaaS architectures.