Building Custom Work Order KPIs in MAS 9 with KPI Manager

🎯 Who this is for: Maximo developers, analysts, and administrators who read Part 3, liked the operational dashboard, and then asked the obvious next question — "but how do I build a KPI that isn't in the box?"

Series: Part 4 of 6 — MAS 9 Work Order Operations: The Missing Pieces | Read time: 20 minutes

📖 Where Part 3 Ended and This Part Begins

Part 3 walked you through the operational dashboard — the Maintenance Manager dashboard, the out-of-box work order KPIs, and how to read them. That's the consumption side: someone already defined those KPIs, and you're placing cards and reading numbers.

This part is the creation side. The out-of-box KPIs are a starting point, not the finish line. Every real Maximo shop measures something IBM never shipped — a backlog that's counted a specific way, a schedule-compliance number tied to your status flow, a craft-utilization metric that only makes sense against your org structure. That's what the KPI Manager application is for.

So this post won't re-list the out-of-box KPIs or re-explain the Maintenance Manager dashboard — Part 3 owns that. Here we build.

🧱 What KPI Manager Actually Is

The KPI Manager application is where every KPI in Manage lives — the ones IBM ships and the ones you create. A KPI, at its core, is a small, saved definition with a handful of parts:

ElementWhat it doesExample
Name / descriptionThe label people read on the cardWO Aging Backlog > 30 Days
Target objectThe Maximo object the KPI queriesWORKORDER
Query (where-clause)Defines which records countstatus = 'APPR' and targstartdate < sysdate
Refresh intervalHow often Maximo recalculates the valueEvery 15 minutes
ThresholdsGreen / yellow / red bands for auto-coloringGreen <10, Yellow 10–25, Red >25
Trend periodThe window over which direction is computedRolling 12 months

That's the whole anatomy. Once a KPI is saved in KPI Manager, it becomes a reusable object that any operational dashboard can point a card at. Build it once, place it many times.

<aside>
💡 Key insight: A KPI is not a report and it's not a card. It's a definition. The card is just the picture frame. This separation is why one well-built backlog KPI can appear as a value tile on the manager's dashboard, a trend line on the planner's, and a color tile on the shift-handover screen — same definition, three frames.
</aside>

🛠️ Building a Custom Work Order KPI

Here's the seven-step path through KPI Manager for a work order KPI. Nothing here is invented — it's the standard KPI Manager flow applied to WORKORDER.

  1. Name and describe it. Be specific — WO Aging Backlog > 30 Days, not Backlog2. Dashboards get crowded; the name is the label people read.
  2. Select the target object. For work order metrics that's usually WORKORDER; for maintenance compliance it may be PM. A KPI can target any Maximo object, which is the point — you are not limited to a fixed catalog.
  3. Write the where-clause. This is the heart of it. The where-clause defines which records count. Conceptually, an aging-backlog KPI is "approved work orders whose target start is in the past" — expressed illustratively as a condition like status = 'APPR' and targstartdate < sysdate.
  4. Set the refresh interval. How fresh does this number need to be? A live dispatch metric might refresh every 15 minutes; a monthly PM-compliance figure can refresh far less often. Don't set everything to real-time — refresh has a cost.
  5. Define thresholds. Assign the green / yellow / red bands. For a backlog count you might set green below 10, yellow 10–25, red above 25. For a compliance percentage the direction flips — red is low.
  6. Configure the trend calculation. Set the period over which the KPI computes direction, so cards can show whether the number is improving or sliding.
  7. (MAS 9.1) Point the KPI service at an external API — optionally. In 9.1 a KPI service can call an external REST API for its data instead of running a Maximo query. More on that below.

<aside>
💡 Key insight: Treat the where-clause examples in this post as conceptual. The exact field names and status codes in your environment depend on your data model and your status flow — the shape is status = ... and somedate < ..., but validate the actual columns against your own schema before you save. A KPI that counts the wrong population looks authoritative and is quietly wrong, which is worse than no KPI at all.
</aside>

🔬 A Worked Build: "WO Aging Backlog > 30 Days"

Let's build one end to end, so the seven steps stop being abstract. The goal: a KPI that tells the planning team how much approved work has been waiting more than a month, and lights up before it becomes a problem.

Step 1 — Name it. WO_ Aging Backlog > 30 Days. Description: "Approved WOs whose target start is more than 30 days in the past. Direction: DOWN is good."

Step 2 — Target object. WORKORDER.

Step 3 — Where-clause (conceptual). Approved work whose target start slipped past a month ago: status = 'APPR' and targstartdate < (sysdate - 30) and historyflag = 0. The historyflag = 0 keeps closed/archived rows out — an easy detail to forget, and the reason a backlog KPI sometimes reads absurdly high.

