Most operations run cost efficiency and driver fairness as two different projects. One lives in route optimization and cost-per-delivery targets. The other lives in HR policy, manual rotation, and whatever a planner remembers about who worked a hard week.
Run separately, they compete for the same routes, tighten the plan for cost and someone absorbs the difference, protect a driver from hard stops and the numbers absorb it instead. Run on the same real data, that competition mostly disappears, because both problems were downstream of the same missing input the whole time.
This shows up in what the plan knows, not in which goal it's chasing.
Both goals are guesses when the underlying data is a guess
A route optimizer that assumes every stop takes about the same effort is guessing at cost. A workload policy that has no record of which stops were harder is guessing at fairness. Among the reasons these end up in tension, both are usually running on the same thin foundation, a flat average standing in for what a stop really requires, so tightening one guess and loosening the other feels like the only two options available.
Traffic and local conditions are only half of what a plan usually gets right
Most routing tools have gotten good at modeling the road, traffic, distance, drive time between stops. Far fewer model what happens once the vehicle stops moving, and fewer still connect that to what a similar stop has taken before, on that street, in that building, for that kind of order. A plan that knows the road well but guesses at the stop is only solving half the estimate, and it's the half that determines both the cost of the route and how hard that route was to run.

Cumulative history is what turns a guess into something worth trusting
Take a stop that needs ID verification at the door, the kind of requirement a flat average never accounts for.
- Logged once, it just looks like a slow stop. Maybe the recipient wasn't ready yet.
- Logged forty times over six months at the same kind of address, it's a pattern. That verification step reliably adds several minutes, not zero.
- That one record now settles two questions at once. For cost, the plan can price that stop at what it takes instead of the average. For fairness, it shows that whichever driver keeps drawing verification stops has been quietly carrying minutes the schedule never counted.
A single day's data can't tell you whether a stop is reliably hard or just unlucky today. Weeks and months of the same stop, the same building, the same order type, can. It isn't two data sets serving two goals, it's one record answering both questions at once.
Without that record, tightening for cost and protecting for fairness pull against each other
This is the trade-off most operations live with by default. Optimize hard for cost per stop, and the hardest stops concentrate on whoever completes them fastest, a pattern worth its own look. Pad routes generously to prevent that instead, and the padding shows up as slower, costlier routes across the board, whether a given stop needed the extra time or not. Neither choice is wrong given what the plan knows. The trade-off exists because the plan doesn't know enough, not because fairness and efficiency are opposed.
This isn't specific to one type of delivery
A grocery operation with a mix of attended and unattended deliveries faces this exact tension. So does a big and bulky operation weighing installation time against route cost, and a direct-store delivery network balancing production schedules against driver hours. Among operations with any real variation in stop difficulty, the underlying pattern tends to hold, cost and fairness get treated as competing priorities right up until the plan has enough real history to stop guessing at either one.

The takeaway
Before treating cost and fairness as two separate initiatives, check whether they're running on two separate guesses, a route optimizer estimating averages, and a workload policy relying on memory. If both are guessing, fixing one without the other will keep feeling like a trade-off it doesn't have to be.

