How to optimize route operations in multiple market locations

Whether you operate in multiple market locations or want to expand into new ones, simple scenario testing can help you make decisions about vehicle fleet size, composition, and capabilities.

As your business grows, so does the number of moving parts. This can translate to everything from managing multiple fleets of vehicles (e.g., two different fleets of cars) to accounting for different business rules and constraints when assigning routes (e.g., all drivers must take breaks in one location but not the other). All of that (and more!) can make managing a business that relies on routing operations — from food delivery to ridesharing — in multiple market locations challenging.

When you’re ready to expand into new geographic markets, you may ask questions like: 

  • What should my fleet look like? Should I use a mix of cars and bikes?
  • How many vehicles do I need given assumptions around min and max order volumes?
  • How do I account for different business rules for a new region?
  • Do I need to take into account real-road distances when calculating ETAs in a new region?

First, let’s get clear on what we mean by a market location. A market location is any geographic area that is serviced by the same fleet of vehicles and adheres to the same set of business rules (e.g., all drivers must take breaks). A market location does not have to be a single city. It can be a part of a city like a neighborhood or even a combination of multiple neighborhoods or cities. What matters here is that one fleet services the market location and the same business rules apply each time routes are generated.

The good news: if this sounds familiar, you’re not alone. We often hear from our customers some version of: “I operate in one city, but I’m launching in another. How do I optimize routes for both at the same time?” The answer, simply put, is: “You don’t.” 

Wait, what? 

What we mean by this is, you don’t optimize routes for both markets together. Rather, you optimize routes for each market, independently (and ideally even before launching, especially if you want to test out multiple prospective launch locations). 

Fortunately, we’ve built Nextmv with testing in mind. (We care about testing a lot, actually.) So, we’ve made it easy to do things like test and manage multiple market locations in Nextmv.

Testing new market vehicle routing operations for a ghost kitchen

Testing in Nextmv Cloud can save you time and help you make better decisions not just before launching in a new market, but also when adding (or removing) vehicles from your fleet, or setting up a new depot location, for example. This blog post focuses on the question of how to test and manage routes for multiple markets using the example of a ghost kitchen operator.

Ghost kitchens are essentially delivery-only restaurants. They’re a physical space to create food that can be ordered, delivered, and enjoyed off the premises at a home or at the office.  Because the kitchen is essentially a depot and vehicles start and end from the same location this is a distribution problem. For this example, we’re going to create routes in Princeton, NJ where our ghost kitchen business currently operates and in Philadelphia where the business is launching a second location soon.

Let’s get started with some sample data! (And if you’d like to follow along and try it yourself, run it in your free Nextmv Cloud account. All it takes is a copy-paste of the files below.)

Ghost kitchen vehicle routing in the Princeton, NJ market

In Princeton, the operator has a fleet of 5 vehicles and each vehicle can carry up to 4 orders at a time (so capacity is set to 4). During a typical hour, the business receives 20 order requests.

