Skip to main content

Driver breaks

Both the SWAT Optimization API and Integration API support driver breaks, allowing dynamic allocation to align with operational needs or legal requirements. For example, Route Optimization can incorporate the length of required breaks after specific driving durations into its execution plan while respecting other set constraints. Two main use cases apply, which can be used in a mutually exclusive manner when simulating the addition of driver breaks to optimization:

  • Single driver break for a vehicle trip
  • Multiple driver breaks for a vehicle trip

Parameters discussed below can be configured via both the Optimization (Stateless) API payload, where they are applied directly to a vehicle object api, and the Integration (Stateful) API, where they are set on the Vehicle resource, for example during bulk vehicle upload via /api/v2/microservices/bulk/task api.

{
"agent_id": "78e07d0f-abbc-4c7d-921e-54ba7bab1041",
"capacity": {
"goods": 13
},
"characteristics": {},
"lat": 1.3309909478620003,
"lon": 103.86845911685897,
// Single and multi break case
"dynamic_break_duration": 3600,

// Single break case
"dynamic_break_min_path_duration": 120,
"dynamic_break_start_time": "2019-08-24T14:15:22Z",
"dynamic_break_end_time": "2019-08-24T14:15:22Z",

// Multi break case
"dynamic_break_avg_time_between_breaks": 360,
"dynamic_break_max_latency": 0,
"max_pickup_locations": 10
}
tip

The planned driver break is ultimately added to the node's slack and is regarded as standard slack (waiting time) at a node for route optimization purposes.

Setting dynamic_break_avg_time_between_breaks to a specific value determines whether to use single or multiple driver break mode. When this value is unset, single driver break is applied. Otherwise, multiple breaks mode is applied. Driver breaks are applied at the node level, not the booking level.

Driver breaks are permitted only at nodes

assigned to the vehicle. The time allocated for driver breaks is added to the node's slack time. The break node is selected from one of the nodes in the path with the greatest slack. The break node cannot be the first or the last in the path, and never a depot or a vehicle position node. If slacks are identical, the break node is selected to be as close as possible to the middle of the path in prebook_cvrptw mode, or to be the node with the fewest trips in progress in prebook mode.

warning

Driver break is a hard constraint. If a requirement to have an allocated driver break is in force, some bookings may be refused if they are no longer meeting additional time constraints assumed by the driver break.

The exception is the break post-processing path, where breaks become a soft constraint that penalises lateness instead of rejecting work.

Single break

Single break scenario assumes that there is only one or no break allowed for a single vehicle trip (optimization run) for a vehicle. Driver break is managed by four parameters:

  • dynamic_break_duration in seconds
  • dynamic_break_min_path_duration in seconds
  • dynamic_break_start_time as date\time stamp
  • dynamic_break_end_time as date\time stamp

Conditions for adding a break

A break will be added if either one of these conditions is met:

  1. The path duration (combined vehicle travel time, nodes' slack time, and nodes' service time) exceeds dynamic_break_min_path_duration.
  2. dynamic_break_min_path_duration is not set, but dynamic_break_duration is set.

If the vehicle path has only a single node, no driver break will be added.

Break placement

The solver will try to place the break at the midway point of the total trip duration & bias toward nodes with long slack time.

If dynamic_break_end_time is set, the solver will try to add a break before dynamic_break_end_time - dynamic_break_duration.

info

The solver ensures that the full break duration fits within the constraints. For example, if both dynamic_break_start_time and dynamic_break_end_time are specified, the break will start no earlier than dynamic_break_start_time and end no later than dynamic_break_end_time. To get exact break start timestamps in the response, enable calculate_break_start_times.

Scenarios

Possible permutationsUsecase
Only dynamic_break_durationMandatory Wellness Break: A standard break assigned to every trip to ensure driver well-being, regardless of trip duration.
dynamic_break_duration with dynamic_break_start_timeScheduled Lunch: A meal break that follows a schedule, such as "Lunch cannot be taken before 11:30 AM", ensuring coverage during morning peaks.
dynamic_break_duration with dynamic_break_end_timePre-Peak Rest: A break that must be completed before a critical time window, like finishing a rest period before the 5:00 PM evening rush hour begins.
dynamic_break_duration with dynamic_break_min_path_duration & dynamic_break_start_timeLate Shift Rest: A break conditioned on a long shift (e.g., > 6 hours) that is pushed to the latter half of the day (e.g., starts after 2:00 PM). Note: The break is placed after the start time even if the minimum path duration is met earlier.
dynamic_break_duration with dynamic_break_min_path_duration & dynamic_break_end_timeWindow-Constrained Long Haul: A break for long trips that must occur within a specific service window, such as using a rest facility before it closes. Note: The end time constraint is respected even if it forces the break before the minimum path duration is fully met.

