Inspiration

Late deliveries are one of the most common (and most frustrating) failure points in food delivery — a five-minute miscalculation in routing or a sudden rain shower can turn a 20-minute order into a cold, late one. We wanted to build a system that didn't just assign couriers to orders, but actually optimized those assignments in real time using live conditions like traffic, weather, and courier location — and then let us simulate "what if" scenarios to see how well the system holds up under pressure. That's how OptiDelivery was born.

What it does

OptiDelivery is a delivery management platform that intelligently matches couriers to orders based on real-time location, route data, and weather conditions. At its core is a cost function scored for every candidate (courier, order) pair:

$$w_{ko}(c,o) = \alpha \cdot T(c,o) + \beta \cdot \text{payout}(o)$$

where $T(c,o)$ is the weather-adjusted travel time — pickup leg plus drop-off leg, scaled by a vehicle-specific rain multiplier $\mu(v)$ (bikes get hit harder by rain than cars, motorcycles land in between):

$$T(c,o) = \mu(v_c)\big[\tau_{\text{pickup}}(c,o) + \tau_{\text{dropoff}}(c,o)\big]$$

Every pair is also checked against two hard feasibility constraints — can the courier make the restaurant's deadline, and does the trip fit inside their remaining shift — accounting for the fact that a courier can't pick up food before the kitchen has it ready:

$$t_{\text{deliver}} = \max(t_{\text{now}} + \mu\,\tau_{\text{pickup}},\ t_{\text{ready}}) + \mu\,\tau_{\text{dropoff}}$$

Infeasible pairs are excluded; feasible ones are handed to the Hungarian algorithm (scipy.optimize.linear_sum_assignment), which solves the global objective:

$$\min_{x} \sum_{c \in C}\sum_{o \in O} w_{ko}(c,o)\, x_{c,o} \quad \text{s.t.} \quad \sum_{o} x_{c,o} \le 1,\ \sum_{c} x_{c,o} \le 1,\ x_{c,o} \in {0,1}$$

This guarantees the assignment that minimizes total cost across the entire fleet at once, rather than each courier greedily grabbing their own best-looking order — which can leave the system as a whole worse off.

The platform tracks the full lifecycle of a delivery — from restaurant pickup to drop-off — and automatically updates courier performance stats (earnings, completed deliveries, late deliveries, time worked) as orders are fulfilled. On top of that, it includes a simulation engine so we can model different demand and weather scenarios and see how the assignment logic performs before it ever touches a real order.

How we built it

We used Supabase (Postgres + Auth + Row Level Security) as our backend foundation, with a Python service layer handling the heavier logic — route calculations, weather lookups, and simulation runs. Database triggers automatically create a user profile on signup and keep courier stats up to date whenever a delivery is marked complete, so the app layer doesn't have to manually track that state. Route and weather data get cached (route_cache, weather_snapshots) to avoid hammering external APIs on every request — turning an expensive live lookup into a lightweight table read for repeat queries — and RLS policies ensure couriers can only see and edit their own profile data.

Challenges we ran into

Keeping the database schema resilient was harder than expected — re-running migrations during active development kept hitting "already exists" errors for tables, policies, and triggers, which forced us to build proper reset scripts and get disciplined about idempotent SQL. Syncing real-time courier state (location, shift status) with asynchronous events like weather changes and order completions also took a few iterations to get right, especially making sure stats updates via triggers stayed accurate even when deliveries were marked late or completed out of order.

Accomplishments that we're proud of

We're proud of building a fully automated stats pipeline — courier earnings, minutes worked, and on-time performance update themselves the moment a delivery is marked complete, with zero manual bookkeeping needed in the app layer. We're also proud of the simulation engine, which lets us stress-test the assignment algorithm against different conditions instead of just hoping it works in production.

What we learned

We learned a lot about designing database schemas that are both secure (via RLS) and resilient to iteration, and about how much complexity lives in "simple" real-world problems like delivery routing once you factor in live weather and traffic — and how a clean cost function and a well-known solver (Hungarian algorithm) can cut through that complexity instead of hand-rolling heuristics. We also came away with a much better appreciation for building idempotent, re-runnable database scripts from day one instead of bolting that on later.

What's next for OptiDelivery

Next, we want to incorporate live traffic data alongside weather to make ETAs even more accurate, build a courier-facing mobile view for real-time job offers, and expand the simulation engine to support multi-day demand forecasting so restaurants and couriers can plan staffing ahead of time.

Share this project:

Updates

Submission history