Low-Level Design: Fleet Management System — Vehicle Tracking, Maintenance, and Route Optimization

Core Entities

Vehicle: vehicle_id, vin (unique), make, model, year, type (SEDAN, VAN, TRUCK, ELECTRIC), status (AVAILABLE, ASSIGNED, IN_MAINTENANCE, OUT_OF_SERVICE), current_driver_id, current_lat, current_lng, odometer_km, fuel_level_pct, battery_soc_pct (for EVs), last_location_update. Driver: driver_id, user_id, license_number, license_expiry, status (AVAILABLE, ON_DUTY, OFF_DUTY), safety_score, total_trips, total_km. Trip: trip_id, vehicle_id, driver_id, start_lat, start_lng, end_lat, end_lng, start_odometer, end_odometer, distance_km, duration_minutes, status (PLANNED, IN_PROGRESS, COMPLETED, CANCELLED), started_at, completed_at. MaintenanceRecord: record_id, vehicle_id, type (OIL_CHANGE, TIRE_ROTATION, BRAKE_SERVICE, INSPECTION, REPAIR), description, cost, performed_by, performed_at, next_due_km, next_due_date. Alert: alert_id, vehicle_id, type (LOW_FUEL, SPEEDING, HARSH_BRAKING, GEOFENCE_VIOLATION, MAINTENANCE_DUE), severity (INFO, WARNING, CRITICAL), details, triggered_at, resolved_at.

Real-Time Vehicle Tracking

Telematics device (OBD-II dongle or integrated ECU) sends GPS coordinates, speed, fuel level, and diagnostics every 5-30 seconds via cellular (4G/LTE) or satellite. Ingestion pipeline: device → MQTT broker (IoT-optimized pub/sub) → location processor → Redis (current position) + Kafka (stream for analytics) + TimescaleDB (time-series history). Why MQTT: low overhead (2-byte header), designed for constrained devices, supports QoS levels (at-least-once delivery for critical data). Redis key: HSET vehicle:{id} lat {lat} lng {lng} speed {speed} fuel {fuel} ts {timestamp}. Geospatial index: GEOADD fleet:vehicles {lng} {lat} {vehicle_id} for proximity queries (“find available vehicles near depot X”). Trip detection: detect trip start (speed > 5 km/h for > 30 seconds) and trip end (stationary > 3 minutes). Automatic trip boundary detection without driver interaction. Offline buffering: if cellular signal is lost, the device buffers data locally (flash storage) and uploads in batch when connectivity returns. Timestamps are device-generated, so historical data is accurate even after reconnection.

Predictive Maintenance

class MaintenanceService:
    MAINTENANCE_RULES = [
        {'type': 'OIL_CHANGE', 'interval_km': 8000, 'interval_days': 180},
        {'type': 'TIRE_ROTATION', 'interval_km': 10000, 'interval_days': 365},
        {'type': 'BRAKE_SERVICE', 'interval_km': 30000, 'interval_days': 730},
        {'type': 'INSPECTION', 'interval_km': None, 'interval_days': 365},
    ]

    def check_maintenance_due(self, vehicle_id: int) -> list[Alert]:
        vehicle = self.repo.get_vehicle(vehicle_id)
        alerts = []
        for rule in self.MAINTENANCE_RULES:
            last = self.repo.get_last_maintenance(vehicle_id, rule['type'])
            km_since = vehicle.odometer_km - (last.performed_at_km if last else 0)
            days_since = (date.today() - (last.performed_at.date() if last else vehicle.commissioned_date)).days
            due_by_km = rule['interval_km'] and km_since >= rule['interval_km'] * 0.9
            due_by_date = rule['interval_days'] and days_since >= rule['interval_days'] * 0.9
            if due_by_km or due_by_date:
                alerts.append(Alert(
                    vehicle_id=vehicle_id,
                    type=AlertType.MAINTENANCE_DUE,
                    severity=AlertSeverity.WARNING if (due_by_km and km_since < rule['interval_km']) else AlertSeverity.CRITICAL,
                    details=f'{rule["type"]} due: {km_since:.0f} km since last service'
                ))
        return alerts

