# Measure routing performance and delivery cost

Compare the same routes, travel modes, datasets and device. Report the dataset release, browser, device, network and whether the visual map is included. A cached route benchmark cannot describe first-use performance.

## Three useful measurements

1. **Cold:** start a fresh browser profile or explicitly clear the SDK's persistent tiles, then initialize and run a route. Include engine startup, graph transfer and calculation.
2. **Warm:** repeat the same request in the same client, then vary nearby endpoints. Report median and p95 over a disclosed number of requests. Nearby requests may still need additional tiles.
3. **Reload/offline:** recreate the client with persistent graph data retained. Separately test airplane mode after the application and all required assets are available offline. OPFS support and eviction vary by browser.

```js
const timings = [];
for (let i = 0; i < 30; i++) {
  const start = performance.now();
  const result = JSON.parse(await client.call('route', JSON.stringify(request)));
  if (!result.trip) throw new Error(result.error || 'Route failed');
  timings.push(performance.now() - start);
}
timings.sort((a, b) => a - b);
console.table({ medianMs: (timings[14] + timings[15]) / 2, p95Ms: timings[28] });
console.log(await client.metrics());
```

Keep cold timing separate from this warm loop. `client.metrics()` includes engine diagnostics and `persistent_tiles` hit/miss/write/error counters. Counter shapes are diagnostic, not a stable billing API. Check the network panel for map requests too; map movement, fonts and sprites are separate from route calculation.

Browser Resource Timing can help with transfer observations, but cross-origin timing visibility requires server headers and cached entries may report zero. Content-Length measures the advertised response size, not bytes received during an interrupted transfer. Customer usage monitoring uses delayed edge logs, which is live for hosted delivery, rather than SDK route counts.

## Estimate a delivery budget

Use decimal GB: **1 GB = 1,000,000,000 bytes**. Add map and graph downloads, updates and re-downloads after eviction. Local calculations on retained data add no route API requests; switching regions may add transfers.

Example, not a pricing quote: 1,000 installations each downloading 20 MB once use about 20 GB. Five fully repeated downloads use about 100 GB. Ten thousand local route calculations can add zero graph transfer if their required data is already retained. This assumes the stated coverage and cache behavior; measure your application rather than multiplying route count by a fixed byte estimate.

An included-GB plan should be evaluated against monthly transferred bytes and the time saved operating tile builds, updates and delivery. Published launch prices are €0/10 GB, €9/50 GB and €29/200 GB per month, before tax. There are no automatic overages; preview access currently has no usage charges or enforced GB limits. Paid activation is pending. See [pricing and cache policy](pricing.md) for update cadence and sourced API comparisons. Optional server routing will have separate pricing if launched.

## Compare fairly with a hosted API

Record server request latency and price for an equivalent action alongside cold and warm local measurements. Include the API's map and route allowances, the SDK's initial download, client battery/memory impact, update cadence and engineering time. First-use or long-distance workloads may favor server routing. Repeated local exploration is where download reuse can pay off.
