objectives list isn’t a set of weights. It’s a ranking: the engine compares two candidate solutions one objective at a time, in the order you give, and the first objective that separates them decides which one wins. This page explains that comparison, what each objective measures, and how to choose an order for your own operation.
How two solutions are compared
The engine looks at the first objective in the list. If one solution is better on it, that solution wins — whatever happens on every later objective. Only when the two solutions are tied on the first objective does the engine look at the second, and so on down the list. No amount of improvement on a later objective can make up for a loss on an earlier one. There are no weights to tune and no exchange rate between objectives: the position in the list is the only lever. Take three candidate solutions for the same plan:
With the default order (
maximizeMandatoryStops, then minimizeDelay, then … minimizeResources):
- C loses straight away: it plans one mandatory stop fewer, even though it’s better on every other line.
- A and B tie on mandatory stops, so delay decides: B wins, even though it needs an extra vehicle.
minimizeResources ahead of minimizeDelay and A beats B instead: you’ve told the engine that fleet size matters more than on-time delivery, so it lets stops run late to avoid dispatching an extra vehicle. C still loses under both orders, because maximizeMandatoryStops stays first.
The default list
If a plan doesn’t setobjectives, the engine uses this order:
overlappingCapacitiesByStopTag limits; then more optional stops; then more stops matched to a resource’s preferredStopTags; then less total working time; then less distance.
Treat it as a starting point to check against your plan, not a template to copy. Several entries do nothing unless your plan declares the data they measure (see each objective below), and an objective your operation cares about may be missing from it.
Built-in objectives
Each built-in objective is a plain string in the list. The ones marked needs data measure something your plan has to declare: without it, the objective has nothing to optimize, doesn’t raise an error, and the comparison simply falls through to the next entry. Drop those from the list rather than keeping a guaranteed no-op.maximizeMandatoryStops
Maximizes the number of mandatory (non-optional) stops planned. First in the default list, so nothing ranked after it can justify leaving a mandatory stop unplanned. A mandatory order with a very lowpriority still counts here: a low priority doesn’t let an order be dropped from this count, only "optional": true does (see maximizeOptionalStops).
minimizeDelay
Minimizes the sum of delays against stops’preferredTimeWindows. Only lateness counts: the engine never plans a stop before its preferred window opens, so arriving early is never traded against it. Needs data: at least one preferredTimeWindows. A plan whose windows are all hard authorizedTimeWindows has no delay to minimize — see Hard vs soft constraints.
minimizeCosts
Minimizes the plan’s total cost, as defined by each resource’scost object (a flat using cost per resource used, per-kilometre km, per-hour workedHours, per-capacity costs, and so on). Needs data: at least one resource with a cost. See Cost modeling.
minimizeResources
Minimizes the number of resources used. When some resources have to stay unused,Resource.priority decides which ones go first (lower numbers matter more). It counts resources directly: no using cost is needed for it to work.
minimizeOverOverlappingCapacitiesOnStops
Minimizes how far the limits set inoverlappingCapacitiesByStopTag are exceeded — the number of resources simultaneously present at stops sharing a tag, beyond the limit set for that tag. The limit is a soft target, not a hard cap: whether the engine accepts an overrun to do better elsewhere depends on where this objective sits in the list. Needs data: plan-level overlappingCapacitiesByStopTag. See Limiting simultaneous depot visits.
maximizeOptionalStops
Maximizes the number of optional stops planned, in addition to the mandatory ones. Marking an order"optional": true takes it out of maximizeMandatoryStops, so this objective is the only reason the engine plans it: without it in the list, an optional stop is unlikely to be planned at all, since it adds distance and time without serving any other objective. In the default order it comes after minimizeResources, so the engine never adds a vehicle just to plan an optional stop. Needs data: at least one order marked "optional": true.
maximizePreferredStops
Maximizes the stops served by a resource whosepreferredStopTags match the stop’s tags — a soft preference, where another resource can still take the stop when that does better on a higher-ranked objective. Needs data: at least one resource with preferredStopTags matching some stops. See Driver skills and qualifications.
minimizeLargestTourDuration
Minimizes the working duration of the single longest tour in the fleet — travel, service, and waiting time included — which narrows the gap between that tour and the others. Not in the default list. It’s an objective the engine improves as far as it can, not a limit it enforces: use a resource’smaxWorkingDuration for a hard bound.
minimizeWorkingDuration
Minimizes the total working duration summed across every tour, travel, service, and waiting time included.minimizeDistance
Minimizes the total distance travelled, summed across every tour.minimizeEarlyLoadings
Minimizes early loadings, as declared per resource inavoidEarlyLoadings or per resource tag in the plan-level avoidEarlyLoadingsByResourceTag: each declaration names a stop tag, and optionally the capacities to consider. Not in the default list: add it explicitly, or the declarations have no effect. Needs data: at least one such declaration.
Object entries
Two kinds of entries are objects rather than names.maximizePrecedences
Rewards the engine for respecting “this stop tag before that stop tag” rules. It takes aprecedences array of pairs, each with a previous and a next stop tag, and the engine tries to satisfy as many pairs as possible. As an objective, it’s a preference, not a hard rule: a stop’s position inside an order’s stops array is the only precedence the engine always enforces.
Custom objectives
Acustom entry optimizes a cost expression of your own, built from costsByResourceTag, in the direction you choose (minimize or maximize), under a name that must not collide with a built-in objective. When a custom objective replaces minimizeCosts, put it at the exact position minimizeCosts held: anywhere else, it’s traded off against different objectives and can return a different plan. See Cost modeling.
Choosing an order
- Put first what you’d never trade away. For most operations that’s
maximizeMandatoryStops: nothing ranked after it can then justify leaving a mandatory stop unplanned. - Check every adjacent pair, not just the first two. Swapping any two neighbours changes which solutions win.
minimizeCostsbeforeminimizeResourcesprioritizes total cost even if reaching it takes an extra vehicle; the reverse caps fleet size first and lets cost settle wherever that leaves it. - Drop the objectives your plan gives no data to, and add the ones it needs:
minimizeLargestTourDurationto balance tours,minimizeEarlyLoadingsfor declared early loading rules. - Keep preferences in objectives, rules in constraints. A hard constraint is never traded off, whatever the order; only soft constraints are arbitrated by the list. See Hard vs soft constraints.
Reading objectives in a solution
A solution reports the achieved value of each objective inobjectives, with its name, direction (minimize or maximize), and value. Values are in each objective’s natural unit: for example a count of planned stops for maximizeMandatoryStops, a count of resources for minimizeResources, kilometres for minimizeDistance, and hours for minimizeWorkingDuration. Comparing these values between two versions of a plan shows which objective an update actually moved.
See also
- How the optimization engine works — the time/quality trade-off and how updates re-optimize a plan.
- Hard vs soft constraints — what the objectives arbitrate, and what they never bend.
- Cost modeling — giving
minimizeCostsand custom objectives something to optimize. objectivesin the API reference — the field’s schema.

