real-time-nemt-dispatch-platform@operr:~/case-study
Healthcare Logistics 8 months 2021

Real-Time NEMT Dispatch Platform

@ Operr — Software Engineer

Optimizing non-emergency medical transportation with intelligent real-time dispatch and route optimization

40% Better Utilization
25% Reduced Wait Times
10K+ Daily Rides

$ cat PROBLEM.md

Manual Dispatch Couldn't Handle Complexity

NEMT transportation involves complex constraints: appointment times, vehicle types (wheelchair, stretcher), driver certifications, and real-time traffic. The existing phone-based dispatch system led to inefficient routing, missed appointments, and underutilized drivers. Dispatchers were overwhelmed during peak hours.

Key Challenges:

  • 🔴 Dispatchers manually matching rides to drivers using paper logs and phone calls
  • 🔴 No visibility into real-time driver locations or availability
  • 🔴 Appointment times missed due to poor route planning
  • 🔴 Vehicle type mismatches — ambulatory patients assigned stretcher vehicles

$ cat SOLUTION.md

Event-Driven Dispatch with Intelligent Route Optimization

We built a real-time dispatch platform using Spring Boot microservices and Kafka, with a custom route optimization engine that considers all NEMT-specific constraints.

Technical Approach:

1
Event-Driven Architecture

Every ride request, driver location update, and status change flows through Kafka. The system reacts in real-time to changing conditions.

2
Constraint-Aware Matching

Custom matching algorithm considers vehicle type, driver certifications, appointment windows, and predicted traffic to find optimal assignments.

3
Real-Time Driver Tracking

GPS integration provides live driver locations. Geofencing triggers automatic status updates when drivers approach pickup/dropoff locations.

4
Predictive ETA Engine

ML model trained on historical trip data provides accurate ETAs that account for time-of-day, weather, and route-specific patterns.

$ cat tech-stack.json

🚀 Core Technologies

Spring Boot

Microservices framework

Why: Mature ecosystem, excellent Kafka integration, enterprise-grade reliability

Apache Kafka

Event streaming and messaging

Why: Real-time event processing with replay capability for debugging

PostgreSQL + PostGIS

Ride data and geospatial queries

Why: Powerful geospatial functions for location-based matching

🔧 Supporting Technologies

Redis GraphHopper React Native

☁️ Infrastructure

AWS (EKS, MSK, RDS) Kubernetes DataDog

$ cat ARCHITECTURE.md

The platform uses event-driven microservices:

1
2
3
4
5
Ride Request → API Gateway → Matching Service → Driver Assignment
     ↓              ↓               ↓                 ↓
   Kafka        Validation      Optimization      Notification
                    ↓               ↓                 ↓
                Driver App   Route Engine      Real-time Map

System Components:

Ride Service

Manages ride lifecycle from request to completion

Matching Service

Constraint-aware driver-ride matching engine

Location Service

Real-time driver tracking and geofencing

Route Service

ETA calculation and turn-by-turn navigation

$ man implementation-details

Building the Matching Engine

The matching algorithm had to balance multiple competing objectives:

Hard Constraints (must satisfy):

  • Vehicle type matches patient needs
  • Driver has required certifications
  • Can reach pickup within time window

Soft Constraints (optimize):

  • Minimize total miles driven
  • Balance workload across drivers
  • Prefer drivers familiar with the route

Implementation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Service
public class MatchingService {
    
    public Optional<Assignment> findBestMatch(Ride ride) {
        return availableDrivers.stream()
            .filter(d -> meetsHardConstraints(d, ride))
            .map(d -> scoreAssignment(d, ride))
            .max(Comparator.comparing(Assignment::getScore));
    }
    
    private double scoreAssignment(Driver driver, Ride ride) {
        double score = 0.0;
        
        // ETA score (closer is better)
        score += 100 - (eta.getMinutes() * 2);
        
        // Driver utilization balance
        score += (averageUtilization - driver.getUtilization()) * 10;
        
        // Route familiarity bonus
        if (driver.hasCompletedSimilarRoute()) {
            score += 15;
        }
        
        return score;
    }
}

Real-Time Location Processing

Processing driver locations at scale required careful optimization:

Location Update Flow:

  1. Driver app sends GPS every 10 seconds
  2. Location Service validates and enriches data
  3. Published to Kafka driver-locations topic
  4. Multiple consumers: matching, geofencing, ETA recalculation

Geofencing for Auto-Status:

  • 100m radius around pickup → “Arriving” notification
  • At pickup location > 2 min → Auto “Waiting” status
  • 100m radius around dropoff → Prepare for completion

Redis for Hot Path:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Latest driver location (hot cache)
redisTemplate.opsForGeo()
    .add("driver-locations", 
         new Point(lon, lat), 
         driverId);

// Find drivers within 5 miles of pickup
Circle searchArea = new Circle(pickupPoint, 
                               new Distance(5, MILES));
GeoResults<String> nearby = redisTemplate.opsForGeo()
    .radius("driver-locations", searchArea);

$ echo $RESULTS

40% Improvement in Driver Utilization

40% Driver Utilization More rides per driver per shift
25% Reduced Wait Times Patients picked up faster
98% On-Time Performance Rides arriving within appointment window
10K+ Daily Rides Platform handling NYC metro volume

Additional Outcomes:

  • Dispatchers went from overwhelmed to strategic, handling 3x ride volume
  • Vehicle type mismatches reduced to near-zero
  • Driver satisfaction improved with fair, optimized assignments

$ cat LESSONS_LEARNED.md

Constraints Are Features, Not Bugs

NEMT constraints (vehicle types, certifications, appointment windows) seemed like obstacles but became competitive advantages when properly encoded in the matching algorithm.

Real-Time Requires Tolerance for Imperfection

We built the system to gracefully handle delayed GPS updates, network issues, and driver app crashes. Eventual consistency was acceptable for most operations.

Driver UX Determines Adoption

The best algorithm means nothing if drivers don't use the app. We invested heavily in a simple, one-tap interface for common actions.

$ cat README.md

Want Similar Results?

Let's discuss how I can help solve your engineering challenges.