Mean time to repair (MTTR)¶
Once an asset fails, how long until it runs again?
Current value (maintenance case data): 5.3 h - ! Watch. Open the case.
| Field | Value |
|---|---|
| Definition | Mean repair hours (failure to return to service) over corrective work orders. |
| Formula | mean(repair_hours) for wo_type = corrective |
| Unit | hours |
| Granularity | Corrective work order; reported monthly by asset and failure mode. |
| Direction | Lower is better ↓ |
| Target and thresholds | ≤ 4.0 h (amber ≤ 6.0 h) |
| Parameters | – |
| Owner | Maintenance Supervisor |
| Source | Work-order generator (synthetic) |
| Input | table work_orders, columns wo_type, repair_hours |
| Recommended chart | boxplot - Distribution per failure mode shows whether the mean is driven by a tail. |
| Related KPIs | Mean time between failures (MTBF), Availability |
How to read it¶
Kept as a mean so that availability = MTBF / (MTBF + MTTR) holds. Because repair times are right-skewed, always look at the median and the longest repairs: waiting for spare parts usually lives in the tail.
Common misreadings¶
- Mean vs median - a few repairs waiting for parts can double the mean while the typical repair is unchanged.
- Repair time is not response time; mixing "time to arrive" and "time to fix" hides where the delay is.
Worked example (from the test suite)¶
| wo_type | repair_hours |
|---|---|
| corrective | 2.0 |
| corrective | 3.0 |
| corrective | 10.0 |
| preventive | 1.0 |
Expected result: 5.00 h. Corrective only: (2 + 3 + 10) / 3 = 5.0 h. The median would be 3.0 h - one long repair drives the mean.
This example is asserted in tests/test_formulas.py against the Python function and in tests/test_sql.py against the SQL below.
Implementations¶
Python function (the single implementation used by the site):
@kpi("mttr")
def mttr(df: pd.DataFrame) -> float:
repairs = df.loc[df["wo_type"].eq("corrective"), "repair_hours"].dropna()
return float(repairs.mean()) if len(repairs) else float("nan")
Reference SQL (tested on SQLite):
SELECT AVG(repair_hours) FROM work_orders WHERE wo_type = 'corrective'