Skip to main content
Not every fleet can serve its full daily demand in a single loop. When total demand across a wave of orders exceeds the fleet’s total capacity, resources need to return to the depot, reload, and go out again — potentially several times — inside their workingTimeWindow. Nothing about this requires a dedicated field: it’s a modeling pattern built from capacities and stop kind, the same primitives covered in the data model.
Before modeling multi-trip tours, check whether you actually need them, using the exact test from the agent modeling checklist (§2, “Check capacity feasibility before modeling orders”): sum your stops’ capacities per dimension and compare against your fleet’s total capacity in a single loop. That test is a strict binary, not a margin call — total demand either fits within total fleet capacity (single-loop, no reload needed) or exceeds it (single-loop is infeasible, not merely suboptimal; the shortfall shows up as unplanned stops, not an error). Even then, this modeling is only justified if the client’s own data or context confirms the fleet genuinely reloads at a depot mid-shift.

The core mechanic: pair each delivery with its own depot pickup

Rather than pre-computing a fixed number of “reload rounds” per vehicle, pair every delivery with a pickup of the same cargo at the depot, inside the same order. The "depot:main" tag used below is an arbitrary stop tag your integration defines to mark same-site pickups — it doesn’t reference a Depot API object; see Depot vs. position.
Each order lists its stops in a fixed sequence — the depot pickup first, then the customer delivery — and both are always served by the same vehicle. Because the pickup loads exactly what the delivery unloads, each pair leaves the vehicle’s load unchanged once both stops are done; in between, it only takes up room for that one delivery’s cargo. This has two advantages over planning a few large reload stops sized to the vehicle’s full capacity:
  • No fixed round count. The engine is free to chain any number of these pairs on a single resource, going back to the depot as many times as the schedule and capacity allow — you don’t need to guess in advance how many rounds each vehicle needs, or leave unused "optional": true reload orders on the table.
  • No per-vehicle sizing. Each pickup carries only its own delivery’s cargo (here 130 kg and 3 piles), so it fits on any vehicle with room for that one delivery, whether the fleet is mixed or uniform. A large reload stop sized to one vehicle’s full capacity would only fit that vehicle, or a bigger one, so you’d have to reserve it for that vehicle with a skills / requiredSkills pair. Here nothing needs reserving: whichever vehicle the engine assigns the delivery to also gets the matching pickup, because both stops belong to the same order.
If you also want to force or bias which stops happen before versus after each other (for example, a fixed morning sector followed by a fixed afternoon sector), combine this with tagged phases and the maximizePrecedences objective. That’s a separate concern from the preceding capacity mechanic.

Charging depot time once per visit, not once per pickup

With one pickup stop per delivery, a vehicle loading five deliveries’ worth of cargo before a round would otherwise pay operationDuration five times over for what is physically a single dock visit. Keep each pickup’s operationDuration negligible (as in the preceding example) and instead charge the real access time once per visit with the plan-level accessDurationsByStopTag field:
This adds the duration once, before the first of a run of consecutive stops sharing the tag — matching a single loading operation at the dock, regardless of how many individual pickups happen during that visit. See Data model for the full field.

Limiting simultaneous depot visits

A physical depot usually has a limited number of loading docks or bays, and can’t serve every vehicle at once. Tag every pickup stop with a shared depot tag (as in the preceding example) and limit simultaneous presence with overlappingCapacitiesByStopTag at the plan level. The objectives list below is a variant built for this example, not the platform default — see The default list for the actual default sequence:
This sets a limit of 2 resources simultaneously present at any stop tagged depot:main — matching, for example, a depot with two loading docks. It’s a soft limit: minimizeOverOverlappingCapacitiesOnStops minimizes any overrun, so how firmly the engine keeps to it depends on where that objective sits in objectives (here right after minimizeDelay). Because every load in this pattern is an explicit tagged stop that’s part of an order — including the first load of the day, not just later reloads — the limit applies uniformly from the very first pickup, with nothing left uncovered. departure and arrival (see Depot vs. position) are only used for the resource’s idle start/end-of-day position; they carry no cargo and no tag, so keep the actual loading out of them entirely.
Without a fairness objective, the engine can load one or two resources up to their limit on repeated depot rounds while others in the fleet sit comparatively idle — all while still satisfying maximizeMandatoryStops and the delay/cost objectives ahead of it. Include minimizeLargestTourDuration (see minimizeLargestTourDuration) to cap how unbalanced the longest single tour can get relative to the rest of the fleet — it’s placed after minimizeResources, described earlier, so fleet size is still minimized first, but tour lengths are then balanced across whatever fleet size that settles on.
If resources are arriving back at the depot and then waiting idle for their next reload window, consider setting the plan-level lateDeparture: true (see Plan-level fields) so the engine compacts departure timing to reduce that idle wait, instead of always having resources leave as early as possible.

Limiting how many times a resource returns to the depot

overlappingCapacitiesByStopTag (preceding section) limits how many resources are simultaneously at the depot — a different question from how many times one resource returns there over the whole tour. For the latter, use the maxStopTagGroups additional constraint:
This limits how many separate visit groups a tagged resource can make to stops sharing the depot:main tag over the whole tour — the two mechanisms can be combined. A common pattern: leave internal resources free to return to the depot as many times as the schedule needs, but cap subcontractor resources (resourceTags) to a single daily depot visit.

See also