Defect Aging and SLA Metrics: How to Measure and Report Them

Defect Aging and SLA Metrics: How to Measure and Report Them

Last updated: October 2026

Defect aging tells you how long each defect has been open, and an SLA tells you how long it was allowed to stay open. Most QA teams track one without the other, so an old Sev 2 sits in the backlog until a release review finds it. This guide shows how to calculate defect aging, set SLA targets by severity, and report both from Jira, Excel and SQL without misleading anyone.

What you will get

  • Formulas for open age, closed age and SLA compliance
  • An example SLA policy by severity you can adapt
  • A decision tree for calendar days, business days or business hours
  • JQL filters, Excel formulas and a T-SQL query for aging buckets
  • Two fictional scenarios: an EHR upgrade and a payments API contract
  • Edge cases that quietly break aging numbers

What defect aging measures

Defect aging is the time between the moment a defect is logged and either its resolution or today. The ISTQB Foundation Level syllabus treats defect reports as a core test management work product. Aging turns those reports into a time signal: which problems are waiting, and for how long.

There are two versions of the number, and mixing them is the first common error. Closed age describes how fast the team fixed things in the past. Open age describes the risk sitting in the backlog right now.

Metric Formula Question it answers
Open defect age as-of date − opened date How long has this defect been waiting?
Closed defect age resolved date − opened date How long did the fix take?
Time in status sum of time spent in one status Where does the waiting happen: dev, retest or info requests?
SLA compliance closed within target ÷ all closed Did we keep our promise last period?
Open past SLA count of open defects with age > target Which promises are already broken?

Defect age vs resolution time

Resolution time is closed age reported as an average across many defects. The TechFitFlow guide on bug tracking metrics covers mean time to resolution by severity. Aging adds what that average hides: the defects that never closed.

A team can post a fast average resolution time while a handful of hard defects sit for months. Those never enter the average until someone finally closes them. Open age by bucket is the number that exposes them.

Defect SLA or SLO: which one does your team have?

Google’s Site Reliability Engineering book draws a line that QA teams rarely draw. An SLO is a target value for a measured service level. An SLA is an agreement that attaches consequences to meeting or missing those targets.

The SRE book’s test is simple: ask what happens if the target is missed. If nothing explicit happens, it is almost certainly an SLO, whatever your process document calls it.

Internal defect target (SLO) Contractual defect SLA
Who sets it QA lead, dev lead and product owner Contract between vendor and client
What a miss triggers Escalation, triage discussion Service credits, penalties, formal review
Clock rules Your team decides and can change them Written in the contract; follow them exactly
Typical use Test phases, sprints, UAT Production support, vendor-owned defects

This guide uses “SLA” for both, because that is how most defect workflows name it. Keep the distinction in mind when you report: a missed internal target is a conversation, while a missed contractual SLA is a cost.

Setting defect SLA targets by severity

No standard body publishes universal defect SLA values. Targets depend on release cadence, team size and what a defect blocks. The table below is an example starting point for a team that works weekdays, not an industry norm.

Severity Example meaning Response target Resolution target
Sev 1 Critical Blocks testing or a core workflow, no workaround 1 business hour 1 business day
Sev 2 High Major function wrong, workaround is painful 4 business hours 3 business days
Sev 3 Medium Function wrong, reasonable workaround exists 1 business day 10 business days
Sev 4 Low Cosmetic or minor, no functional impact 3 business days 30 business days or next release

Tie the targets to severity, not priority. Severity describes impact, while priority describes order of work. A low-severity defect can be high priority because a demo is tomorrow, but that should not move its SLA. The guide on priority vs severity covers that split in detail.

Rules to write down before the first report

  • Start event. Usually the created timestamp. For defects logged outside office hours, decide whether the clock starts at once or at the next business hour.
  • Stop event. Resolved by development, or closed after retest. Pick one per metric and label it.
  • Pause conditions. Jira Service Management lets admins define start, pause and stop conditions for SLAs. Common pauses are “Waiting for information” and “Waiting for vendor”.
  • Severity changes. If a Sev 2 is downgraded to Sev 3 on day 4, does the target become 10 days from the original open date? Write the rule and apply it the same way every time.
  • Reopens. Continue the original clock. A reopened defect was never really fixed.
  • Exclusions. Rejected, duplicate and “works as designed” defects leave the SLA population.

Where the SLA clock runs

New: clock runs
→
Triaged: clock runs
→
In progress: clock runs
→
Waiting for info: paused
→
Fixed / retest: clock runs
→
Closed: clock stops

