Ride marketplaces fail when demand spikes: users churn if pricing is slow or unfair, drivers churn if they cannot get rides. This system keeps the marketplace balanced by reacting to supply/demand changes within a 30s freshness window.
Real-world impact
- Fast pricing: <100ms responses even under high reads.
- Fairness: dynamic H3 resolution avoids overpricing short rides and underpricing long rides.
- Transparency: users see nearby drivers, improving trust and conversion.
- Driver updates go to Kafka (
driver-locations). - Consumer writes driver presence into Redis (ZSET with timestamps).
- Rider booking computes distance, selects H3 resolution, and calculates surge from request/driver ratio.
- Driver availability returns nearby drivers + active ride requests.
See ARCHITECTURE.md for full details.
Resolution changes based on trip distance:
- Short trip → finer grid (higher resolution)
- Long trip → broader grid (lower resolution)
- Mid trip → default resolution
Default thresholds (configurable in application.yml):
short-trip-km-threshold: 5.0long-trip-km-threshold: 20.0min-h3-resolution: 7max-h3-resolution: 9
This reduces unfair pricing when a short trip lands inside a large geofence.
basePrice = distanceKm * pricePerKm
ratio = requestCount / driverCount
if driverCount == 0: surge = 3.0
elif ratio <= 1.0: surge = 1.0
else: surge = min(1 + ratio/2, 3.0)
finalPrice = basePrice * surge
./mvnw spring-boot:run
cd frontend
npm install
npm run dev
Open http://localhost:5173.
while true; do
curl -s -X POST http://localhost:8081/rider/book \
-H "Content-Type: application/json" \
-d '{"riderId":"rider_live","pickupLat":29.3446,"pickupLng":79.5644,"dropLat":29.3806,"dropLng":79.4636}' \
| python - <<'PY'
import json,sys
data=json.load(sys.stdin)
print("surge:", data["surgeMultiplier"], "final:", data["finalPrice"],
"drivers:", data["nearbyDrivers"], "ratio:", round(data["ratio"],2),
"res:", data["resolution"], "geofence:", data["geofenceId"])
PY
sleep 2
done
redis-cli --scan --pattern "geofence:*:*:drivers"
redis-cli ZCARD "geofence:<RESOLUTION>:<GEOFENCE_ID>:drivers"
redis-cli ZCARD "geofence:<RESOLUTION>:<GEOFENCE_ID>:requests"
redis-cli ZRANGE "geofence:<RESOLUTION>:<GEOFENCE_ID>:requests" 0 -1
POST /driver/locationPOST /driver/location/batchGET /driver/availability?lat=...&lng=...POST /rider/book
- Realtime surge updates (WebSockets/SSE)
- Push price changes to the rider UI without rebooking.
- Horizontal scale
- Multiple app nodes behind Nginx / load balancer.
- Distributed Redis
- Regional Redis clusters to reduce latency + cost.