Two-leg trip time calculator
Drive 180 km at 90 km/h, then 30 km at 30 km/h, and the trip takes 3 hours with a combined average of 70 km/h, not the 60 you get by averaging the speeds. Enter each leg's distance and speed. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Distance 1
- 180
- Speed 1
- 90
- Distance 2
- 30
- Speed 2
- 30
- Time 1 hours
- 2
- Time 1 minutes
- 120
- Time 1 formatted
- 2h
- Time 2 hours
- 1
A two-leg trip time calculator answers the everyday planning question that a single average-speed box cannot: how long does the whole drive take when the first stretch and the second stretch run at different speeds, and what combined average speed does that imply for the journey as a whole. Enter the distance and speed of each sequential route leg in matching units—kilometres with kilometres per hour, or miles with miles per hour—and the tool divides each distance by its own speed, adds the two driving times, and reports total driving time plus the true combined average speed. Combined average speed is total distance over total time, not the arithmetic mean of the two speeds. Zero or negative speed or distance is rejected because a motionless or backwards leg cannot produce a finite travel time. The arithmetic is pure and deterministic: no maps vendor, no live traffic, no wall-clock dates.
Why two sequential legs need their own times
When a journey has two sequential stretches that do not share a speed—a motorway run followed by a congested urban last mile, a rural climb then a descent, a legal highway limit then a school-zone crawl—the honest duration is the sum of two independent times, not one blended distance divided by a guessed blend of the two speeds. Total driving time is those two quotients added together.
Drivers who average ninety and thirty by adding the speeds and dividing by two get sixty, but if the slow stretch is short the true combined average sits closer to ninety, and if the slow stretch is long it sits closer to thirty. This calculator exists so planners, teachers, and dispatch scripts stop making that blend-speed mistake on two-part journeys. The model is unit-agnostic: keep kilometres with kilometres per hour or miles with miles per hour, and the hours come out correctly.
It does not query live traffic, weather, elevation, or a maps vendor, and it does not add rest stops, fuel fills, or hotel nights. Those belong to other tools. Here the question is strictly two sequential legs, two speeds, one total driving time, and one combined average speed you can defend by hand.
Practical tips, limits, and related searches
Use this landing when the search is a two-leg trip time calculator, a two-part journey with different speeds, or combined average speed from two sequential driving legs. It is not a single-speed road-trip duration tool, not a compare-two-alternative-routes calculator, not a multi-stop distance summer, and not a live traffic ETA. Prefer a single-speed driving-time tool if both stretches truly share one rate.
Prefer a route-comparison tool if the two numbers are rival paths rather than sequential parts of one itinerary. Keep each pair of distance and speed in the same unit family, and prefer realistic moving averages rather than posted maximums if you want conservative hours for family trips or heavy vehicles. When scripting fleets, recompute after each pair of legs with updated remaining distances so cumulative error does not grow.
Absolute limits reject absurd inputs that would overflow intermediate results.
What you can do with it
Highway then city last mile
Drivers add a fast motorway leg to a slow urban approach and get total driving time plus a combined average that is not the naive mean of the two speeds.
Classroom two-part journey problems
Teachers generate deterministic answers for two-leg motion homework and show why (v1 + v2) / 2 is the wrong combined average.
Two-leg courier dispatch
Dispatch scripts estimate rural pickup plus urban delivery as sequential legs without calling a maps vendor, then hand total hours to scheduling tools.
FAQ
How is two-leg trip time calculated?
Each leg time is its distance divided by its speed. Combined average speed is total distance divided by that total time.
What happens if a speed is zero?
Zero or negative speed or distance cannot produce a finite two-leg driving time.
Do I need to specify kilometres or miles?
Use any consistent pair (km with km/h, or miles with mph). The formula is unit-agnostic; mixed units are not converted automatically.
Why is the average speed not simply the mean of the two speeds?
Because it is total distance divided by total time. Averaging 90 and 30 gives 60, but 180 km at 90 plus 30 km at 30 averages 70, since most of the distance is driven fast.
Does it include rest stops or traffic?
No. It adds only the two driving times. Live traffic, weather, elevation, rest stops and fuel fills are not part of the calculation, so add them yourself if your plan needs them.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/travel/trip-time-two-legs \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"distance_1":180,"speed_1":90,"distance_2":30,"speed_2":30}'const res = await fetch("https://api.kit.forhosting.com/travel/trip-time-two-legs", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"distance_1": 180,
"speed_1": 90,
"distance_2": 30,
"speed_2": 30
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/travel/trip-time-two-legs",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"distance_1": 180,
"speed_1": 90,
"distance_2": 30,
"speed_2": 30
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/travel/trip-time-two-legs", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"distance_1":180,"speed_1":90,"distance_2":30,"speed_2":30}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"distance_1":180,"speed_1":90,"distance_2":30,"speed_2":30}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/travel/trip-time-two-legs", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"distance_1": 180,
"speed_1": 90,
"distance_2": 30,
"speed_2": 30
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "travel.trip_time_two_legs",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_distance | 1000000 |
max_speed | 10000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Why two sequential legs need their own times
The first-leg time is distance_1 divided by speed_1. The second-leg time is distance_2 divided by speed_2. Combined average speed is then total distance divided by that total time: (distance_1 plus distance_2) divided by (time_1 plus time_2). That combined figure is a distance-weighted harmonic mean of the two speeds, not their arithmetic average.
How to call the API and what comes back
Distances and speeds must be strictly positive and within the published maxima: one million distance units per leg and ten thousand speed units per hour. Mixing unit families silently warps the hours, because the formula never converts kilometres into miles. Send a JSON body with four required finite numbers: distance_1 and speed_1 for the first sequential leg, and distance_2 and speed_2 for the second. Each field accepts a JSON number or a numeric string, and each has short aliases (d1, first_distance, v1, first_speed, and the matching second-leg names) so scripts written around different naming habits still resolve. On success the response echoes the rounded inputs, each leg time in hours and minutes plus a compact formatted string such as two hours or forty-five minutes, total_distance, total_time_hours, total_time_minutes, total_time_formatted, the combined average_speed, the formula string, a short English message, and ordered substitution steps you can show next to the answer. Failed validation—missing fields, non-finite values, out-of-range magnitudes, or zero or negative distance or speed—returns invalid_input naming the field and is never charged. Pricing is a flat $0.002 per successful request with unit item. Pair the hours with your own calendar if you need a wall-clock arrival; this endpoint does not read the system clock.
Practical tips, limits, and related searches
Failed tasks that return invalid_input do not consume prepaid balance, which keeps exploratory scripts cheap when you deliberately send speed_1 equal to zero to verify error handling.
Technical questions
Is combined average speed the mean of the two speeds?
No. Combined average speed is (distance_1 + distance_2) / (time_1 + time_2), a distance-weighted harmonic mean, not (speed_1 + speed_2) / 2.
What does the two-leg trip time calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.