Design goal
Design a ride-hailing system that stays correct when:
- GPS is imperfect
- Apps background or crash
- Payment processors retry
- Operators change fees and zones without a full redeploy
Happy path
- Rider requests a vehicle tier in a service area
- Matching finds nearby eligible drivers (H3-oriented areas, tier fallbacks)
- Driver accepts → arrive → PIN → trip in progress
- Trip completes →
trip.completed - payment-service charges the rider →
payment.completed - Driver earnings recorded idempotently → weekly Connect payouts
Critical boundaries
[Driver / Rider clients]
│ REST │ WS
▼ ▼
api-gateway realtime-gateway
│ │
domain services location / trip
│
RabbitMQ events → payment → Stripe
→ notify → FCM/SMS/email
Matching
Matching is physics plus policy: location quality, vehicle tier, service area, and driver presence. Client UX must surface assignment state quickly even when the transport mix includes polling.
Reliability patterns
- Idempotent earnings keyed by trip
- Cancel settlement sealed before payment side effects
- Active-trip recovery on the driver client
- RuntimeConfig for operational change without redeploy
- Service-owned databases so billing schema changes do not lock trip writes
Scaling posture
Early infrastructure is cost-aware (EKS, Helm, ArgoCD, observability with OpenTelemetry/Prometheus/Grafana). The design prioritizes correctness and operability before premature horizontal drama. Capacity assumptions in infra docs are planning inputs — not published product KPIs — so this portfolio does not invent ride counts or GMV.
Decision principles
- Prefer clear ownership over shared convenience
- Isolate money and realtime from the REST request path
- Treat recovery and reconnect as product features
- Document what you did not build alone