The dynamic_break_start_time and dynamic_break_end_time parameters define a time window within which the driver break can be scheduled. It's possible to specify only the maximum or minimum time boundary, in which case only that constraint will be enforced.

Multiple breaks

Multiple break scenario assumes that there could be multiple, one or no breaks allocated to a vehicle for a single trip (optimization run). Driver break is managed by three parameters in this case:

  • dynamic_break_avg_time_between_breaks in seconds
  • dynamic_break_duration in seconds
  • dynamic_break_max_latency in seconds

The dynamic_break_duration parameter specifies the duration of the breaks that should be scheduled. Each planned break will have the same duration.

The dynamic_break_avg_time_between_breaks parameter governs the maximum average time a vehicle can drive without a break. It encompasses the cumulative vehicle travel time, node slack time, and node service time in its computation. There is no prescribed minimum interval between breaks, thereby allowing for multiple consecutive breaks at the same node.

Using dynamic_break_max_latency, a driver's break constraint can be transformed into a more flexible constraint that tolerates tardiness. This value specifies the maximum allowable delay for the break. If you do not set it, it defaults to half of dynamic_break_duration.

How breaks are calculated

Break planning always happens in two stages:

  1. Placement — deciding which gap in the route each break sits in, and how many breaks there are.
  2. Start time calculation — deciding the precise clock time each break begins. See Break start time calculation.

Stage 1 has two entirely different implementations. Which one runs depends on your lateness settings, and they do not honour the same set of parameters.

In-solver placement (default)

Normally breaks are a constraint inside the routing solver. The solver carries a trip-duration dimension with a break variable attached to every node, so break feasibility is evaluated during the route search itself — a candidate route that cannot fit its mandatory break is rejected as the search explores it. This is why breaks are described above as a hard constraint, and why enabling them can cause bookings to be rejected.

Placement rules in this mode:

  • Single break mode uses a node-selection strategy: the break goes to a node with non-zero slack, preferring one midway along the path in prebook_cvrptw mode, or the node with the fewest trips in progress in prebook mode.
  • Multiple breaks mode enforces the average interval between breaks, with dynamic_break_max_latency as the tolerance for overshooting it.
  • Breaks are never placed on depot or vehicle position nodes.

Break post-processing

There is a second implementation — sometimes called soft dynamic breaks — that removes breaks from the routing search entirely and inserts them afterwards, in a separate constraint-solving pass over the finished routes.

It activates only when all of the following hold:

  • Break post-processing is enabled in the deployment (BREAKS_POSTPROCESSING_ENABLED).
  • At least one vehicle has dynamic_break_duration set.
  • calculation_parameters.allow_vehicle_late is true.
  • calculation_parameters.max_possible_lateness is not set — lateness must be unbounded.
This is a deployment setting, not a request parameter

BREAKS_POSTPROCESSING_ENABLED is an environment setting on the solver service and is off by default. You cannot switch paths from a request payload — the request only influences the decision through allow_vehicle_late and max_possible_lateness. If you need to know which path a given environment uses, check with the SWAT team.

When this path is taken, the routing solver is told to ignore breaks completely. Routes are optimized break-free, and only then does the post-processing pass choose a break arc per vehicle and shift the schedule to accommodate it.

Because the routes were already fixed before breaks were considered, the model cannot reject work to satisfy a break. Instead it minimises a weighted cost made up of total break time, total slack, and a lateness penalty scaled by vehicle_late_penalty_coefficient, with node finalization types nudging arrival times earlier or later. Lateness beyond a node's close time is penalised rather than forbidden — hence "soft".

Post-processing rewrites the schedule and can silently yield no breaks

This model may adjust scheduled_ts and slack on nodes across the route, not just insert a break — so arrival times can differ from what the routing stage produced.

If this pass cannot find a solution, the error is logged and the routes are returned with no breaks at all rather than failing the request. If it exceeds its time limit (BREAKS_POSTPROCESSING_TIME_LIMIT, 30 seconds by default) the optimization fails outright.