Step 4 — Refresh interval. 15 minutes. Planners act on this during the day, so it should feel live, but a backlog doesn't move fast enough to justify anything tighter.

Step 5 — Thresholds. This is a count you want low, so red is the high number:

BandRangeMeaning
🟢 Green< 10Backlog under control
🟡 Yellow10 – 25Watch it
🔴 Red> 25Intervene — reassign or escalate

Step 6 — Trend period. Rolling 12 weeks, so the planner can see whether the aging backlog is trending up or being worked down over the quarter.

Step 7 — Place it. Save the KPI, then open the operational dashboard and add a KPI Value card pointing at it for the manager's board, plus a Threshold Tile on the shared stand-up screen so the color does the talking.

That's a complete, useful KPI in about ten minutes — and every one of those decisions (the 30-day cutoff, the historyflag filter, the direction, the bands) is a policy choice you made deliberately, not a default you inherited. That deliberateness is the difference between a KPI people trust and one they quietly ignore.

🎨 Thresholds: The Feature That Does the Most Work

Thresholds are the smallest part of the definition and the highest-leverage. Once you set green / yellow / red bands, the dashboard colors the KPI automatically — a card flips to red the instant the underlying work order population crosses your line, with nobody watching.

The only thing to get right is direction:

KPI shapeYou want it…So red means…
Backlog countLowA high number
Overdue WO countLowA high number
Schedule compliance %HighA low number
PM compliance %HighA low number

Get the direction backwards and your dashboard glows green while the shop is on fire. It's the single most common threshold mistake, and it's a thirty-second fix — just decide, per KPI, whether up is good or bad before you type the bands.

💡 In MAS 9.1, the Threshold Tile card renders a KPI as one big color-coded tile against exactly these bands — the most direct possible expression of a thresholded KPI. It's covered as a card choice below.

📊 Matching a KPI to the Right Card

A KPI is shape-agnostic; the card decides how it reads. Part 3 introduced the dashboard's card catalog — here's the build-side view, focused on the question each card answers:

Card typeAnswers the questionVersion
KPI Value"What's the number right now, and is it moving?"9.0
KPI Trend"How has this behaved over the last N months?"9.0
KPI Comparison"How does this break down by site / work type / craft?"9.0
Threshold Tile"Are we in the green, yellow, or red band?"9.1

The rule of thumb: pick the card to match the decision the viewer is making. A dispatcher deciding right now wants a KPI Value or Threshold Tile. A planner reviewing a quarter wants a KPI Trend. A manager comparing crews wants a KPI Comparison. Same KPI definition underneath — you're just choosing the frame that fits the moment.

⚡ The MAS 9.1 External API Unlock

Through MAS 9.0, a KPI is a query against a Maximo object. Full stop. If the number you want to show doesn't live in a Maximo table, you can't make a KPI out of it — you'd have to integrate that data into Maximo first, then query it.

MAS 9.1 changes that. In 9.1, KPI services can return JSON from an external REST API instead of running a Maximo query. The KPI still renders on a card the same way, with the same thresholds and trend behavior — but its source can be another system entirely.

Think about what that opens up for work order operations:

  • A KPI card showing a contractor's live crew count pulled from their scheduling API.
  • A parts-availability figure sourced from a supplier or ERP endpoint, sitting next to your backlog KPI.
  • A weather or safety index from an external service, so the shift-handover dashboard shows the field condition alongside the work queue.

<aside>
💡 Key insight: This is the difference between a Maximo dashboard and an operations dashboard. Before 9.1, everything on the board was Maximo data by definition. After 9.1, a KPI card is a display surface for any number your services can fetch as JSON — Maximo becomes the frame, not the boundary. If you're on 9.0 and this is on your roadmap, it's a concrete reason to prioritize the 9.1 step.
</aside>

The honest caveat: an external-API KPI is only as reliable as the endpoint behind it. A Maximo where-clause fails loudly inside your own system; a remote API can go slow or dark without warning. Own the endpoint's uptime, and set the refresh interval with that latency in mind.

🍳 Three WO KPI Recipes You'll Actually Build

Concrete beats abstract. Here are three work order KPIs worth building on day one — described conceptually, because your exact fields and codes are yours to confirm.

Recipe 1 — Aging backlog (> 30 days)

Count approved work orders whose target start has been in the past for more than a month (the worked build above). Conceptually status = 'APPR' and targstartdate < (sysdate - 30). Thresholds: low is good, so red is a high count. Card: KPI Value on the manager's board, or a Threshold Tile for the morning stand-up.

Recipe 2 — Schedule compliance

The share of scheduled work that actually got done on time. It's a percentage, so high is good — flip your thresholds. Best shown as a KPI Trend so the team sees whether the last few months are climbing or slipping.

Recipe 3 — Emergency-work ratio by craft