Reopened defects resume from their previous total, not from zero. Rejected and duplicate defects leave the SLA report.

Calendar days, business days or business hours

The clock you choose can flip a defect from met to missed with no change in team behavior. A Sev 1 opened Friday afternoon and fixed Monday morning took 3 calendar days but 1 business day.

Clock Fits when Watch out for
Calendar days 24/7 production support; patient-facing or revenue systems Weekday teams look slow every Monday
Business days Test phases and sprints staffed Monday to Friday Needs a holiday list that matches the team’s location
Business hours Targets under 2 days, contracts written in hours Time zones; whose working hours count

1. Is there a contract with consequences?

Yes: use the contract’s clock, hours and time zone exactly. Stop here.

No: go to question 2.

2. Does anyone fix defects on weekends?

Yes: use calendar days.

No: go to question 3.

3. Is the shortest target under 2 days?

Yes: business hours for Sev 1 and Sev 2, business days for the rest.

No: business days for all severities.

A worked example: same defects, two clocks

The six fictional defects below are measured as of Friday, October 23, 2026, with no holidays in range. Targets come from the example policy above.

Defect Severity Opened Resolved Calendar days Business days Target (business days) Business-day result Calendar-day result
PROJ-1042 Sev 2 Mon Oct 5 Thu Oct 8 3 3 3 Met Met
PROJ-1047 Sev 1 Fri Oct 9 Mon Oct 12 3 1 1 Met Missed
PROJ-1051 Sev 3 Tue Oct 6 Open 17 13 10 Open, breached Open, breached
PROJ-1055 Sev 2 Wed Oct 21 Open 2 2 3 Open, within SLA Open, within SLA
PROJ-1058 Sev 4 Thu Sep 10 Open 43 31 30 Open, breached Open, breached
PROJ-1060 Sev 3 Mon Oct 12 Fri Oct 23 11 9 10 Met Missed

Measured in business days, all three closed defects met their targets: 100% compliance. Measured in calendar days against the same numbers, only one did: 33%. Nothing about the work changed, only the clock.

How to calculate defect aging in Jira

Jira Software has no built-in report for defect resolution time, as of October 2026. Atlassian’s knowledge base says so and suggests a workaround: an automation rule that writes the days between created and resolved into a number field. That value is stored once, in whole days, when the issue reaches the final status.

For open defects, JQL filters give you the aging buckets directly. Relative dates must be wrapped in quotes. Atlassian’s JQL reference notes that an unquoted value is read as milliseconds, so created < -30d does not behave as intended.

-- Open bugs older than 14 calendar days, worst first
project = PROJ AND issuetype = Bug AND resolution = Unresolved
AND created < "-14d"
ORDER BY priority DESC, created ASC

-- Stale bugs: open, and nobody has touched them for 7 days
project = PROJ AND issuetype = Bug AND resolution = Unresolved
AND updated < "-7d"

-- Bugs resolved this month, for SLA compliance
project = PROJ AND issuetype = Bug AND resolved >= startOfMonth()

Correct result for the first filter: only unresolved bugs whose Created date is more than 14 days before now. If closed bugs appear, your workflow closes them without setting a Resolution.

Two checks before you trust these filters. First, open one closed bug and confirm its Resolution field is set; otherwise it still matches resolution = Unresolved. Second, in service team-managed spaces the Resolution field is not available, and Atlassian suggests statusCategory = Done instead.

JQL relative dates count calendar time from now. For business-day aging, export the filter to CSV and calculate in Excel or SQL. The step-by-step guide on creating a defect in Jira covers the fields that need to be filled for these filters to work.

How to calculate defect aging in Excel

Put the export in an Excel table named Defects with columns Opened, Resolved, Severity and Target. Add a named cell AsOf for the report date and a named range Holidays.

Calendar age:
=IF([@Resolved]="", AsOf-[@Opened], [@Resolved]-[@Opened])

Business age:
=MAX(0, NETWORKDAYS([@Opened], IF([@Resolved]="", AsOf, [@Resolved]), Holidays) - 1)

Aging bucket:
=LOOKUP([@[Business age]], {0,3,8,15,31}, {"0-2","3-7","8-14","15-30","31+"})

SLA status:
=IF([@Resolved]="",
    IF([@[Business age]]>[@Target], "Open - breached", "Open - within SLA"),
    IF([@[Business age]]<=[@Target], "Met", "Missed"))