Parameter support by path

Not every break parameter is read by both implementations. This is the most common source of "why is my break parameter being ignored" questions:

ParameterIn-solverBreak post-processing
dynamic_break_durationYesYes
dynamic_break_avg_time_between_breaksYesYes
dynamic_break_min_path_durationYes, single break mode onlyYes, single break mode only
dynamic_break_start_time / dynamic_break_end_timeYes, single break mode onlyYes, single break mode only
dynamic_break_max_latencyYes, multiple breaks modeIgnored
dynamic_break_consider_slack_as_breaksYes, multiple breaks mode, logistics path constraints onlyIgnored
dynamic_break_restart_slack_limitYes, with dynamic_break_consider_slack_as_breaksIgnored
dynamic_break_allow_between_identical_locationsYes, multiple breaks mode, logistics path constraints onlyIgnored

Note that the break time window and minimum path duration apply to single break mode only in both implementations. Setting dynamic_break_start_time on a vehicle that also has dynamic_break_avg_time_between_breaks has no effect on placement.

When no break is produced

Both implementations skip a vehicle entirely — returning a route with no break rather than an error — when:

  • dynamic_break_duration is not set on the vehicle.
  • The path has only one node, or fewer than two nodes between the start and end node.
  • The path duration is shorter than dynamic_break_min_path_duration.
  • Every node in the path is scheduled before dynamic_break_start_time, or every node after dynamic_break_end_time.
  • In multiple breaks mode, the path is shorter than dynamic_break_avg_time_between_breaks.

Break start time calculation

Placement only settles which gap each break occupies. A separate pass then derives the precise clock time each break begins, and populates break_start_ts in the result. It works for both single and multiple break scenarios, and runs regardless of which placement path was used.

Within the chosen gap, the earliest a break may start is the break node's scheduled arrival plus its service time plus any compound zone exit time; the latest is the next node's scheduled arrival minus that node's zone entry time and the break duration. The break must fit entirely inside that window.

Two behaviours are worth knowing:

  • Single break mode may place the break either before or after the break node is serviced. The model is biased toward taking it after service, and only moves it before service when that is the only way to satisfy dynamic_break_start_time / dynamic_break_end_time.
  • Multiple breaks mode always places breaks after service, and distributes them by minimising deviation from evenly spaced intervals measured from the vehicle's start time. The vehicle-level break time window is not applied in this mode.

If this model cannot find a solution the error is logged and break_start_ts is left unpopulated; exceeding BREAK_START_TIMES_SELECTION_TIME_LIMIT (30 seconds by default) fails the optimization.

Enabling

Set calculate_break_start_times in your engine settings:

engine_settings → calculation_parameters
{
"engine_settings": {
"calculation_parameters": {
"calculate_break_start_times": true
}
}
}
Using the Integration (Stateful) API or logistics pipeline?

You do not need to set this flag. The SWAT logistics pipeline enables break start time calculation automatically for every optimization run. This setting is only relevant when calling the Optimization (Stateless) API directly.

Response

When enabled, break_start_ts will be populated with a list of exact break start timestamps — one per break scheduled at that node.

{
"dynamic_break": true,
"dynamic_break_time": 7200,
"break_start_ts": [
"2022-08-01T15:30:00.000000+00:00",
"2022-08-01T17:30:00.000000+00:00"
]
}

When disabled, break_start_ts will not be populated.

Interpreting results

Optimization (Stateless) API

In the Optimization (Stateless) API, drivers' break schedules can be found within the vehicle assignments list, which enumerates all nodes assigned to a vehicle api.

warning

A booking requires association with two nodes (pickup and drop-off). Due to route optimization, a vehicle may perform multiple pickups and drop-offs. Consequently, vehicle route assignment is handled at the node level. The Optimization (Stateless) API provides a sequential list of nodes assigned to the vehicle, not bookings.

The following example showcases two breaks assigned at a single node. The response indicates dynamic_break as true and details the total break duration in dynamic_break_time (e.g., 7200 seconds for two 1-hour breaks). The break_start_ts provides a list specifying the exact start timestamps for each break. The value denoted by slack signifies the overall waiting time at that particular node, which in this instance incorporates the total dynamic_break_time plus any remaining standard node slack.

