In a lot of transport offices there are two planning systems. One is the software. The other is a whiteboard, or a spreadsheet, or one person’s memory, and it tracks the things the software does not know about: which truck is free after the morning shift, which trailer is off the road until Thursday, whether the crew that needs 90 minutes to sanitise its equipment can make the next job.
The whiteboard exists because a vehicle in a plan is usually treated as a single indivisible thing, while in reality it is an assembly of scarce parts. A tractor unit. A trailer. A driver. Sometimes a specialised piece of equipment that only three depots own. Each part has its own availability, its own cost and its own rules about being handed on. Resource modelling in the Route Optimization OptiFlow API is how those parts get into the optimisation, and this release extends it in two directions.
Availability windows: when an asset can be used
Resources are a top-level list in the optimization request, alongside vehicles and orders. Each one has an id, a categories list — the same category mechanism used elsewhere in the API, and what a vehicle’s requiredResourceCategories matches against — and now an availabilities list. A window carries an earliestStart and a latestEnd as full date-times with an offset to UTC, plus an id of its own that has to be unique within the resource. A route that uses the resource must start and finish inside the same window.
That single rule covers the two situations that filled the whiteboard. The first is shift structure: a truck shared between an early and a late driver is available 05:00–13:00 as one window and 13:00–21:00 as another, and the optimiser will not produce a route that straddles them. The second is unavailability: a trailer in for maintenance from Thursday simply has no window on those days, so no plan reaches for it.
The “same window” part deserves emphasis, because it is what makes the constraint sound rather than approximate. The rule binds per route: each route using the resource must fit inside one window, start and end. It does not force every route sharing a resource into the same window — that is the point of defining several. A truck with a morning and an afternoon window can carry one route in each; what it cannot do is carry a single route that begins in the morning window and ends in the afternoon one. Combined with the older rule that a resource is never used by two vehicles at the same time, two drivers can hand a truck over between shifts but cannot both be halfway through using it.
Which window each route was given comes back in the result, as the availability identifier on the assigned resource. That matters for anything beyond a single call: if you feed a plan back in to be reconstructed or re-optimised, the resource identifier and the availability identifier both have to be supplied, or the second run has no way to know which window the first one committed to. Giving each window a meaningful id — a shift name rather than a number — makes those round trips much easier to read.
Two resource categories at once
The second extension is on the vehicle side. requiredResourceCategories now accepts two entries rather than one, so a vehicle can require a resource from a driver category and one from a trailer category at the same time.
This is how much of the industry is actually organised. Tractor units and trailers are pooled separately and matched per job. A crew and a lift are booked as a pair. Previously a single required resource category could represent whichever pool was scarcer, and the other was left to the whiteboard. With two categories the optimiser has to satisfy both pools at once, and the plan it returns is one that can actually be assembled on the yard on the morning it runs.
Two is the current limit, and for the overwhelming majority of operations it is the pairing that matters: the person and the equipment.
The pieces that were already there
These additions land on a resource model that already handles the rest of a shared asset’s behaviour. The core rule has been there from the start: a resource cannot be used by two vehicles at once, so routes sharing one must not overlap in time. Around that sit minimumBufferDuration, the gap required between consecutive assignments — the 90 minutes for equipment sanitisation, the turnaround for fuelling and inspection — a set of resource costs covering fixed, per-vehicle, over-vehicles and layover charges, and resource constraints including maximumVehicles and a cap on the total route duration a single resource may accumulate.
One interaction between those pieces is easy to miss: buffer durations are not bounded by the availability windows. A buffer may extend past the end of a window, which is the behaviour you want — the sanitisation after the last route of a shift does not have to finish before the shift does — but it means a window is not a hard boundary on everything associated with the resource, only on the routes that use it.
Put together with availability windows and dual categories, that is a working model of a shared fleet: who and what exists, when it can be used, how long it needs between uses, what it costs, and how many can be in play at once.
One piece of commercial mechanics is worth knowing before you model heavily with resources, because it surprises people at the wrong moment. Shared resources count as separate assets for licensing: the asset count for an optimisation is the sum of the vehicles and the distinct shared resources, so a run with 40 vehicles drawing on 40 trailers is not a 40-asset run. Note that it counts vehicles, not routes — a vehicle that ends up without a route still counts. Worth checking against your own plan limits early rather than discovering it during a load test.
What it changes at the desk
Utilisation is the visible gain. Assets held back as safety margin because their availability was tracked by hand can be released into the plan, and the reserve that a manual coordinator has to keep gets smaller. Conflicts stop being discovered on the yard.
The less visible gain is that re-planning becomes possible. A manually coordinated resource allocation is expensive to redo, so it tends to be done once and defended for the rest of the day. When availability lives in the model, a mid-morning change can be re-optimised with the resource picture intact, and the answer that comes back is still executable.
For teams building on PTV Developer, resources are also the natural join point between systems that already hold this data. Maintenance schedules, shift rosters, equipment calendars — all of them describe availability windows. Feeding those into the request means the optimiser reflects them without anybody transcribing anything, and it means the plan does not need a validation pass to catch double-booked assets.
When the pool becomes the bottleneck
Availability windows are hard boundaries. Narrow them tightly and the pool can become the binding constraint on the whole plan, with orders left unassigned not because there is no capacity in the vehicles but because there is no window left in the resources. That is the correct answer, and it is also useful information: it tells you which asset to add. Where the shape of the constraint is uncertain, it is worth starting from generous windows and tightening once you can see which resource is scarce.
Why it is pressing
Fleets are getting more expensive to own and more mixed in composition, so sharing is increasing rather than decreasing. Alternative-fuel vehicles introduce assets with genuinely limited availability — charging schedules, restricted range, specialised equipment at a subset of depots. Driver shortage means people are the scarcest resource in the assembly and their shifts are planned as carefully as the vehicles.
None of that is manageable on a whiteboard next to the planning system. It belongs inside it.
