> ## Content Index
> Fetch the complete content index at: https://blog.afi.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# GMPRO docs: Driver breaks
- URL: https://blog.afi.io/blog/gmpro-docs-driver-breaks/
- Published: 2024-11-23T07:46:00.000Z
- Updated: 2026-08-22T04:53:15.000Z
- Description: How to add driver breaks to a route using the Google Maps Platform Route Optimization API.
- Author: Afian Anwar
- Tags: googlemaps

Ever take a long road trip and feel like you need a short nap at a highway rest stop before getting back behind the wheel? Those little breaks aren't just nice - they're essential for keeping you refreshed and ready for the road ahead. Professional drivers feel the same way too, which is why the [Federal Motor Carrier Safety Administration](https://www.fmcsa.dot.gov/?ref=blog.afi.io) (FMCSA), part of the United States Department of Transportation, requires a 30-minute break for drivers after 8 hours of work. The European Union has similar rules, and [mandates a 45-minute break after 4.5 hours of driving](https://transport.ec.europa.eu/transport-modes/road/social-provisions/driving-time-and-rest-periods%5Fen?ref=blog.afi.io).

In this blog post, I’ll show you how to incorporate driver breaks into a route plan, ensuring they are accounted for when using the [Google Maps Platform Route Optimization API](https://developers.google.com/maps/documentation/route-optimization?ref=blog.afi.io) (GMPRO).

![Driver breaks (coffee icon) shown on a gantt chart](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/11/Screenshot-2024-11-17-at-5.38.49-PM.png)

Driver breaks (coffee icon) shown on a gantt chart

Part 1: [GMPRO: Google Maps Platform route optimization API](https://afi.io/blog/gmpro-google-maps-platform-route-optimization-api/?ref=blog.afi.io)  
Part 2: [GMPRO TSP solver: Google Maps with more than 25 waypoints](https://afi.io/blog/gmpro-tsp-solver-google-maps-with-more-than-25-waypoints/?ref=blog.afi.io)  
Part 3: [Google Maps route optimization: multi vehicle](https://afi.io/blog/google-maps-route-optimization-multi-vehicle/?ref=blog.afi.io)  
Part 4: [Fleet routing app - free Google Maps route planner for multiple stops](https://www.afi.io/blog/fleet-routing-app-free-google-maps-route-planner-for-multiple-stops/?ref=blog.afi.io)  
Part 5: [GMPRO docs: Fixed vehicle costs](https://afi.io/blog/gmpro-docs-fixed-vehicle-costs/?ref=blog.afi.io)  
Part 6: [GMPRO docs: Territory optimization and route planning](https://www.afi.io/blog/gmpro-docs-territory-optimization-and-route-planning/?ref=blog.afi.io)  
Part 7: [GMPRO docs: Solving the VRP with route clustering and soft constraints](https://www.afi.io/blog/gmpro-docs-solving-the-vrp-with-route-clustering-and-soft-constraints/?ref=blog.afi.io)  
Part 8: [GMPRO docs: Driver load balancing with soft constraints](https://afi.io/blog/gmpro-docs-driver-load-balancing-with-soft-constraints/?ref=blog.afi.io)  
**Part 9: GMPRO docs: Driver breaks (this article)**  
Part 10: [GMPRO docs: Complete deliveries before pickups in cargo bike logistics](https://www.afi.io/blog/gmpro-docs-complete-all-deliveries-before-pickups-in-cargo-bike-logistics/?ref=blog.afi.io)  
Part 11: [GMPRO docs: Force stop sequences using precedence rules](https://blog.afi.io/blog/gmpro-docs-force-stop-sequences-using-precedence-rules/)  
Part 12: [GMPRO docs: Cut cost / raise care with smart NEMT routing](https://blog.afi.io/blog/gmpro-docs-cut-cost-raise-care-with-smart-nemt-routing/)  
Part 13: [GMPRO docs: Routing for Demand Responsive Transport](https://blog.afi.io/blog/gmpro-docs-routing-for-demand-responsive-transport/)  
Part 14: [GMPRO docs: Squash durations and parking](https://blog.afi.io/blog/gmpro-docs-squash-durations-and-parking/)  
Part 15: [GMPRO docs: Google Large Vehicle Routing](https://www.afi.io/blog/gmpro-docs-google-large-vehicle-routing/?ref=blog.afi.io)

### What is a driver break?

A driver break is a planned pause in a route. The [GMPRO documentation](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel?ref=blog.afi.io#BreakRule) is even more specific, defining it as a *contiguous period of time during which the vehicle remains idle at its current position and cannot perform any visit*.

![Driver breaks shown as a scheduled pause in a driver's route](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/11/Screenshot-2024-11-19-at-4.52.31-PM.png)

Driver breaks shown as a scheduled pause in a driver's route

### How do I add driver breaks to my route?

In GMPRO, adding driver breaks to a route is as simple as specifying a `breakRule` in the `vehicle` object like this:

```JSON
{
    "breakRule": {
        "breakRequests": [
            {
                "earliestStartTime": "2024-07-08T17:00:00Z",
                "latestStartTime": "2024-07-08T17:00:00Z",
                "minDuration": "1800s"
            }
        ]
    }
}
```

The `breakRequests[]` array contains `breakRequest` (break) objects, each specifying the start time and duration of a break. To schedule multiple breaks, you can add additional `breakRequest` objects to the array. In the example below, the driver is scheduled for two breaks. The first at 5 pm UTC and the second three hours later, at 8 pm UTC.

```JSON
{
    "breakRule": {
        "breakRequests": [
            {
                "earliestStartTime": "2024-07-08T17:00:00Z",
                "latestStartTime": "2024-07-08T17:00:00Z",
                "minDuration": "1800s"
            },
            {
                "earliestStartTime": "2024-07-08T20:00:00Z",
                "latestStartTime": "2024-07-08T20:00:00Z",
                "minDuration": "1800s"
            }
        ]
    }
}
```

`earliestStartTime` is the earliest time that the break should start by, in UTC "Zulu" format.

`latestStartTime` specifies the latest possible time for the break to begin, provided in UTC "Zulu" format. To schedule a break at a fixed time, set both `earliestStartTime` and `latestStartTime` to the same value.

`minDuration` is the total time spent by the driver on break, in string format e.g. `"minDuration": "600s"` is 600 seconds, or 10 minutes.

👨‍💻

Screenshots in this blog post were taken with [GMPRO-viewer](https://gmpro-viewer.afi.dev/?ref=blog.afi.io) , using data imported via [GMPRO-json-converter](https://gmpro-json-converter.afi.dev/?ref=blog.afi.io). Both tools are free to use.

### GMPRO driver breaks example

Here's an example of a 30-minute break scheduled to start at 10:00 AM PST, incorporated into a delivery route in Vancouver, BC.

![Driver breaks shown as part of a route on the GMPRO-viewer app](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/11/Screenshot-2024-11-20-at-12.19.52-AM.png)

Driver breaks shown as part of a route on the GMPRO-viewer app

**Input**

```JSON
{
    "model": {
        "shipments": [
            {
                "deliveries": [
                    {
                        "arrivalLocation": {
                            "latitude": 49.3208826,
                            "longitude": -123.0710097
                        },
                        "duration": "600s",
                        "timeWindows": [
                            {
                                "startTime": "2024-07-08T16:00:00Z",
                                "endTime": "2024-07-08T19:00:00Z"
                            }
                        ]
                    }
                ],
                "loadDemands": {
                    "weight": {
                        "amount": "1"
                    }
                },
                "label": "yvr123"
            },
            {
                "deliveries": [
                    {
                        "arrivalLocation": {
                            "latitude": 49.313724,
                            "longitude": -123.0514561
                        },
                        "duration": "600s",
                        "timeWindows": [
                            {
                                "startTime": "2024-07-08T16:00:00Z",
                                "endTime": "2024-07-08T19:00:00Z"
                            }
                        ]
                    }
                ],
                "loadDemands": {
                    "weight": {
                        "amount": "1"
                    }
                },
                "label": "yvr789"
            },
            {
                "deliveries": [
                    {
                        "arrivalLocation": {
                            "latitude": 49.343481,
                            "longitude": -123.0863414
                        },
                        "duration": "600s",
                        "timeWindows": [
                            {
                                "startTime": "2024-07-08T16:00:00Z",
                                "endTime": "2024-07-08T19:00:00Z"
                            }
                        ]
                    }
                ],
                "loadDemands": {
                    "weight": {
                        "amount": "1"
                    }
                },
                "label": "yvr987"
            },
            {
                "deliveries": [
                    {
                        "arrivalLocation": {
                            "latitude": 49.3352081,
                            "longitude": -123.1453979
                        },
                        "duration": "600s",
                        "timeWindows": [
                            {
                                "startTime": "2024-07-08T16:00:00Z",
                                "endTime": "2024-07-08T19:00:00Z"
                            }
                        ]
                    }
                ],
                "loadDemands": {
                    "weight": {
                        "amount": "1"
                    }
                },
                "label": "yvr654"
            },
            {
                "deliveries": [
                    {
                        "arrivalLocation": {
                            "latitude": 49.3513846,
                            "longitude": -123.2631103
                        },
                        "duration": "600s",
                        "timeWindows": [
                            {
                                "startTime": "2024-07-08T16:00:00Z",
                                "endTime": "2024-07-08T19:00:00Z"
                            }
                        ]
                    }
                ],
                "loadDemands": {
                    "weight": {
                        "amount": "1"
                    }
                },
                "label": "yvr321"
            }
        ],
        "vehicles": [
            {
                "startLocation": {
                    "latitude": 49.3191441,
                    "longitude": -122.9522224
                },
                "loadLimits": {
                    "weight": {
                        "maxLoad": 5
                    }
                },
                "startTimeWindows": [
                    {
                        "startTime": "2024-07-08T16:00:00Z"
                    }
                ],
                "endTimeWindows": [
                    {
                        "endTime": "2024-07-08T19:00:00Z"
                    }
                ],
                "breakRule": {
                    "breakRequests": [
                        {
                            "earliestStartTime": "2024-07-08T17:00:00Z",
                            "latestStartTime": "2024-07-08T17:00:00Z",
                            "minDuration": "1800s"
                        }
                    ]
                },
                "label": "will-yvr",
                "costPerKilometer": 1
            }
        ],
        "globalStartTime": "2024-07-08T07:00:00Z",
        "globalEndTime": "2024-07-09T06:59:00Z"
    },
    "populatePolylines": true
}
```

**Output**

```JSON
{
    "routes": [
        {
            "vehicleLabel": "will-yvr",
            "vehicleStartTime": "2024-07-08T16:00:00Z",
            "vehicleEndTime": "2024-07-08T18:10:29Z",
            "visits": [
                {
                    "shipmentIndex": 1,
                    "startTime": "2024-07-08T16:12:11Z",
                    "detour": "0s",
                    "shipmentLabel": "yvr789",
                    "loadDemands": {
                        "weight": {
                            "amount": "-1"
                        }
                    }
                },
                {
                    "startTime": "2024-07-08T16:27:57Z",
                    "detour": "614s",
                    "shipmentLabel": "yvr123",
                    "loadDemands": {
                        "weight": {
                            "amount": "-1"
                        }
                    }
                },
                {
                    "shipmentIndex": 2,
                    "startTime": "2024-07-08T16:47:46Z",
                    "detour": "1908s",
                    "shipmentLabel": "yvr987",
                    "loadDemands": {
                        "weight": {
                            "amount": "-1"
                        }
                    }
                },
                {
                    "shipmentIndex": 3,
                    "startTime": "2024-07-08T17:37:27Z",
                    "detour": "4706s",
                    "shipmentLabel": "yvr654",
                    "loadDemands": {
                        "weight": {
                            "amount": "-1"
                        }
                    }
                },
                {
                    "shipmentIndex": 4,
                    "startTime": "2024-07-08T18:00:29Z",
                    "detour": "5660s",
                    "shipmentLabel": "yvr321",
                    "loadDemands": {
                        "weight": {
                            "amount": "-1"
                        }
                    }
                }
            ],
            "transitions": [
                {
                    "travelDuration": "731s",
                    "travelDistanceMeters": 7966,
                    "waitDuration": "0s",
                    "totalDuration": "731s",
                    "startTime": "2024-07-08T16:00:00Z",
                    "vehicleLoads": {
                        "weight": {
                            "amount": "5"
                        }
                    }
                },
                {
                    "travelDuration": "346s",
                    "travelDistanceMeters": 2383,
                    "waitDuration": "0s",
                    "totalDuration": "346s",
                    "startTime": "2024-07-08T16:22:11Z",
                    "vehicleLoads": {
                        "weight": {
                            "amount": "4"
                        }
                    }
                },
                {
                    "travelDuration": "589s",
                    "travelDistanceMeters": 4089,
                    "waitDuration": "0s",
                    "totalDuration": "589s",
                    "startTime": "2024-07-08T16:37:57Z",
                    "vehicleLoads": {
                        "weight": {
                            "amount": "3"
                        }
                    }
                },
                {
                    "travelDuration": "581s",
                    "travelDistanceMeters": 6408,
                    "breakDuration": "1800s",
                    "waitDuration": "0s",
                    "totalDuration": "2381s",
                    "startTime": "2024-07-08T16:57:46Z",
                    "vehicleLoads": {
                        "weight": {
                            "amount": "2"
                        }
                    }
                },
                {
                    "travelDuration": "782s",
                    "travelDistanceMeters": 12161,
                    "waitDuration": "0s",
                    "totalDuration": "782s",
                    "startTime": "2024-07-08T17:47:27Z",
                    "vehicleLoads": {
                        "weight": {
                            "amount": "1"
                        }
                    }
                },
                {
                    "travelDuration": "0s",
                    "waitDuration": "0s",
                    "totalDuration": "0s",
                    "startTime": "2024-07-08T18:10:29Z",
                    "vehicleLoads": {
                        "weight": {}
                    }
                }
            ],
            "routePolyline": {
                "points": "ks_lHbfmmV?l@s@??l@?LAp@L?F?rA@~@@x@A~AGJ?dAFdB?j@Az@AzAC?\\At@?v@?rAAlB@p@AdF?lB?b@CpC?lB?lBAv@?dD?zC?T?hC?PAdD?H?r@An@ArC?hA?t@?v@A`KAvB?f@Av@?fA?~@Gb@?^?N?pB@x@?XBjB@Z?h@@t@@lA@vA@v@BxBL|HH|H?LBlB@lBD~ED~E@n@@jAAnD?lB?r@?z@AdC?t@Av@?v@?lBAt@?nBCjBAnB?t@?vAAdBAtBC|EAdDAbDAtCChB?nA?|BAjBAzE?\\AdDAdB?p@AhBAtB?BAt@?v@?hB?B?j@?D?P?T@V@VDp@Ff@D^Ff@F\\BJF\\H\\FRDR`@zAj@|ATp@L\\?@L\\HVVr@t@xBL^JXNb@n@bBHTLTZl@bArBZj@pA~BnAxBTb@Vb@p@tAh@`A`@r@r@lANZr@bBTp@Np@TlAHdABl@@n@CbACh@ALGd@EZGh@G\\Mv@Kp@Kj@AFCP?DE`@Ej@?BEn@AZ?N?T?R?Z?NBj@@^@T@B@TH`ALlABVFv@JdA@HFt@Hz@Dd@@HFr@?@Db@B\\@^@\\?\\?B?@AVA\\CXCPMj@?DI\\GPCFGN]t@CFCDs@rAi@fAm@jAO\\M\\GLCFIVENENKd@W~AE^CXEh@Eh@?BEfA?@Ah@?f@AjAAd@?N?T?l@?l@?`@BjA@RFtADv@BdA?BD`@B\\DTNv@Lj@DNFVFVLd@Nn@FZFT?BDTFf@?p@?ZALAJCTEPITELGLEFEFGHEFABABABAD?De@TMFMFWNKLGLKPEJGPM\\IRQn@Md@CNITA@ETEJAHANAZA^Ih@El@?X?B?hA?D?X@|@A^?b@@lBAlAArC?X?JCbKAzAAPEr@?BAr@?@?J?j@?N?X?bA?d@Ab@ArBAvA?v@?t@?~@?p@?lECbA?lA?N@HBJ?v@?X?^Av@AfBAbCAjDA`ACtD?nBAhB?ZApAAnB?v@A~@MWKSJRLV?hB?lAAdD?v@?~@AlB?vAAh@AbBAt@Av@?t@Af@?nB?BAbB@RA\\?lA?D?n@AxA?zAAlCAz@AnBAlA?b@AtCCdDCfKC`BAJAJAFEJQf@GTA@Ql@Sj@A?e@zAOd@K^M`@e@vAUj@ADe@tAAD{BxGM`@KKKM{@w@OOk@k@[YSMGCSGA?MCa@?eA?kBCcBAC?_@?gAAuAAO?k@AK?e@AM?sACK?aAAI?a@?UAI?O?Y?[A?t@?R?x@?t@?r@?\\AF?N?j@?BAv@?D?p@D?d@@z@B?cB?mA?cA?e@@iDUAI?O?Y?[A[?kACU?sAEc@A{@AkBAiBAsB?}A@cBEiBAeBAiBAeBCmB?yACeBEoA@M?_BAAtA?v@AdD?t@Aj@?H?h@?dA?rAiAEc@CmAEI?o@Ai@?M?W?E?E?S?S@_@AaAAcCBc@@O@QFK?gACS?eBCc@?kBAs@Ac@?c@AQ?E?MAeAC@v@@|@?dD?v@AdD?vB?zE?JAzF?nA?^?dCApD?hA?lB?dDAlBAzA?tA?t@?v@@lB?v@?t@?pD?`D?@?t@A|E?v@?v@eACA?cBCS?A?wC@U?wAAq@Be@@]AMAIAICGCIEICGEGEIGiCcBuDcCcBkAkAu@gAo@qAy@On@It@Iz@INCHBIHOH{@Hu@No@pAx@fAn@jAt@bBjAtDbChCbBHFFDFDHBHDFBHBH@L@\\@d@Ap@CvA@T?vCA@?R?bBB@?dAB~ABhB?v@?N?hAB@?dA@vBBjAAPFjBB\\@lA@@l@?N?f@?F?F@d@?h@@T@\\@`@Bh@?BD|@@j@Bf@HzC?B?@HPAxA?vAAt@?x@A~A?TA`@?J?`@AR?p@ChBA^CpBAf@C~@An@A~@?XAd@?L?XA^?p@A~@Al@Ab@?ZAv@?LAf@?@Ab@Ad@Aj@Al@?PChACnAAX?`@Aj@A@A~@Ab@Ab@Af@?h@CdAA`AAp@A`@Ad@?^Af@C`BAh@AxAAvB?`A?r@?f@A|A?rA?\\?R?|E?f@?L?d@?z@?b@?j@?h@?|@?l@?Z?lA?~@?`AAlC?N?dC?rB?fB?nA?`@?hA?v@?hA?z@?~A?pA?|@?\\?h@?|@?j@?Z?^?d@?N?T?b@A`@?h@AZAFA`@Eb@?FEXG`@GZADI^K\\M\\EHIPM\\MTOZa@t@k@hACBOVQ\\]n@S`@U`@GL]n@QZOXQZOXOXQ\\O\\MVOXIPEJOZEFIP]r@MVMVKTEHWh@EFMZOVUNA@EHINa@r@i@`AQZKROZ]v@Qb@CFEJUp@Od@[dAM`@Mj@Mv@Gj@SxACZA^Cj@Ch@ClAChA?JCz@A|@AZ?`@AN?`AChBAr@CzCA`A^?r@@T@f@@pAEfAEP?PAh@?LA@?XIvB@H?|@@l@@z@@@x@?z@Az@?NAf@?J?h@A`@?FAD?DCDADE@C@C@Q?S@O?_@@I?[@S?O@G@S@G@UFSHURA?EHEDOPEHIJGLENG^I\\CTCRCTAXA^Af@?@?P?rA?tB?j@@H?J?H@HDh@B^@D?F?D?|@?F?p@?|@?n@?jA?lB?lB?lBAv@?lB?t@AlD?n@xA?zA??u@?o@?n@?t@{A?yA?}ACwA?_BC[@U?c@?@PAb@?l@?`B?T?vAAdE?J?F?xA?R?xAArB?t@?t@?@?L?X?N?L?h@@r@Al@?z@?pA?nA?Z?j@?^?^?h@?B?Z?`AAlA@H?H?~@?D?r@Aj@?P?n@?bB?J?lBS?gAAe@?s@?cA?U?cA?EAQAwA?{A?w@?c@?k@?q@?OAKAIAGAECGCIAICIEKEIGQOKKKKIMKOKOGMWw@AEKa@IWK_@CUAEEUEYAYM?E?C@A?EBA@A@A@A@CDCFADAD?@AB?D?HAN?H?`@?T?f@?F?n@?X?D?t@?VA`@?R@`@?v@AH?^?\\?|@?^ATAb@?VAH?@?BFXGfAAPCf@C`@Ch@C^Ch@APAHC`@A^Ch@Cb@AHARCf@AZEh@Cb@A\\?@Cd@CZ?F?BC\\Cf@Cb@AP?@AJA`@C\\Cd@Cd@C^Cf@A^Cd@ATEh@A^A`@?BAXCl@?XAh@Ab@Af@?\\Ah@?h@?X@`@?b@@^?J@\\@d@@b@?L@L@L@\\@d@Bd@@X?@FnABz@Bd@FdB@X@l@?@B`ABhA@b@@fA@f@?X?b@?^?H?Z?h@?^?@Af@?`@A`@?TAl@Af@A^A^Ch@A\\Ad@CV?DCd@Ab@Cb@C^IdAGbAGbAIhAGbACh@AXCf@A^AVCl@Aj@AXAb@Af@A\\A`@Aj@CdAAt@Ad@A\\C`BChAAn@Cp@Az@AHAbAAH?@Ap@?FAVAZ?@Cb@A\\ALATCb@Eb@?FCXGd@EXEXGb@I\\I^Mf@GVOd@O`@M^O^Q^MXS\\KT]p@S^Q\\Yj@S^CFEJO\\MVO\\MZKZM^GREPK\\I^CNCLK`@In@Kr@C`@E^Cb@Cf@Cb@A`@A`@Cb@Ad@?^Ab@?JEhCCjB?@?d@AbAAbA?B?|A?fB?B?n@?`@@h@?`@?`@@fA@b@?b@?B@^@hAB~@?JBz@@f@@b@@T@j@B`@B`ABd@@d@DhAB`@HhB@b@Dl@Bv@?FF|@@f@?@Bb@Bf@@ZFdA@b@FfA@ZB`@Bn@DdAFdABz@@FD~@D|@Bz@@BB|@FpAD`A@DBn@ZvGD`A?H@L@Z@L?LBd@Bh@@b@@^?DB^@b@@bA@fA@`@?N?N@h@?l@?T?d@A`@?d@?h@Ab@?JAX?^Ad@Ah@C`AAf@AZCx@?HCpAE~BAd@Cd@Av@Av@EhBGnBA^Ab@C`@A`@Cd@C^Cd@C\\?BE^APAPGx@Gh@KfAE\\Ed@ABE\\E\\Gd@E\\G`@G^EVCHE\\GXAFIb@EVAFG^ShAG`@I`@G^G\\G\\G^Ib@Kh@G`@Ib@Ib@AFCJCPG`@I`@G^G^ANCNAFEXIf@AFE\\Gd@CTCNGd@K`AG`@Ed@E^C`@Gb@Eb@Ed@C`@C^Ed@C\\Cb@Eb@C`@GhACb@A^Ef@Ab@Cb@A`@A^Cd@Ab@Aj@AZ?FAh@Ah@Af@Ad@?f@?d@Aj@?b@?f@?p@?\\?H?b@?h@BlC?Z?l@@x@?X?L?b@@`@?b@?`@@b@?b@?d@@b@?`@?f@@`@?`@?f@@`A?f@A`@?b@AZAd@Ad@C`@Cb@Eb@E\\G`@G`@?BGXCLCRCHGTI`@IZM^ITOJA??BEJ]|@Qb@g@pA?@gApCMb@Qj@[fA[nA[bBCJO|@G`@ENGJCDCBCBE@G@C@C?I?ME?VKtCEnB?NSjDC\\Gn@ABKr@a@|CMt@Ib@UdA?@CJUz@Qj@KXCJA?O^U^CBGHILONOLIBIDSFg@LC?E@YFGBMBo@JI@m@J{@De@D]A[Gw@MaBYsAYa@IOCSGSGMGWOGGg@i@kAyAYa@A?m@w@i@c@YUECi@]s@SG?iAGgAFcAXE@m@b@_@n@Ud@M`@E\\CTAZ?JDbAB\\Fp@?BF^PtAF|@@bAARC|@CrA@f@B`@Dt@@L@V@N@DBZ?D?L@p@?DA`@?BANANCXOv@If@G`@Gd@ANATIpA?BEh@AJIh@CHQh@M\\CJAFAD?J?LBFFJFHJHHDPDP@RARKNKHSLa@Hm@Hc@HQDIPOPMRGFATCD?d@A^Cx@Bb@@R@N@b@@b@@X@H@D@JHJJHNRv@FT@DLRJHVNRPJB^LZNFD^Td@f@Z`@TXJPJN\\ZXVNJB@\\J@?ZBh@?XYR]VeANi@Pm@DKLc@@ARi@J]@?h@mALUFKNSBAVSFALCR?TD`@LVLLFHJHSHKFCL?LBD@PHn@`@Z^RPHJVXt@z@HJVb@@@Rl@Rl@@DNr@Dj@D^?V@t@@rA?X@v@?x@@j@"
            },
            "breaks": [
                {
                    "startTime": "2024-07-08T17:00:00Z",
                    "duration": "1800s"
                }
            ],
            "metrics": {
                "performedShipmentCount": 5,
                "travelDuration": "3029s",
                "waitDuration": "0s",
                "delayDuration": "0s",
                "breakDuration": "1800s",
                "visitDuration": "3000s",
                "totalDuration": "7829s",
                "travelDistanceMeters": 33007,
                "maxLoads": {
                    "weight": {
                        "amount": "5"
                    }
                }
            },
            "routeCosts": {
                "model.vehicles.cost_per_kilometer": 33.007
            },
            "routeTotalCost": 33.007
        }
    ],
    "metrics": {
        "aggregatedRouteMetrics": {
            "performedShipmentCount": 5,
            "travelDuration": "3029s",
            "waitDuration": "0s",
            "delayDuration": "0s",
            "breakDuration": "1800s",
            "visitDuration": "3000s",
            "totalDuration": "7829s",
            "travelDistanceMeters": 33007,
            "maxLoads": {
                "weight": {
                    "amount": "5"
                }
            }
        },
        "usedVehicleCount": 1,
        "earliestVehicleStartTime": "2024-07-08T16:00:00Z",
        "latestVehicleEndTime": "2024-07-08T18:10:29Z",
        "totalCost": 33.007,
        "costs": {
            "model.vehicles.cost_per_kilometer": 33.007
        }
    }
}
```

Information about the break(s) can be found in the `route` object in the response. In the `breaks` array, you'll find:

```JSON
{
    "breaks": [
        {
            "startTime": "2024-07-08T17:00:00Z",
            "duration": "1800s"
        }
    ]
}
```

Structurally, breaks are a type of `transition` (time interval in between `visits`), so they are also included in the `transitions` array of each `route` object.

```
{
    "travelDuration": "581s",
    "travelDistanceMeters": 6408,
    "breakDuration": "1800s",
    "waitDuration": "0s",
    "totalDuration": "2381s",
    "startTime": "2024-07-08T16:57:46Z",
    "vehicleLoads": {
        "weight": {
            "amount": "2"
        }
    }
}
```

### Sequencing breaks and visits

While a `break` is not technically a `visit` (it does not have a fixed location), it is often helpful to treat it as one when presenting routes to drivers.

![Driver breaks shown on the Routific (left), Parcelizer (middle) and Sparqle (right) driver apps](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/11/Screenshot-2024-11-25-at-10.59.14-AM.png)

Driver breaks shown in apps for Routific (left), Parcelizer (middle) and Sparqle (right)

To achieve this, we simply combine breaks and visits into a single list and sort them by their `startTime`. Here's how to do this for one route. First, create a new folder `/route_printer`, and save `gmpro_driver_breaks_output.json` to it. This file contains the [response](https://developers.google.com/maps/documentation/route-optimization/interpret-response?ref=blog.afi.io) from an API call to the GMPRO `/optimizeTours` endpoint.

[gmpro\_driver\_breaks\_outputgmpro\_driver\_breaks\_output.json11 KBdownload-circle](https://blog.afi.io/content/files/2024/11/gmpro%5Fdriver%5Fbreaks%5Foutput.json "Download")

In your favorite text editor, create a new file `printRoute.js`. Add the code below and save the file in the same folder as `gmpro_driver_breaks_output.json`.

```javascript
/*** printRoute.js ***/
const fs = require('fs').promises;

async function loadJsonFile(filePath) {
    try {
        const fileData = await fs.readFile(filePath, 'utf8');
        const jsonObject = JSON.parse(fileData);
        
        // Print visits and driver breaks for a single driver
        console.log("*** " + jsonObject.routes[0].vehicleLabel + " ***");
        const visitsAndBreaks = sortVisitsAndBreaks(jsonObject.routes[0].visits, jsonObject.routes[0].breaks);
        printVisitsAndBreaks(visitsAndBreaks);

        return jsonObject;
    } catch (error) {
        console.error('Error loading JSON file:', error);
        return null;
    }
}

function sortVisitsAndBreaks(visits, breaks) {

    const visitsAndBreaks = [...visits, ...breaks];
    return visitsAndBreaks.sort((a, b) => new Date(a.startTime) - new Date(b.startTime));

}

function printVisitsAndBreaks(arr) {
    for (const obj of arr) {
        if (obj.hasOwnProperty('shipmentLabel')) {
            console.log(`${obj.shipmentLabel} : ${obj.startTime}`);
        } else {
            console.log(`break : ${obj.startTime}`);
        }
    }
}

// Call the function with the file path
loadJsonFile('gmpro_driver_breaks_output.json');

```

The code above reads a JSON file `gmpro_driver_breaks_output.json` and converts its contents into a Javascript object.

```javascript
/*** printRoute.js ***/
const fs = require('fs').promises;

const fileData = await fs.readFile(filePath, 'utf8');
const jsonObject = JSON.parse(fileData);
```

Next, we extract the `visits` and `breaks` array from the output JSON and use the `...` spread operator to merge them into a single array. This array is then sorted by their `startTime` in ascending order.

```
/*** printRoute.js ***/
function sortVisitsAndBreaks(visits, breaks) {

    const visitsAndBreaks = [...visits, ...breaks];
    return visitsAndBreaks.sort((a, b) => new Date(a.startTime) - new Date(b.startTime));

}
```

Finally, the array is specially formatted and printed out to show both `breaks` and `visits`, together with their respective `startTimes`.

```bash
*** will-yvr ***
yvr789 : 2024-07-08T16:12:11Z
yvr123 : 2024-07-08T16:27:57Z
yvr987 : 2024-07-08T16:47:46Z
break : 2024-07-08T17:00:00Z
yvr654 : 2024-07-08T17:37:27Z
yvr321 : 2024-07-08T18:00:29Z
```

### Scheduling a driver break at a specific location

If you need a driver to take his break at a specific location e.g. a truck rest stop or a gas station, you should instead a create a dummy `shipment` with a well defined time window and add a high `penaltyCost` (the cost of not delivering this `shipment`) to it and a much lower `penaltyCost` everywhere else. This will force the GMPRO solver to include the break in the final route solution.

```
{
    "deliveries": [
        {
            "arrivalLocation": {
                "latitude": 49.6312767,
                "longitude": -121.0725622
            },
            "duration": "1800s",
            "timeWindows": [
                {
                    "startTime": "2024-07-08T16:00:00Z",
                    "endTime": "2024-07-08T16:30:00Z"
                }
            ]
        }
    ],
    "penaltyCost": 9001,
    "label": "lunch-break@coquihalla-lakes-rest-area"
}
```

### Have a driver break, have a Kit Kat

Driver breaks are crucial for two main reasons: they ensure drivers remain well-rested and help your fleet stay compliant with national regulations. After reading this post, you should know [how to include driver breaks in a GMPRO API call](https://developers.google.com/maps/documentation/route-optimization/reference/rest/v1/ShipmentModel?ref=blog.afi.io#BreakRule) and integrate them optimally into driver schedules. They can also be used to plan [multi day routes with overnight stays](https://www.drivemyway.com/blog/a-truck-drivers-guide-to-pd-routes-vs-longhaul-runs/?ref=blog.afi.io), but that is a topic for a different blog post altogether.

Next: [Part 10: MPRO docs: Complete deliveries before pickups in cargo bike logistics](https://www.afi.io/blog/gmpro-docs-complete-all-deliveries-before-pickups-in-cargo-bike-logistics/?ref=blog.afi.io)

**This article was written by** [**Afi Labs**](https://afi.io/?ref=blog.afi.io)**, a** [**Google Maps Premier Partner**](https://www.afi.io/?ref=blog.afi.io) **and reseller. We build route optimization, navigation, and fleet tracking software on Google Maps, and offer volume pricing on GMP licensing.** [**Talk to an engineer**](https://www.afi.io/contact%5Fus?ref=blog.afi.io) **or** [**follow Afian on LinkedIn**](https://www.linkedin.com/in/afian-anwar/?ref=blog.afi.io)**.**