{
"booking_uid": "some_booking", // Booking UID this node belongs to
"dynamic_break": true,
"dynamic_break_time": 7200,
"break_start_ts": [
"2022-08-01T15:30:00.000000+00:00",
"2022-08-01T17:30:00.000000+00:00"
],
"lat": 30.0,
"location_code": null,
"location_name": null,
"lon": 130.0,
"matrix_timestamp": null,
"node_type": "pickup",
"scheduled_cumulative_distance": 0,
"scheduled_ts": "2022-08-01T14:34:18.600504+00:00",
"service_time": 0,
"slack": 18349.5,
"stop_id": "warehouse",
"uid": "some_uid" // This node's UID
}

If dynamic_break is set to null or false, no break is scheduled at that node.

Integration (Stateful) API

In the Integration (Stateful) API, drivers' break schedules are returned within the break_info property of the Node object (e.g., when retrieving routes or simulation results).

Instead of flat fields like dynamic_break and break_start_ts, the stateful API groups all break segments under break_info.driver_break_list. Each entry in this list specifies the exact start_time and duration of the break applied at this node. Standard waiting time is still accounted for separately on the node, but the break details are explicitly segregated here for easier parsing.

{
"uid": "some_node_uid",
"node_type": "pickup",
"break_info": {
"driver_break_list": [
{
"start_time": "2022-08-01T15:30:00Z",
"duration": 3600
},
{
"start_time": "2022-08-01T17:30:00Z",
"duration": 3600
}
]
},
"close_time_offset": 18349
}

If no break is scheduled at a node, the break_info property will be null or contain an empty driver_break_list.

info

break_start_ts is only populated when calculate_break_start_times is enabled. When disabled, dynamic_break and dynamic_break_time are still returned but exact start timestamps will not be available.

note

If calculate_break_start_times is not set (the Stateless API default), the result will still show dynamic_break and dynamic_break_time to indicate which node the break is attached to and how long it lasts — but no break_start_ts clock time will be returned.

Breaks under manual edits

Everything above describes how breaks are planned during an optimization run. When a dispatcher subsequently edits a route through the Manual Edit Actions API, that planned break schedule is no longer guaranteed to hold.

Manual edits do not preserve breaks by default

Break handling during manual edits is gated by logistics_api_settings.logistics_break_info_handling_enabled, which defaults to false. While it is false, any manual edit clears break_info from the nodes it modifies, so a compliant break plan can disappear the first time a route is touched.

This setting also controls whether calculate_break_start_times is applied to the solver calls that manual edits make — so with it disabled, manual edits produce no break start timestamps either.

Even with the setting enabled, the guarantees differ by action. Only vehicle_assign_booking_list and shift_nodes_time_windows re-plan breaks against the full constraint set. vehicle_reorder_nodes and vehicle_shift_nodes re-derive breaks arithmetically using only dynamic_break_duration and dynamic_break_avg_time_between_breaks — the break time window, minimum path duration, and maximum latency are ignored.

Single break mode is not maintained by reorder or shift

Because the arithmetic recalculation requires dynamic_break_avg_time_between_breaks to be set, and single break mode is selected precisely by leaving that parameter unset, reordering or shifting the route of a single-break vehicle removes its planned break. Multiple breaks mode is unaffected.

See Driver Breaks and Manual Edits for the full per-action breakdown.

FAQ

Some common use cases are explained below

Q: How do I model a situation where a driver has to take a 30-minute break when a trip exceeds 4 hours, assuming there's only one driver break during the trip?
A: The vehicle assigned to the driver must have the following parameters configured. If the planned vehicle path is less than four hours, no breaks will be scheduled. Additionally, breaks can be allocated at any point along the path (attached to a node) because start and end-time constraints are not set.

{
// ...
"dynamic_break_duration": 1800,
"dynamic_break_min_path_duration": 14400
// ...
}

Q: Can you provide examples of scenarios involving multiple driver breaks with varying slack and service times, given that the break duration (dynamic_break_duration) is set to 30 minutes and the time between breaks (dynamic_break_avg_time_between_breaks) is set to 4 hours?
A: Please see the following time diagrams

Scenario 1: Travel 5h

Scenario 2: Slack 5h + Travel 5h

Scenario 3: Slack 2h + Travel 3h

Scenario 4: Service 1h + Slack 1h + Travel 3h

Scenario 5: Multi-stop

Playground

You can try out the Driver Break concept using the playground below. The example defines a vehicle with a dynamic_break_duration of 3600 seconds (1 hour).

Loading...