---
title: "Analyze cost and on-time performance"
description: "Insights, at /production?select=insights, prices scheduled work at two hourly rates you type in: Labor $/hr and Production $/hr, defaulting to $35 and $50. It multiplies each task's labor hours and machine hours by those rates, compares the result with the Budget typed on the task, and reports completion, on-time, cost, profit and margin across a date range that opens on the last 90 days. The rates live in the report and are never saved to your organization. A task with no due date counts as on time, and an Approved task counts as neither Completed nor Active."
category: "Watch production"
source_url: "https://www.iotflows.com/docs/production/production-insights/"
---
# Analyze cost and on-time performance

Put an hourly cost on work the scheduler already recorded, and see what finished late.

Insights prices the schedule. It takes every task in a date range, multiplies the hours logged against it by two hourly rates you type in, and reports what that work cost, what it made against the budget on the task, and how much of it hit its due date.

The page reads the scheduler's records and writes nothing back. Nothing here changes a job, a task, or a session.

**Before you start**

- **The Scheduling Engine module.** Every organization sees the **Insights** tab whether or not it is licensed, so the tab strip is not proof. See [Module entitlement](/docs/production/overview/#entitlement).
- **Web only.** Neither mobile app has an Insights tab.
- **Tasks with hours on them.** Insights counts hours operators and machines actually logged, so a schedule nobody has run against produces an empty report. See [Start, pause, and complete a job](/docs/production/run-a-job/).
- **A Budget on the tasks**, if you want profit rather than cost. See [Job and scheduler fields](/docs/production/job-fields-reference/).

There is no role gate. Anyone who can open Production can open Insights and change the rates.

## Open Insights
Open **Production**, then the **Insights** tab, at `/production?select=insights`.

The report opens on the last 90 days, at a labor rate of $35 an hour and a production rate of $50 an hour. Those are defaults in the page, not settings your organization chose.

![The Insights tab at /production?select=insights, showing the Production tab strip above a filter bar with Machines, Jobs and Operations pills on the left, a search-and-status pill with a 90d date button in the center and an Options button on the right, above the Workorders, Financials and Hours cards](/images/production/prod-insights-01.webp)

*Production Insights. Requires the Scheduling Engine module and is web only.*

### Narrow the window and the work
Seven controls sit in the filter bar, and they split into two kinds.

| Control | Where | What it narrows |
|---|---|---|
| **Date range** | The center pill: `1d`, `7d`, `30d`, `90d`, `1y`, or **Custom** with two date fields and **Apply** | Refetches the report |
| **Labor $/hr**, **Production $/hr** | The **Options** menu | Refetches the report |
| **Machines** | Filter pill, grouped by department | Filters the rows on screen |
| **Jobs**, **Operations** | Filter pills, each with a search box | Filters the rows on screen |
| Search | The magnifier inside the center pill, matching workorder number, title, part, job, operation and machine | Filters the rows on screen |
| **All** / **Done** / **On Hold** | Status buttons in the center pill | Filters the rows on screen |

Only the date range and the two rates go back to the server. Everything else narrows rows the page already holds, so the cards, both charts and the table move the instant you click.

**Machines**, **Jobs** and **Operations** write themselves into the address bar, so a filtered view is a link you can send. **Reset**, in the **Options** menu, clears every filter and returns the window to 90 days.

## Completion and on-time KPIs
Three cards run across the top. **Workorders** carries the counts, **Financials** carries the money, and **Hours** is a donut splitting total hours into production and labor.

A task is *on time* when it completed before its due date, or when it has no due date at all. It is behind when it has a due date and either completed after it or is still open past it.

| KPI | Definition | Counts what |
|---|---|---|
| **Workorders** | Every task in the window after the filters | Tasks, not jobs. A job for 250 of `BH-4021` with three operations contributes three |
| **Completed** | Tasks at status **Done** | Closed work only |
| **Active** | Tasks that are neither **Done** nor **Approved** | Open, In Progress and On Hold |
| **Completion** | Completed ÷ Workorders | The whole window, not a rolling rate |
| **On-time** | On time ÷ (on time + behind) | Every task carrying a due date, plus every task carrying none |
| **Losing money** | Share of tasks whose profit is below zero | Needs budgets to mean anything |
| **Margin** | Total profit ÷ total budget | The small percentage under the **Financials** number |

> **Warning:**
> **Why don't Completed and Active add up to Workorders?**
>
> A task at status **Approved** counts in neither. It stays in the **Workorders** total and it lowers **Completion**, so a plant that approves tasks after closing them reads as less complete than it is.

> **Info:**
> **A task with no due date counts as on time.**
>
> It lands in both halves of the on-time fraction, so a board where half the work was never given a due date reports an on-time rate it did not earn. Check the **Due date** column before you trust the number. See [Job and scheduler fields](/docs/production/job-fields-reference/).

![The Workorders card, showing a large count above four chips reading Completed, Active, Completion as a percentage and On-time as a percentage, beside the Financials card and its Total cost, Labor cost, Production cost and Losing money chips, with numbered callouts on Completion and On-time](/images/production/prod-insights-02.webp)

*Completion and on-time KPIs across the period.*

## Set hourly rates
Select **Options** at the right of the filter bar. It holds two fields.

1. Enter **Labor $/hr**, the hourly cost of an operator. It opens at `35`.
2. Enter **Production $/hr**, the hourly cost of a machine running. It opens at `50`.
3. Select **Apply**, or press Enter in either field.

A blue dot on the **Options** button means a rate is typed but not applied. **Reset**, beside **Apply**, returns both fields to the defaults and clears the filters with them.

> **Warning:**
> **The rates are not saved.**
>
> They belong to the report, not to your organization, so they return to $35 and $50 on every page load and nobody else sees the numbers you typed. Write your two rates down somewhere your team can find them, or two people will price the same week differently.

**Use fully burdened hourly cost, and use one pair of rates for the whole plant.** Fully burdened means wage plus benefits, overhead and downtime allowance for labor, and machine cost plus power, tooling and floor space for production.

Insights applies one labor rate and one production rate to everything in the window by design, so there is no per-machine rate to argue about. A per-machine rate that is really a guess turns every machine comparison into a comparison of guesses.

![The Options popover open below the Options button, showing a numbered callout on a Labor $/hr field reading 35 and a second on a Production $/hr field reading 50, each prefixed with a dollar sign, above a Reset link and a dimmed Apply button](/images/production/prod-insights-03.webp)

*Setting hourly rates. Use fully burdened cost, and set them once for the whole plant.*

## The cost model
A task's *actual* is what it cost: the hours recorded against it, priced at your two rates. A task's *budget* is the dollar figure typed on the task when it was created, which is what you expected to be paid or to spend. Profit is the difference.

| Input | Set on | Unit | Used in |
|---|---|---|---|
| **Labor $/hr** | The **Options** menu on this page | Dollars per hour | Labor cost, Total cost, `Labor $/unit`, Profit |
| **Production $/hr** | The **Options** menu on this page | Dollars per hour | Production cost, Total cost, `Production $/unit`, Profit |
| Labor hours | Sessions operators logged against the task | Hours | Labor cost, the **Hours** donut |
| Production hours | Machine time recorded against the task | Hours | Production cost, the **Hours** donut |
| **Budget** | The task, in **Create Workorder** or inline on the scheduler board | Dollars | Profit, Margin, the **Budget** bar |
| Units | The task's good count | Parts | The two per-unit columns, `Profit/u` |

Total cost is labor cost plus production cost. Profit is budget minus total cost, and margin is total profit over total budget across the window.

For example, `OP20 Turn` on job `BH-4021` logs 6.0 labor hours and 9.5 production hours. At $35 and $50 that is $210 of labor and $475 of production, so total cost is $685. Against a $900 budget the task shows $215 profit and a 23.9% margin, and 400 good parts make that $1.71 profit a unit.

> **Info:**
> **No budgets on your tasks?**
>
> Then profit and margin have nothing to subtract from, and the **Financials** card reads as pure loss. Use **Total cost**, **Labor cost** and **Production cost** on that card and ignore the large number above them until budgets are in.

## Budget versus actual
**Financials: Profitability**, the column chart below the cards, is where cost meets the quote. One column per bucket, bucketed on the date each task was *created*. The **Weekly** and **Monthly** toggle at its top right also moves the **Volume** chart above it.

| Series | Color | Shows | Visible by default |
|---|---|---|---|
| **Budget** | Gray | The bucket's total quote, drawn as a wide bar behind the rest | No. Select it in the legend |
| **Production cost** | Dark orange | Machine hours priced at **Production $/hr** | Only when no task in the window has a budget |
| **Labor cost** | Light orange | Operator hours priced at **Labor $/hr** | Only when no task in the window has a budget |
| **Profit / Loss** | Green, turning red below zero | Budget minus total cost, stacked on the cost | Only when at least one task has a budget |

The chart reads your data before it draws. Give one task a budget and it switches from a cost breakdown to a profit stack, so two organizations looking at the same chart can see different series. Select **Budget** in the legend to put the quote behind the stack, and the gap between the gray bar and the colored one is the variance.

The largest gap is the job worth opening. A week where production cost runs long against a flat budget usually means the machine took longer than the quote assumed, which the `Production / Labor (h)` column in the table below will confirm.

![The Financials Profitability column chart with a Weekly and Monthly toggle at its top right, showing gray Budget bars behind narrower stacks of dark orange production cost, light orange labor cost and a green Profit segment that turns red below the zero line in three weeks, with a violet arrow at the deepest of them, Aug 17](/images/production/prod-insights-04.webp)

*Budget against actual. The largest variance is the job worth investigating.*

**You do not need this page to know whether you are late.** On-time is visible on the scheduler board, where an overdue task is marked in place.

Insights exists to put money on it. See [Plan jobs on the scheduler board](/docs/production/scheduler/).

## The operations table
**Details: All operations** at the foot of the page is one row per task, 20 rows a page, sorted newest first. Select any header to sort by it.

Three of its columns pack two numbers each, colored dark orange for production and light orange for labor: `Production / Labor (h)` draws a bar for each, scaled to the largest value on the page rather than in the whole report; `Production / Labor Cost` prices those hours; and `Production / Labor $/unit` divides by good count and adds a donut showing production's share of the cost. `Profit` and `Profit/u` are green at or above zero and red below.

The **Group** pill above the table offers **None**, **Job** and **Asset**. Grouping moves that column to the front, keeps each group's rows together, and adds a totals row per group covering every matching row rather than only the page on screen. Group by **Job** to find the job that lost money, and by **Asset** to find the machine that keeps eating hours.

![The All operations table grouped by job, showing the Job, Operation, Part, Asset, WO #, Title, Status, Qty and Profit columns, with a totals row closing each of four job groups, a Group pill set to Job above it and an Export CSV button carrying a menu chevron above right](/images/production/prod-insights-05.webp)

*The operations table, and its CSV export.*

## Export
**Export CSV**, at the top right of the table, downloads every row your filters match in the sort order on screen, not only the visible page. With **Group** set to **None** it downloads at once. With **Group** set to **Job** or **Asset** it opens a menu offering **Operation rows**, **Totals by job** or **Totals by asset**, and **Rows + totals**.

Column lists for all three layouts are in [Production Insights CSV](/docs/monitoring/exports-reference/#insights-csv). The file carries the rates you applied, baked into the cost columns, so label it with them before you send it on.

## When the report is empty
| Symptom | Cause | Fix |
|---|---|---|
| **No insights available for the selected range.** | No task was created inside the window | Widen the date range before you suspect the data. A new board often has nothing in the last 90 days |
| The cards read zero and the charts are blank | The filters exclude everything | Select **Reset** in the **Options** menu, then reapply one filter at a time |
| **No workorders match the current filters.** under the table | The search box or a status button is still narrowing rows | Clear the search with the **✕** inside the pill, and select **All** |
| **Not enough date data** under a chart | The matching tasks carry no creation date, so nothing can be bucketed | Check the range. An ERP import that skipped dates also causes it. See [Import a schedule from your ERP](/docs/production/import-erp-schedule/) |
| Every cost column reads `$0.00` | Both rate fields are empty, so nothing is priced | Reopen **Options**, enter both rates, and select **Apply** |
| Cost is zero but the work ran | No session was ever logged against the task, so there are no hours to price | See [Start, pause, and complete a job](/docs/production/run-a-job/) |
| **Failed to load insights.** | The request for the report failed | Select **Retry**. If it repeats, narrow the range: a year at a busy plant is a large request |

## See also
- [Plan jobs on the scheduler board](/docs/production/scheduler/)
- [Start, pause, and complete a job](/docs/production/run-a-job/)
- [Job and scheduler fields](/docs/production/job-fields-reference/)
- [Exports and report columns](/docs/monitoring/exports-reference/)
- [Compare production over weeks and months](/docs/production/historical-production/)