SLA compliance (closed defects only):
=COUNTIFS(Defects[SLA status],"Met") /
 (COUNTIFS(Defects[SLA status],"Met") + COUNTIFS(Defects[SLA status],"Missed"))

Correct result: a defect opened and resolved on the same Tuesday shows calendar age 0 and business age 0. Opened Friday and resolved Monday shows 3 and 1.

Why the - 1 and the MAX(0, …)? Microsoft’s documentation example counts both the start and end dates as workdays. Without the subtraction, a same-day fix would show an age of 1. A defect logged on a Saturday and fixed on Sunday would otherwise show -1, which the MAX removes.

Microsoft also warns that dates stored as text cause errors. CSV exports often arrive that way. Convert the Opened and Resolved columns to real dates before applying the formulas. For weekends other than Saturday and Sunday, use NETWORKDAYS.INTL.

Once ages and statuses exist, a pivot table by severity and bucket gives you the weekly view. The walkthrough on pivot tables for defect reporting shows that build step by step.

TechFitFlow toolkit (paid)

QA Defect Tracker (Excel)

Skip building this workbook. Paste your defects into the log and the aging, SLA flags and report fill in.

  • SLA days per severity on a settings tab, feeding an automatic “Within SLA?” flag on every row
  • Age in days from opened and closed dates against a report “as of” date (calendar days; swap in the NETWORKDAYS formula above for business days)
  • Report tab: open defects by severity and status, by module, and a weekly opened-vs-closed trend

$14 · instant downloadSee what’s inside

How to calculate defect aging and SLA compliance in SQL

When defects land in a reporting database, a calendar table gives you business days without fragile date math. The query below uses SQL Server (T-SQL) and a fictional schema. Run it in a non-production environment first.

One detail matters for aging. Microsoft documents that DATEDIFF counts datepart boundaries crossed, not elapsed time. DATEDIFF(day, '2026-10-09 23:59', '2026-10-10 00:01') returns 1 after two minutes. Cast timestamps to date first so every defect is measured the same way.

-- T-SQL (SQL Server). Fictional tables:
--   dbo.Defect(DefectKey, Severity, Status, OpenedAt, ResolvedAt)
--   dbo.SeveritySla(Severity, ResolveTargetBusinessDays)
--   dbo.BusinessCalendar(CalendarDate, IsBusinessDay)
DECLARE @AsOf date = '2026-10-23';

WITH base AS (
    SELECT
        d.DefectKey,
        d.Severity,
        d.Status,
        CAST(d.OpenedAt AS date)                    AS OpenedDate,
        CAST(d.ResolvedAt AS date)                  AS ResolvedDate,
        COALESCE(CAST(d.ResolvedAt AS date), @AsOf) AS ClockEndDate
    FROM dbo.Defect AS d
    WHERE d.Status NOT IN ('Rejected', 'Duplicate')
)
SELECT
    b.DefectKey,
    b.Severity,
    b.OpenedDate,
    b.ResolvedDate,
    DATEDIFF(day, b.OpenedDate, b.ClockEndDate) AS AgeCalendarDays,
    bd.AgeBusinessDays,
    s.ResolveTargetBusinessDays                 AS TargetBusinessDays,
    CASE
        WHEN b.ResolvedDate IS NOT NULL
             AND bd.AgeBusinessDays <= s.ResolveTargetBusinessDays THEN 'Met'
        WHEN b.ResolvedDate IS NOT NULL                            THEN 'Missed'
        WHEN bd.AgeBusinessDays > s.ResolveTargetBusinessDays      THEN 'Open - breached'
        ELSE 'Open - within SLA'
    END                                         AS SlaStatus
FROM base AS b
CROSS APPLY (
    SELECT COUNT(*) AS AgeBusinessDays
    FROM dbo.BusinessCalendar AS c
    WHERE c.CalendarDate >  b.OpenedDate
      AND c.CalendarDate <= b.ClockEndDate
      AND c.IsBusinessDay = 1
) AS bd
JOIN dbo.SeveritySla AS s
    ON s.Severity = b.Severity
ORDER BY bd.AgeBusinessDays DESC;

Correct result: one row per defect except rejected and duplicate ones. With the six defects from the worked example, PROJ-1058 tops the list at 31 business days and “Open – breached”.

The calendar condition counts business days after the open date, up to and including the end date. That matches the Excel formula, so both tools agree on the same defect.