Proactive alerts at 90% of the interval allow scheduling during low-demand periods. ML-based predictive maintenance: train on sensor data (vibration, temperature, oil quality estimates from driving patterns) to predict component failure before interval-based triggers. Reduces unplanned downtime by catching failures early.

Driver Behavior and Safety Scoring

Telematics data enables driver behavior analysis. Monitored events: speeding (speed > speed_limit + 10%), harsh braking (deceleration > 4 m/s²), harsh acceleration (acceleration > 3 m/s²), sharp cornering (lateral acceleration > 3 m/s²), distracted driving (detected via phone movement patterns on mobile apps), seatbelt compliance (from OBD data on modern vehicles). Safety score (0-100): start at 100. Deduct points per event: harsh braking = -1, speeding = -2, harsh cornering = -0.5. Scores reset weekly (rolling window). Coaching: weekly reports sent to drivers and fleet managers. Persistent low scores trigger in-app coaching videos or in-person reviews. Gamification: leaderboard among fleet drivers, bonuses for top safety scores. Geofencing: define zones (customer sites, restricted areas). Alert when a vehicle enters or exits a geofence. Use polygon geofence (list of lat/lng vertices); point-in-polygon check on each location update (ray casting algorithm, O(n) per update where n = polygon vertices).


{“@context”:”https://schema.org”,”@type”:”FAQPage”,”mainEntity”:[{“@type”:”Question”,”name”:”Why use MQTT instead of HTTP for telematics data from vehicles?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”MQTT is a publish-subscribe protocol designed for constrained IoT devices and unreliable networks. It has a 2-byte minimum overhead (vs HTTP's hundreds of bytes), supports Quality of Service levels (at-least-once delivery), handles intermittent connectivity gracefully with persistent sessions, and a single broker can handle millions of concurrent connected devices. HTTP request-response is too heavyweight for devices sending location updates every 5 seconds over cellular.”}},{“@type”:”Question”,”name”:”How does offline buffering work for vehicle telematics?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”When a vehicle loses cellular connectivity (tunnel, rural area), the telematics device stores location and telemetry data in local flash memory with device-generated timestamps. When connectivity is restored, the device uploads the buffered data in batch. The backend stores the data with the original device timestamps rather than the upload time, preserving accurate trip history. Gaps in the stream are filled by the buffered records rather than appearing as missing data.”}},{“@type”:”Question”,”name”:”How do you detect trip start and end automatically without driver input?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Trip start: vehicle speed exceeds a threshold (e.g., 5 km/h) for more than 30 consecutive seconds — filters out brief movements (parking lot maneuvering). Trip end: vehicle is stationary (speed < 2 km/h) for more than 3 consecutive minutes — filters out brief stops at traffic lights. The ignition signal (from OBD-II) can supplement speed-based detection for more accuracy. State machine: IDLE → MOVING (trip start) → IDLE (trip end).”}},{“@type”:”Question”,”name”:”How is driver safety score calculated from telematics events?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Start each driver at 100 points. Deduct points for detected events: harsh braking (deceleration > 4 m/s², -1 point), speeding (speed > limit + 10%, -2 points), harsh cornering (lateral acceleration > 3 m/s², -0.5 points). Events are detected from the accelerometer and GPS data stream in real time. Scores are computed over a rolling 7-day window — older events age out. Scores reset weekly so drivers can recover from bad days.”}},{“@type”:”Question”,”name”:”How do you implement geofence alerts for a fleet?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”Define geofences as polygons (list of lat/lng vertices stored in the database). On each location update, run a point-in-polygon test using the ray casting algorithm: cast a horizontal ray from the vehicle's position and count how many polygon edges it crosses — odd count means inside, even means outside. Compare to the vehicle's previous state (inside/outside). State change triggers an alert. For circular geofences, a simple distance check (Haversine) is sufficient.”}}]}

See also: Uber Interview Prep

See also: Lyft Interview Prep

See also: DoorDash Interview Prep

Scroll to Top