Here is the sample input file for the Princeton ghost kitchen:

  "defaults": {
    "vehicles": {
      "start": { "lon": -74.659296, "lat": 40.349274 },
      "end": { "lon": -74.659296, "lat": 40.349274 },
      "shift_start": "2022-03-30T09:00:00-05:00",
      "speed": 10,
      "capacity": 4
    "stops": { "quantity": -1, "unassigned_penalty": 2000 }
  "vehicles": [
    { "id": "vehicle-1" },
    { "id": "vehicle-2" },
    { "id": "vehicle-3" },
    { "id": "vehicle-4" },
    { "id": "vehicle-5" }
  "stops": [
    { "id": "location-1", "position": { "lon": -74.65212, "lat": 40.34921 } },
    { "id": "location-2", "position": { "lon": -74.645424, "lat": 40.357723 } },
    { "id": "location-3", "position": { "lon": -74.66337, "lat": 40.360058 } },
    { "id": "location-4", "position": { "lon": -74.66859, "lat": 40.347534 } },
    { "id": "location-5", "position": { "lon": -74.66565, "lat": 40.340885 } },
    { "id": "location-6", "position": { "lon": -74.64397, "lat": 40.351948 } },
    { "id": "location-7", "position": { "lon": -74.672455, "lat": 40.359142 } },
    { "id": "location-8", "position": { "lon": -74.64326, "lat": 40.364777 } },
    { "id": "location-9", "position": { "lon": -74.667915, "lat": 40.349358 } },
    { "id": "location-10", "position": { "lon": -74.67122, "lat": 40.357338 } },
    { "id": "location-11", "position": { "lon": -74.672455, "lat": 40.359142 } },
    { "id": "location-12", "position": { "lon": -74.66396, "lat": 40.350163 } },
    { "id": "location-13", "position": { "lon": -74.6621, "lat": 40.35075 } },
    { "id": "location-14", "position": { "lon": -74.6475, "lat": 40.356453 } },
    { "id": "location-15", "position": { "lon": -74.65316, "lat": 40.351654 } },
    { "id": "location-16", "position": { "lon": -74.66931, "lat": 40.357834 } },
    { "id": "location-17", "position": { "lon": -74.65713, "lat": 40.350388 } },
    { "id": "location-18", "position": { "lon": -74.660614, "lat": 40.345367 } },
    { "id": "location-19", "position": { "lon": -74.6579, "lat": 40.35302 } },
    { "id": "location-20", "position": { "lon": -74.6778, "lat": 40.327255 } }

Running the input file for 3 seconds in Nextmv Cloud console, we get routes for 5 vehicles to deliver 20 orders. We see that all orders are assigned and distributed evenly across the vehicles (each vehicle has 4 stops assigned to it).

Ghost kitchen vehicle routing in the Philadelphia, PA market

Now let’s look at what this same demand might look like in Philadelphia, PA, the location we’re interested in expanding into. Unlike Princeton, the fleet in Philadelphia will consist of scooters, whose maximum capacity is only 2 orders. As a good first approximation, we will assume that everything else in this Philadelphia market is the same with 20 orders with 5 vehicles. 

For the second location, we don’t yet have orders so we will need to select 20 random locations from the neighborhoods we are planning to operate in. We can then use that to create a second input file with 20 locations and 5 vehicles (remembering that the vehicles in our Philadelphia fleet are scooters that have a capacity of 2). 

Here is the sample input file for the Philadelphia ghost kitchen:

  "defaults": {
    "vehicles": {
      "start": { "lon": -75.14366, "lat": 39.960448 },
      "end": { "lon": -75.14366, "lat": 39.960448 },
      "shift_start": "2022-04-20T09:00:00-05:00",
      "speed": 10,
      "capacity": 2
    "stops": { "quantity": -1, "unassigned_penalty": 2000 }
  "vehicles": [
    { "id": "vehicle-1" },
    { "id": "vehicle-2" },
    { "id": "vehicle-3" },
    { "id": "vehicle-4" },
    { "id": "vehicle-5" }
  "stops": [
    { "id": "location-1", "position": { "lon": -75.13703, "lat": 39.960285 } },
    { "id": "location-2", "position": { "lon": -75.12933, "lat": 39.969673 } },
    { "id": "location-3", "position": { "lon": -75.14721, "lat": 39.971104 } },
    { "id": "location-4", "position": { "lon": -75.1536, "lat": 39.958527 } },
    { "id": "location-5", "position": { "lon": -75.15005, "lat": 39.95223 } },
    { "id": "location-6", "position": { "lon": -75.15506, "lat": 39.97227 } },
    { "id": "location-7", "position": { "lon": -75.128456, "lat": 39.976475 } },
    { "id": "location-8", "position": { "lon": -75.15312, "lat": 39.960674 } },
    { "id": "location-9", "position": { "lon": -75.15579, "lat": 39.968246 } },
    { "id": "location-10", "position": { "lon": -75.158905, "lat": 39.97001 } },
    { "id": "location-11", "position": { "lon": -75.148254, "lat": 39.961025 } },
    { "id": "location-12", "position": { "lon": -75.14662, "lat": 39.96251 } },
    { "id": "location-13", "position": { "lon": -75.13178, "lat": 39.968018 } },
    { "id": "location-14", "position": { "lon": -75.1378, "lat": 39.96261 } },
    { "id": "location-15", "position": { "lon": -75.154236, "lat": 39.970413 } },
    { "id": "location-16", "position": { "lon": -75.14119, "lat": 39.961906 } },
    { "id": "location-17", "position": { "lon": -75.14365, "lat": 39.95723 } },
    { "id": "location-18", "position": { "lon": -75.14181, "lat": 39.963703 } },
    { "id": "location-19", "position": { "lon": -75.13572, "lat": 39.97016 } },
    { "id": "location-20", "position": { "lon": -75.13429, "lat": 39.97077 } }

Running the sample input file for 3 seconds in Nextmv Cloud console, we get routes for 5 vehicles to deliver our hypothetical 20 orders in Philadelphia. Because our vehicles can now only carry 2 orders, we see that 10 stops are unassigned. This tells us that we’ll need to take fewer orders, recruit a larger fleet, or rethink our decision to use scooters over cars for this new location.

While this example is simple, it helps illustrate how easy it is to model and manage multiple market locations with Nextmv. Simply create a separate JSON input with your unique business constraints for each location and run it in Nextmv Cloud console or API. Doing so before you launch can help you reason about your business needs and make better decisions about aspects of your operations such as fleet size and capacity as we explored in this example.

Represent location-specific properties with vehicle route optimization 

You can add location-specific complexity to your input file as you see fit — from differing the default vehicle and stop values to adding compatibility attributes, route limits, and more

In addition to creating separate input files for each market location, you may also want to create separate run profiles too. Why would you want to do this? An example could be that you only want to use a dispatch and fleet management platform such as Onfleet in some locations. All this requires is that you create a run profile with an Onfleet integration to use with those locations and not the other. Or, if some locations require drivers to cross bodies of water or go around mountains, the Streets or HERE measure integrations may be preferable over the default Haversine measure for calculating distances and durations in those locations. Again, you can create a run profile with Streets or HERE measure integration to use with those locations and not others.

Try testing route optimization scenarios in different markets

See the value of the Nextmv Cloud for testing out and managing multiple market locations. All you need to do is: 

  1. Create a free Nextmv Cloud account (or log into your existing account)
  2. Click “Premium Trial” in the top navigation
  3. Start experimenting with Premium features and 50,000 free decisions

Have questions? We love to chat about all things optimization. Get in touch with our team!

Video by:
No items found.