-- T-SQL. Weekly summary: open defects by severity and aging bucket,
-- plus SLA compliance for defects resolved in the last 30 days.
DECLARE @AsOf date = '2026-10-23';

WITH base AS (
    SELECT
        d.Severity,
        CAST(d.OpenedAt AS date)                    AS OpenedDate,
        CAST(d.ResolvedAt AS date)                  AS ResolvedDate,
        COALESCE(CAST(d.ResolvedAt AS date), @AsOf) AS ClockEndDate
    FROM dbo.Defect AS d
    WHERE d.Status NOT IN ('Rejected', 'Duplicate')
),
aged AS (
    SELECT
        b.Severity,
        b.ResolvedDate,
        s.ResolveTargetBusinessDays AS TargetDays,
        (SELECT COUNT(*)
         FROM dbo.BusinessCalendar AS c
         WHERE c.CalendarDate >  b.OpenedDate
           AND c.CalendarDate <= b.ClockEndDate
           AND c.IsBusinessDay = 1) AS AgeDays
    FROM base AS b
    JOIN dbo.SeveritySla AS s ON s.Severity = b.Severity
)
SELECT
    Severity,
    SUM(CASE WHEN ResolvedDate IS NULL AND AgeDays BETWEEN 0 AND 2   THEN 1 ELSE 0 END) AS [Open 0-2],
    SUM(CASE WHEN ResolvedDate IS NULL AND AgeDays BETWEEN 3 AND 7   THEN 1 ELSE 0 END) AS [Open 3-7],
    SUM(CASE WHEN ResolvedDate IS NULL AND AgeDays BETWEEN 8 AND 14  THEN 1 ELSE 0 END) AS [Open 8-14],
    SUM(CASE WHEN ResolvedDate IS NULL AND AgeDays BETWEEN 15 AND 30 THEN 1 ELSE 0 END) AS [Open 15-30],
    SUM(CASE WHEN ResolvedDate IS NULL AND AgeDays > 30              THEN 1 ELSE 0 END) AS [Open 31+],
    SUM(CASE WHEN ResolvedDate IS NULL AND AgeDays > TargetDays      THEN 1 ELSE 0 END) AS [Open past SLA],
    CAST(
        SUM(CASE WHEN ResolvedDate >= DATEADD(day, -30, @AsOf) AND AgeDays <= TargetDays THEN 1.0 ELSE 0 END)
        / NULLIF(SUM(CASE WHEN ResolvedDate >= DATEADD(day, -30, @AsOf) THEN 1 ELSE 0 END), 0)
    AS decimal(5, 2))                                                                  AS [SLA compliance 30d]
FROM aged
GROUP BY Severity
ORDER BY Severity;

Correct result: one row per severity. The bucket columns add up to that severity’s open count. SLA compliance is NULL, not zero, for a severity with no resolved defects in the window.

Oracle: subtracting two DATE values returns days as a number, so use TRUNC(resolved_at) - TRUNC(opened_at) for calendar age. Snowflake: it also has a DATEDIFF function; check its boundary behavior in the Snowflake documentation before you port the query.

Reporting defect aging: five numbers that hold up

A weekly aging report needs fewer numbers than most teams send. These five answer the questions a release manager actually asks.

  1. Open defects by severity and aging bucket. The shape of the backlog. A growing 31+ column is a warning even when totals look flat.
  2. Open past SLA, by owner team. Names a place to act, not a percentage to debate.
  3. SLA compliance for defects closed this period. The promise-keeping rate. Report the denominator next to it.
  4. Median open age by severity. Less distorted by one ancient defect than the average.
  5. Stale count. Open defects with no update in 7 days. Often the cheapest to fix, because nobody is working them.
Statistic Open business ages 13, 2, 31 What it tells you
Mean 15.3 days Pulled up by the single oldest defect
Median 13 days The typical open defect
Maximum 31 days The defect to name in the meeting

Scenario 1: an EHR upgrade with a vendor in the loop

Lakeside Regional Health, a fictional hospital system, runs regression testing for a quarterly EHR upgrade. The test window is three weeks, followed by a change freeze before go-live. Compliance wants signed evidence of every Sev 1 and Sev 2 resolution.

On day 6, a tester logs PROJ-1042, a Sev 2. Medication reconciliation drops a home medication for test patient “Test, Alpha”, MRN 000123. Triage traces it to vendor-delivered content, so the internal team cannot fix it alone.

