**European Economic Area (EEA) developers**

> [!NOTE]
> If your billing address is in the European Economic Area, effective on 8 July 2025, the [Google Maps Platform EEA Terms of Service](https://cloud.google.com/terms/maps-platform/eea) will apply to your use of the Services. Functionality varies by region. [Learn more](https://developers.google.com/maps/comms/eea/faq.md.txt).

A route matrix is a two-dimensional array of route information, where the rows correspond to
the origins and the columns correspond to the destinations. Given a list of origins and
destinations, the Route Matrix class calculates the distance and duration of a route starting
at each origin and ending at each destination. Use the Route Matrix class to calculate the
distance and duration of a route for multiple origins and destinations.
<iframe src="https://maps-docs-team.web.app/samples/routes-route-matrix/dist/" allow="fullscreen; fullscreen"></iframe>

#### See the complete example source code

This example shows how to use the Route Matrix class to calculate the distances and durations
for travel between multiple origins and destinations.

### TypeScript

```typescript
// Initialize and add the map.
let map: google.maps.Map;
const markers: google.maps.marker.AdvancedMarkerElement[] = [];
const center = { lat: 51.55, lng: -1.8 };

async function init(): Promise<void> {
    //  Request the needed libraries.
    const [
        { Map },
        { Place },
        { AdvancedMarkerElement, PinElement },
        { RouteMatrix },
        { LatLngBounds, UnitSystem },
    ] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('routes'),
        google.maps.importLibrary('core'),
    ]);

    const bounds = new LatLngBounds();

    map = new Map(document.getElementById('map')!, {
        zoom: 8,
        center,
        mapId: 'DEMO_MAP_ID',
    });

    // Build the request using Place instances.
    const origin1 = new Place({
        id: 'ChIJ83WZp86p2EcRbMrkYqGncBQ', // Greenwich, London, UK
    });
    const origin2 = new Place({
        id: 'ChIJCSkVvleJc0gR8HHaTGpajKc', // Southampton, UK
    });
    const destinationA = new Place({
        id: 'ChIJYdizgWaDcUgRH9eaSy6y5I4', // Bristol, UK
    });
    const destinationB = new Place({
        id: 'ChIJ9VPsNNQCbkgRDmeGZdsGNBQ', // Cardiff, UK
    });

    await Promise.all([
        origin1.fetchFields({ fields: ['location', 'displayName'] }),
        origin2.fetchFields({ fields: ['location', 'displayName'] }),
        destinationA.fetchFields({ fields: ['location', 'displayName'] }),
        destinationB.fetchFields({ fields: ['location', 'displayName'] }),
    ]);

    const destinations = [destinationA, destinationB];
    const origins = [origin1, origin2];
    const request: google.maps.routes.ComputeRouteMatrixRequest = {
        origins,
        destinations,
        travelMode: 'DRIVING',
        units: UnitSystem.METRIC,
        fields: ['distanceMeters', 'durationMillis', 'condition'],
    };

    // Show the request.
    document.getElementById('request')!.innerText = JSON.stringify(
        request,
        null,
        2
    );

    // Get the RouteMatrix response.
    const response = await RouteMatrix.computeRouteMatrix(request);

    // Show the response.
    document.getElementById('response')!.innerText = JSON.stringify(
        response,
        null,
        2
    );

    // Add markers for the origins.
    for (const origin of origins) {
        if (origin.location) {
            const pin = new PinElement({
                glyphText: 'O',
                glyphColor: 'white',
                background: '#137333',
                borderColor: 'white',
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: origin.location,
                title: `Origin: ${origin.displayName}`,
            });
            marker.append(pin);
            markers.push(marker);
            bounds.extend(origin.location);
        }
    }

    // Add markers for the destinations.
    for (const destination of destinations) {
        if (destination.location) {
            const pin = new PinElement({
                glyphText: 'D',
                glyphColor: 'white',
                background: '#C5221F',
                borderColor: 'white',
            });

            const marker = new AdvancedMarkerElement({
                map,
                position: destination.location,
                content: pin,
                title: `Destination: ${destination.displayName ?? 'Unknown'}`,
            });

            markers.push(marker);
            bounds.extend(destination.location);
        }
    }

    // Fit the map to the bounds of all markers.
    map.fitBounds(bounds);
}

void init();
```

### JavaScript

```javascript
// Initialize and add the map.
let map;
const markers = [];
const center = { lat: 51.55, lng: -1.8 };

async function init() {
    //  Request the needed libraries.
    const [
        { Map },
        { Place },
        { AdvancedMarkerElement, PinElement },
        { RouteMatrix },
        { LatLngBounds, UnitSystem },
    ] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('routes'),
        google.maps.importLibrary('core'),
    ]);

    const bounds = new LatLngBounds();

    map = new Map(document.getElementById('map'), {
        zoom: 8,
        center,
        mapId: 'DEMO_MAP_ID',
    });

    // Build the request using Place instances.
    const origin1 = new Place({
        id: 'ChIJ83WZp86p2EcRbMrkYqGncBQ', // Greenwich, London, UK
    });
    const origin2 = new Place({
        id: 'ChIJCSkVvleJc0gR8HHaTGpajKc', // Southampton, UK
    });
    const destinationA = new Place({
        id: 'ChIJYdizgWaDcUgRH9eaSy6y5I4', // Bristol, UK
    });
    const destinationB = new Place({
        id: 'ChIJ9VPsNNQCbkgRDmeGZdsGNBQ', // Cardiff, UK
    });

    await Promise.all([
        origin1.fetchFields({ fields: ['location', 'displayName'] }),
        origin2.fetchFields({ fields: ['location', 'displayName'] }),
        destinationA.fetchFields({ fields: ['location', 'displayName'] }),
        destinationB.fetchFields({ fields: ['location', 'displayName'] }),
    ]);

    const destinations = [destinationA, destinationB];
    const origins = [origin1, origin2];
    const request = {
        origins,
        destinations,
        travelMode: 'DRIVING',
        units: UnitSystem.METRIC,
        fields: ['distanceMeters', 'durationMillis', 'condition'],
    };

    // Show the request.
    document.getElementById('request').innerText = JSON.stringify(
        request,
        null,
        2
    );

    // Get the RouteMatrix response.
    const response = await RouteMatrix.computeRouteMatrix(request);

    // Show the response.
    document.getElementById('response').innerText = JSON.stringify(
        response,
        null,
        2
    );

    // Add markers for the origins.
    for (const origin of origins) {
        if (origin.location) {
            const pin = new PinElement({
                glyphText: 'O',
                glyphColor: 'white',
                background: '#137333',
                borderColor: 'white',
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: origin.location,
                title: `Origin: ${origin.displayName}`,
            });
            marker.append(pin);
            markers.push(marker);
            bounds.extend(origin.location);
        }
    }

    // Add markers for the destinations.
    for (const destination of destinations) {
        if (destination.location) {
            const pin = new PinElement({
                glyphText: 'D',
                glyphColor: 'white',
                background: '#C5221F',
                borderColor: 'white',
            });

            const marker = new AdvancedMarkerElement({
                map,
                position: destination.location,
                content: pin,
                title: `Destination: ${destination.displayName ?? 'Unknown'}`,
            });

            markers.push(marker);
            bounds.extend(destination.location);
        }
    }

    // Fit the map to the bounds of all markers.
    map.fitBounds(bounds);
}

void init();
```

### CSS

```css
/*
 * Always set the map height explicitly to define the size of the div element
 * that contains the map.
 */
/* Optional: Makes the sample page fill the window. */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#container {
    height: 100%;
    display: flex;
}

#sidebar {
    flex-basis: 15rem;
    flex-grow: 1;
    padding: 1rem;
    max-width: 30rem;
    height: 100%;
    box-sizing: border-box;
    overflow: auto;
}

#map {
    flex-basis: 0;
    flex-grow: 4;
    height: 100%;
}

#sidebar {
    flex-direction: column;
}
```

### HTML

```html
<html>
    <head>
        <title>Route matrix</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <div id="container">
            <div id="map"></div>
            <div id="sidebar">
                <h3 style="flex-grow: 0">Request</h3>
                <pre style="flex-grow: 1" id="request"></pre>
                <h3 style="flex-grow: 0">Response</h3>
                <pre style="flex-grow: 1" id="response"></pre>
            </div>
        </div>
    </body>
</html>
```

### Try Sample

[JSFiddle.net](https://jsfiddle.net/gh/get/library/pure/googlemaps-samples/js-api-samples/tree/main/dist/samples/routes-route-matrix/jsfiddle)

## Request limits

The `computeRouteMatrix` method enforces the following request
limits for waypoints using address or Place instances, and for items. Items are the routes
between each origin and destination in a route matrix, so the number of items is the number of
origins times the number of destinations. For example, if you have 10 origins and 10
destinations, you have 100 items:

- **The number of items** cannot exceed 625 for routes that are not `TRANSIT` routes.
- **If you specify a `TRANSIT` route**, the number of items cannot exceed 100.
- **If you specify `TRAFFIC_AWARE_OPTIMAL`**, the number of items cannot exceed 100.
- **If you specify origins or destinations using addresses or Place instances**, you specify up to 50 total this way.

For additional details, see [Get a transit route](https://developers.google.com/maps/documentation/javascript/routes/route-transit.md.txt).

## Example route matrix request

The following example shows a `ComputeRouteMatrixRequest`. This example
does the following:

- Shows specifying an array of two origin and two destination waypoints. The method calculates a route from each origin to each destination so the response contains four routes.  
  In the array, the first element is at an index of 0, the second is index 1, and so forth.
- Specifies the fields to return. In this example, the request is configured to return `durationMillis`, `distanceMeters`, and `condition` for each route.

### TypeScript

```typescript
const destinations = [destinationA, destinationB];
const origins = [origin1, origin2];
const request: google.maps.routes.ComputeRouteMatrixRequest = {
    origins,
    destinations,
    travelMode: 'DRIVING',
    units: UnitSystem.METRIC,
    fields: ['distanceMeters', 'durationMillis', 'condition'],
};
```

### JavaScript

```javascript
const destinations = [destinationA, destinationB];
const origins = [origin1, origin2];
const request = {
    origins,
    destinations,
    travelMode: 'DRIVING',
    units: UnitSystem.METRIC,
    fields: ['distanceMeters', 'durationMillis', 'condition'],
};
```

The response contains the four possible routes for the combination of all origin and
destination waypoints, as shown in the following example:

```json
"matrix": {
  "rows": [
    {
      "items": [
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 202587,
          "durationMillis": 10040000
        },
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 252734,
          "durationMillis": 12240000
        }
      ]
    },
    {
      "items": [
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 166135,
          "durationMillis": 6596000
        },
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 216282,
          "durationMillis": 8797000
        }
      ]
    }
  ]
}
    
```

Identify each route in the result by using the origin and destination index to find the
corresponding `RouteMatrixItem` in the 2D array. For example, the
`RouteMatrixItem` describing the route calculated from the origin at index 1 and
destination 0 in the request would be in the 2nd element of the `RouteMatrix.rows`
array and the 1st element of the `RouteMatrixRow.items` array.

The following code snippet shows how to identify the `RouteMatrixItem` to find
the route for a specific origin and destination:

```javascript
// Find the route for origin 'x' and destination 'y'.
const {matrix} = await RouteMatrix.computeRouteMatrix(request);
const myRouteMatrixItem = matrix.rows[x].items[y];
    
```

## Choose fields to return

When you request a route matrix, you must use a field mask to specify what information the
response should return.

Using a field mask also ensures that you don't request unnecessary data, which in turn helps
with response latency and avoids returning information your system doesn't need.

Specify the list of fields you need by setting the
[`ComputeRoutesMatrixRequest.fields`](https://developers.google.com/maps/documentation/javascript/reference/route-matrix.md.txt#ComputeRouteMatrixRequest.fields) property, as shown in the following snippet:

```javascript
fields: ['durationMillis', 'distanceMeters', 'condition'],
    
```

### Determine what field masks to use

Here's how you can determine which fields you want to use, and construct the field masks for
them:

1. **Request all fields** using a field mask of `['*']`.

   > [!CAUTION]
   > **Caution:** While you can use this wildcard field mask while in development to determine what fields you need, don't use it in production. Requesting all fields in production results in higher costs and longer response times. Your cost may also increase unexpectedly as more advanced features are added, since this field mask will automatically include them. Instead, request only the fields you need to minimize your costs and request response time.

2. **Look at the hierarchy of the fields** in the `RouteMatrixItem` class for the fields you want.
3. **Construct your field masks** using the hierarchy of the fields shown in
   the previous step, using this format:

   ```
   topLevelField[.secondLevelField][.thirdLevelField][...]
   ```

For example, for this `RouteMatrixItem`:

```json
  "travelAdvisory": {
    "fuelConsumptionMicroliters": 0,
    "tollInfo": {
      "estimatedPrices": [
        {
          "currencyCode": "USD",
          "units": 4,
          "nanos": 400000000
        }
      ]
    }
  },
    
```

If you want to return only the `tollInfo` field for the `RouteMatrixItem`,
your field mask is as follows:

```
fields: ['travelAdvisory.tollInfo']
```

If you instead want to request the estimated fuel consumption, your field mask is as follows:

```
fields: ['travelAdvisory.fuelConsumptionMicroliters']
```

If you want to request both, your field mask is as follows:

```
fields: ['travelAdvisory.fuelConsumptionMicroliters', 'travelAdvisory.tollInfo']
```

And if you want to request the complete set of travel advisories, your field mask is as
follows:

```
fields: ['travelAdvisory']
```

> [!NOTE]
> The property hierarchy is only available for `RouteMatrix.computeRouteMatrix`, and is not supported for `Route.computeRoutes`.

## Request a transit route matrix

Get a transit route matrix that uses the public transportation options available in the
region. Transit options may include buses, subways, and trains, among others. To request a
transit route matrix:

- Set the `travelMode` to `TRANSIT`
- Request the `travelAdvisory` field.

Learn more about [transit routes](https://developers.google.com/maps/documentation/javascript/routes/route-transit.md.txt).