---
title: "How each metric is calculated"
description: "The definition behind every number IoTFlows shows and what each one leaves out. Uptime is availability, running time over running plus stopped, and is the number the interface has labeled OEE. Unknown time and None-severity breaks sit outside both uptime and downtime. The parts gauge measures output against the ideal cycle time, FPY compares a step's count to the step before it, and every window is calculated whole rather than averaged per shift. There is no combined OEE figure and no quality factor."
category: "Reference"
source_url: "https://www.iotflows.com/docs/monitoring/metrics-reference/"
---
# How each metric is calculated

The definition behind every number on every screen, and what each one leaves out.

Every metric comes from two streams: the running and stopped states a sensor reports, and the detection events that count parts. This page defines each number once, and every other page links here.

**The number the interface labels OEE is availability, not OEE.** IoTFlows is renaming that label to Uptime, and this page uses Uptime throughout.

## Uptime
*Uptime* is availability: the share of the window a machine spent running.

```
uptime = running time ÷ (running time + stopped time)
```

The sensor decides running and stopped, the same state that colors the shift status bar. For example, a machine that ran 6 h 30 min of a 9 h shift and was stopped 2 h 30 min reads 72% uptime. Time the sensor did not report is left out of both terms, see [Unknown time](#unknown).

The same percentage carries two labels: **Uptime** on a machine card and machine page, **Utilization** on the Assets KPI row and the Advanced Report. The **Uptime** KPI tile on the Assets page is different: that one is total running hours, as `71:15h`. See [Read the fleet KPIs](/docs/monitoring/assets-overview/#kpis).

Diagram: A diagram in three columns under the heading Textbook OEE: Availability times Performance times Quality. Under Availability, a box reads Uptime, running divided by running plus stopped, with the input labeled: running and stopped states from the sensor. Under Performance, a box reads Parts gauge, parts made divided by parts possible at the ideal cycle time, with the input labeled: detection events, and the ideal cycle time in the Parts List. Under Quality, a dashed box reads Not measured, no good-versus-scrap factor. A note across the bottom reads: nothing multiplies these together. There is no combined OEE figure; read each number on its own.

*The two factors IoTFlows computes, uptime and the parts gauge, against the three of textbook OEE. Quality is not measured and nothing multiplies them together.*

**There is no combined OEE figure and no quality factor in the product.** IoTFlows shows availability as uptime and performance as the parts gauge, separately, and has no good-versus-scrap term. Comparing an IoTFlows uptime of 85% to an OEE of 60% from another system is comparing one factor to a product of three.

## Downtime
*Downtime* is the time the sensor reported the machine stopped. Every minute is running or stopped unless the sensor was silent.

Downtime is the same total with or without a reason on it. A *classified* stop carries a downtime category, an *unclassified* stop does not, and both count in full. Classification changes what the [Downtimes report](/docs/monitoring/downtimes/) can say about the time, not how much there is, see [Classify a downtime event](/docs/monitoring/classify-downtime/).

A stop's red or orange on the status bar is a duration threshold and has no effect on the number, see [Set status colors and downtime thresholds](/docs/monitoring/status-colors/).

## Unknown time
*Unknown time* is any interval where the sensor was powered off or had lost its connection. It is absence of data, not a machine state, and it counts toward **neither** uptime nor downtime.

For example, a SenseAi unplugged over a weekend produces 48 unknown hours, not 48 hours of downtime. On the shift status bar the stretch is gray, and the card keeps the last state the cloud recorded, so an offline machine can still read stopped. Gray on the bar is what separates a dead link from a stopped machine, see [Troubleshoot a device that is offline](/docs/hardware/troubleshoot-offline-device/).

On the Advanced Report, turn on **Exclude Unknown** when you want to be certain the report's **Total Utilization** follows this definition, see [Choose what the number includes](/docs/monitoring/advanced-report/#switches).

## The None severity
*None* is a downtime severity for categories whose stops are nobody's loss. Its purpose is legally required breaks: a mandated one-hour lunch is a stop on the sensor, but it should not count against the plant.

A None-severity stop is downtime by default. With **Exclude None** on, it leaves both uptime and downtime, the same way unknown time does. For example, a department that takes the mandated hour reads 82% uptime with the switch off and 93% with it on, because the hour leaves the denominator too. Which categories carry None is set in [Set severity](/docs/monitoring/downtime-categories/#severity).

Diagram: A horizontal bar representing one shift from 8am to 5pm, divided into segments. Most of the bar is running. A short classified stop labeled Tool change sits around 9:30, a short unclassified stop around 10:30, a one-hour break labeled Lunch, severity None, from 12 to 1, and a stretch labeled Sensor offline, Unknown, from about 2:20 to 3. A key beneath assigns each kind of segment to a bucket: running counts as uptime; a classified stop and an unclassified stop both count as downtime; the None break counts as downtime, or as neither with Exclude None on; sensor offline counts as neither. A note reads: uptime percentage is running divided by running plus stopped. Minutes in neither bucket are why the percentages do not add up to the length of the shift.

*How a shift's clock divides: uptime, classified downtime, unclassified downtime, a None break and unknown time. This is the figure behind most questions of the form why does this not add up.*

### What is excluded from uptime and downtime
| Excluded | When | Toggle | Why |
|---|---|---|---|
| Unknown time | Always | **Exclude Unknown** on the Advanced Report makes it explicit | The sensor reported nothing, so there is no state to count |
| Stops with severity None | Only when the toggle is on | **Exclude None** on the Advanced Report | A mandated break is a stop no one is accountable for |

Leave Unknown and None in when you are asking where the shift went, because a number without them no longer adds up to the shift. Exclude them when you are comparing machines or holding someone to a number.

## Performance
*Performance* is the parts gauge: actual output against what the machine could have produced at its ideal cycle time in the same running time.

```
performance = parts made ÷ (running time ÷ ideal cycle time)
```

The *ideal cycle time* is entered per operation in the Parts List, see [Set cycle times and filters](/docs/production/cycle-times-and-filters/). The gauge is green when the percentage meets the machine's goal and red when it does not, see [Set uptime goals](/docs/monitoring/oee-goals/).

Watch uptime to find machines that are stopped, and the parts gauge to find machines that are running slowly. A machine can sit at 95% uptime and still miss its goal, because uptime does not know how fast the machine was going. For example, a press running all shift at 40 strokes a minute against an ideal of 60 shows a green uptime ring and a red parts gauge.

You do not need the parts gauge to tell whether a machine is stopped. It earns its place once an operation with an ideal cycle time is assigned to the machine.

## FPY
*FPY*, first pass yield, compares a step's good count with the count of the step before it in a cascading group.

```
fpy = this step's good count ÷ previous step's good count, capped at 100%
```

Where a step produced less than the step before it, the difference is the loss from the first step through to this one. For example, if OP10 made 1,200 parts and OP20 made 1,080, OP20 reads 90% FPY and a loss of 120. It is a multi-operation measure, which is why it appears only on cascading group cards, see [Group machines into cascades](/docs/monitoring/asset-groups/). It reads green from 95% and amber from 80%.

A group can instead measure each step against its own cycle-time baseline, with no reference step. The group page says when to use which.

## Cycle time
Three cycle-time figures appear in the product, from three places.

| Figure | Comes from | Appears as |
|---|---|---|
| *Actual cycle time* | Detection events: running time between counted parts | **Cycle time** on cards and machine pages, and its inverse **Production rate** |
| *Ideal cycle time* | Entered per operation in the Parts List | The basis of the parts gauge and the hourly goal |
| Target | The machine's goal, see [Set uptime goals](/docs/monitoring/oee-goals/) | The color threshold on the cycle-time figure |

A red cycle time means the machine is producing more slowly than its goal allows, not that it is stopped. For example, a machining center with a 90 s ideal cycle that is turning parts every 2 min reads a red **Cycle time** and a green **Uptime**, and both are correct.

## Production metrics
*Hourly production* is parts counted per clock hour, drawn as bars on the machine card against a per-hour goal derived from the ideal cycle time and the machine's goal, see [Set cycle times and filters](/docs/production/cycle-times-and-filters/).

*Machines producing* on the Assets page KPI row counts machines whose sensor reports running at this moment, out of the filtered fleet. It is the one KPI on the row with no window.

Any selected window, including one spanning several shifts, is calculated **across the whole window**, not as an average of per-shift figures. For example, a machine at 90% on a long day shift and 50% on a short night shift reads 80% for the two together, because the day shift contributed more minutes.

Which minutes fall in the window is itself a question for a shift that crosses midnight. On a report, such a shift is divided at midnight and its later hours are counted on the next day, unless **Shift islands** is on. The live views never divide it. So the same night shift has two defensible denominators, see [Where the overnight hours land](/docs/admin/shifts-and-timezone/#overnight-hours).

## Where each metric appears
| Metric | What it measures | Basis | Excludes | Appears on |
|---|---|---|---|---|
| Uptime (%) | Availability, running ÷ (running + stopped) | Sensor states | Unknown always, None with the toggle | Cards and machine pages as **Uptime**; Assets KPI row and Advanced Report as **Utilization** |
| Uptime (hours) | Total running time | Sensor states | Unknown | Assets KPI row, Advanced Report **Uptime Hours** |
| Downtime | Total stopped time | Sensor states | Unknown, None with the toggle | Assets KPI row, cards, Downtimes report, Advanced Report |
| Unknown | Time with no sensor data | Gaps in the stream | Neither uptime nor downtime | Advanced Report **Unknown Hours**, gray on status bars |
| Performance | Output against the ideal cycle time | Detection events, Parts List | Machines with no operation | Parts gauge on cards and Shift Production |
| FPY | This step's count against the previous step's | Good counts in a cascade | Groups in cycle-time baseline mode | Cascading group cards |
| Actual cycle time | Running time per counted part | Detection events | Stopped time | Cards and machine pages |
| Hourly production | Parts per clock hour against the ideal | Detection events, Parts List | Nothing | Cards, Shift Production |
| Machines producing | Machines running right now | Live sensor state | Nothing, no window | Assets KPI row |

## See also
- [Troubleshoot wrong utilization or OEE](/docs/monitoring/troubleshoot-monitoring/)
- [Build a utilization report](/docs/monitoring/advanced-report/)
- [Set cycle times and filters](/docs/production/cycle-times-and-filters/)
- [Group machines into cascades](/docs/monitoring/asset-groups/)
- [Set uptime goals](/docs/monitoring/oee-goals/)