The SLA report shows PROJ-1042 breached on day 9 and the dev lead objects. The team waited four days on the vendor. Both views are true, so the team reports two clocks:

  • Total age: the release risk. Leadership needs it for the go/no-go call.
  • Internal age: total age minus time in “Waiting for vendor”. This is the number the internal SLA applies to.

The constraint that shapes the fix is the freeze date, not the SLA. A Sev 2 still open at freeze needs a documented workaround or a delay decision. Showing vendor wait time separately moves that conversation to the vendor manager a week earlier.

Scenario 2: a payments API with a contractual SLA

Northgate Payments, a fictional processor, supports a bank partner under a contract. Production Sev 1 defects must be resolved within 8 business hours, measured in the bank’s time zone, or service credits apply. By the SRE definition, that is a true SLA.

The development team sits in another time zone and works a different day. Their internal tracker measured in local business days, so a defect could look healthy internally while the contractual clock had already expired.

The fix was to report the contractual clock exactly as written, in the bank’s hours, and to set a tighter internal target as an SLO. The internal target gives a buffer before money is at stake. Every Sev 1 ticket stores both the contract deadline timestamp and the internal one.

Edge cases that break aging numbers

  • Migrated tickets. After a tool migration, Created can be the import date. Every legacy defect then looks young. Keep the original open date in its own field.
  • Bulk closures. A release clean-up that closes 80 old defects in one afternoon wrecks the resolution-time average for that week. Report “closed as won’t fix” separately.
  • Severity downgrades. A Sev 2 that misses its SLA and is quietly downgraded to Sev 3 disappears from the breach list. Log severity changes and report the original severity too.
  • Reopens. Starting a new clock on reopen hides fixes that did not work. Continue the original clock and count reopens on their own.
  • Weekend logging. Automated test runs log defects at 2 a.m. Saturday. Decide whether the clock starts then or at the next business hour.
  • Holidays by location. A team split across countries has different holiday lists. Use the list for the team that owns the fix, or the one named in the contract.

Common mistakes with defect aging and SLA reports

Mistake Why it hurts Fix
Reporting only average resolution time Defects that never close are invisible Add open age by bucket
Counting rejected and duplicate defects Inflates compliance with fast, empty closures Exclude them from the SLA population
Calendar days for a weekday team Every Friday defect looks late Business days with a holiday list
SLA tied to priority Targets move whenever the plan changes Tie targets to severity
No written pause rules Every breach becomes an argument Agree start, pause and stop events first
Compliance % without the denominator 100% of 2 looks like 100% of 200 Show “x of y” next to every rate

FAQ

What is defect age in software testing?

Defect age is the time a defect has been open. For an open defect it runs from the logged date to today. For a closed defect it runs from the logged date to resolution.

How do you calculate defect aging?

Subtract the opened date from the resolved date, or from the report date if the defect is still open. Decide first whether you count calendar days, business days or business hours. In Excel, use NETWORKDAYS minus 1 for business days.

What is the difference between an SLA and an SLO for defects?

An SLO is a target. An SLA is an agreement with consequences, such as service credits, attached to missing the target. Most internal QA targets are SLOs, even when the team calls them SLAs.

Should defect aging count weekends and holidays?

Count them only if someone works defects on those days. A weekday test team should use business days and a holiday list, or its weekend defects will look late. Production support for 24/7 systems usually counts calendar time.

How do you track defect aging in Jira?

Use JQL filters such as created < "-14d" with resolution = Unresolved for open aging buckets. Jira Software has no built-in resolution time report, so Atlassian suggests an automation rule that stores days to resolve in a number field.

Next steps

Write down your clock rules before you report a single aging number. Start, stop, pause, reopen and severity-change rules decide whether your SLA report is trusted or argued over.

  1. Agree the start, pause and stop events with the dev lead and product owner, and record them in your test plan.
  2. Pick a clock with the decision tree above, and build a holiday list for the team that owns fixes.
  3. Set up the three JQL filters and export them weekly into Excel or your reporting database.
  4. Send the five-number report for four weeks, then review whether the targets match reality. If you would rather start from a finished workbook, the QA Defect Tracker (paid) has the log, SLA flags and report tab built in.

Sources

Download the Defect Aging & SLA Checklist (PDF)

Two printable pages: a clock-rules worksheet, a blank SLA policy table by severity, the five weekly report numbers, and the Excel, JQL and SQL formulas from this guide.

Get the free checklist

More free templates, cheat sheets and toolkits: TechFitFlow Resources

Scroll to Top