How much of each craft's work is reactive versus planned. Same underlying idea broken out across a dimension — a natural KPI Comparison card. It turns "we do too much firefighting" from a feeling into a number per crew.

⚠️ Edge Cases and Troubleshooting

KPIs fail quietly — they keep showing a number, just the wrong one. Here's how to diagnose the common ones.

SymptomWhat it meansWhat to do
KPI reads impossibly highClosed/history rows aren't filtered outAdd historyflag = 0 (or your equivalent) to the where-clause
KPI shows 0 when you expect recordsWhere-clause is too tight, or a status code is wrong for your flowTest the where-clause as a list query first; confirm the actual status values
Dashboard glows green while the shop is on fireThreshold direction is backwardsFlip the bands; write "up/down is good" in the description
KPI card is slow, or the dashboard dragsUn-indexed columns or a heavy query on every refreshFilter on indexed columns; lengthen the refresh interval
KPI count doesn't match a report's numberDifferent filters, or a snapshot-vs-live timing gapReconcile the definitions; remember the KPI is live at its refresh interval
External-API KPI shows stale or blank values (9.1)The remote endpoint is slow, down, or changed its responseVerify the endpoint; align the refresh interval to its latency; treat it as an external dependency
Two teams argue over "the backlog number"Two KPIs, two where-clauses, same nameStandardize one governed definition and point both cards at it

The pattern: a wrong KPI is more dangerous than a missing one, because it carries the authority of a number on a dashboard. Test the where-clause as a plain list query before you trust it as a KPI.

🧠 Why It Works This Way

Two design choices in KPI Manager are worth understanding, because they shape how you should build.

A KPI is a definition, not a display. IBM deliberately separated the what to measure (the KPI) from the how to show it (the card). That separation is why the same aging-backlog KPI can be a value tile, a trend line, and a threshold tile across three dashboards without three definitions to maintain. Build the metric once, cleanly, and let the cards do the presentation. It also means a fix to the definition propagates everywhere the KPI is shown — one place to correct, not ten.

The external-API capability arrived in 9.1, not earlier, for a reason. Through 9.0, tying KPIs to the Maximo object model kept them fast, governed, and trustworthy — the number always came from your own system. Opening KPIs to external JSON in 9.1 is a deliberate expansion of the dashboard from a Maximo view to an operations view, and it comes with the deliberate trade-off we flagged: you gain reach, and you take on the reliability of whatever endpoint you point at. IBM added the capability once the dashboard was mature enough to be an operational command center rather than just a Maximo report surface — which is exactly the framing from Part 3.

🔧 Practical Notes Before You Build in Production

  • Standardize naming first. KPIs proliferate. Agree on a convention (WO_ Aging Backlog, PM_ Compliance) before ten people create three versions of the same metric.
  • Match refresh to reality. A number nobody acts on in real time doesn't need a 15-minute refresh. Reserve tight intervals for genuinely live operational KPIs.
  • Decide threshold direction per KPI, explicitly. Write "up is good" or "down is good" in the description. It prevents the glowing-green-while-on-fire failure mode.
  • Test the where-clause as a list query first. If it returns the right records in a result set, it'll count the right population as a KPI. If it doesn't, you've caught the error before it reached a dashboard.
  • Govern custom KPIs like Part 3 governs dashboards. Who owns the definition? Who can edit the where-clause? A wrong KPI definition is a silent data-quality problem — treat KPI definitions as change-controlled objects, not throwaway tweaks.
  • Confirm your 9.1 posture before promising external-API KPIs. The JSON-from-external-API capability is a 9.1 feature. If you're on 9.0, it's a reason to plan the step, not a thing you can wire up today.

Key Takeaways

  • KPI Manager is the build side of the story; Part 3 is the consume side. A custom KPI is a named where-clause against any Maximo object, plus a refresh interval, thresholds, and a trend period.
  • Color thresholds (green / yellow / red) drive automatic card coloring — get the direction right per KPI or the dashboard lies to you.
  • Match the KPI to the card: KPI Value for "now," KPI Trend for "over time," KPI Comparison for "by dimension," and the 9.1 Threshold Tile for "which band."
  • MAS 9.1 lets KPI services return JSON from an external REST API, so a work order dashboard can show numbers that never lived in Maximo — at the cost of owning that endpoint's reliability.
  • Treat where-clause examples as conceptual — validate the real fields and status codes against your own schema, and test as a list query before you trust the KPI.

References

Series Navigation

Previous:Part 3 — The Operational Dashboard for Work Order Management
Next:Part 5 — From BIRT Reports to KPIs

About TheMaximoGuys: We help Maximo developers and teams navigate the move to MAS 9 with practical, no-hype guidance grounded in how the platform actually behaves.

Published by TheMaximoGuys | July 2026