River
Y CombinatorBacked by Y Combinator
FREE TEMPLATE

Support SLA Reporting Template

Three documents and three sheets that reconstruct each ticket's elapsed time from its pause and reopen history, so two SLA reports on one export finally agree.

Free download  ·  No account needed

Agent Work Time Breach Rate

Fenwick Freight Systems, 391 tickets this quarter

Naive read of the ticket export82 of 391 — 21.0%
Corrected for the written pause and reopen rule29 of 391 — 7.4%

One ticket, worked both ways

TicketTargetNaive elapsedCorrected elapsedDivergence
FF-3017816h51.5h — breach5.5h — within targetFull week sitting Solved before a reopen counted as agent work

124 tickets carried a Pending, On-hold or reopen event this quarter, totaling roughly 1,207 business hours the naive method charged to agents as active work.

Every ticketing platform's export carries a ready-made elapsed-time or resolution-time column, and most SLA reports get built directly on top of it. That column is usually the naive one, a flat business-hours conversion from creation to close. It allows for no status the metric is documented to pause on, and no credit for a ticket that gets solved, reopened, and solved again. Zendesk documents its own pause rules explicitly: Agent Work Time pauses on Pending and On-hold, Requester Wait Time pauses on Pending only, and neither rule transfers to the other.

This pack rebuilds elapsed time per ticket against the rule the policy actually specifies, then publishes the naive and corrected breach rate side by side rather than only the flattering one. Reopens are where most reports go wrong, in one of two ways. One resets the clock to zero. The other carries the full calendar gap through, as if the agent worked the ticket the whole time it sat solved. Zendesk's guide to SLA policies documents a third option: reactivate the target with credit for time spent, and treat the solved window as a pause.

Fenwick Freight Systems ran 391 tickets from a complete ticket export with full status history through this reconstruction across three support queues this quarter. The naive method, reading straight off the export's own elapsed-time column, put the Agent Work Time breach rate at 21.0%. Applying the documented pause and reopen rule instead put it at 7.4%, a 13.6 percentage-point gap traced to 124 tickets and roughly 1,207 business hours of wait time the naive method had charged to agents.

Three sheets, from queue rollup to logged breach

Performance by Queue and Priority, Business-hours Calculation, and the Breach Log.

Performance by Queue and Priority

Agent Work Time, 391 tickets this quarter across three queues, naive versus corrected against the documented pause and reopen rule.

QueuePriorityTargetTicketsNaiveCorrected
Fleet OpsUrgent8h2231.8%13.6%
Fleet OpsHigh16h6428.1%10.9%
Fleet OpsNormal24h9714.4%5.2%
BillingUrgent8h1526.7%6.7%
BillingHigh16h4822.9%8.3%
BillingNormal24h6114.8%4.9%
OnboardingUrgent8h922.2%0.0%
OnboardingHigh16h3129.0%12.9%
OnboardingNormal24h4418.2%4.5%
All queuesAll39121.0%7.4%

Every segment's corrected rate is lower than its naive one, and Onboarding Urgent's nine tickets go from 22.2% naive to zero real breaches once Pending and On-hold time is excluded.

Business-hours Calculation

Five tickets worked by hand, showing exactly where the naive and corrected methods split.

TicketMetricNaiveCorrectedWhy they split
FF-30089Agent Work27.5h, breach27.5h, breachNo pause to misapply
FF-30211Agent Work7.0h, within7.0h, withinNo pause to misapply
FF-30142Agent Work26.0h, breach8.0h, within18h Pending counted as work
FF-30178Agent Work51.5h, breach5.5h, withinA week Solved before reopen counted as work
FF-30205First Reply64h on badge0.25h to deadlineCalendar-hours badge hides the real buffer

Two tickets never touch a pause or reopen and both methods land on the same number. The other three are where a naive report and a corrected one stop agreeing.

Breach Log

One row per real breach against the corrected rule, logged with a reason as it happens.

DateTicketOverageReasonStatus
Apr 6FF-30061+6.4hGPS vendor diagnostic delayFirst occurrence
Apr 19FF-30094+3.9hGPS vendor diagnostic delaySecond occurrence
May 2FF-30117+3.1hFinance sign-off on invoiceFirst occurrence
May 14FF-30138+5.7hCustomer's fleet list incompleteFirst occurrence
May 28FF-30165+5.0hGPS vendor diagnostic delayThird, escalated
Jun 9FF-30183+7.6hBilling-to-Fleet-Ops handoff delayFirst occurrence
Jun 21FF-30201+2.2hAgent on leave, no backupFirst occurrence

The GPS vendor diagnostic reason repeats a third time on May 28 and triggers the review Breach Procedure defines, the only reason in this log that does.

What's in the pack

01

SLA Definitions

Targets by priority for First Reply Time and Agent Work Time, the business-hours calendar, and the pause and reopen rule per metric. Stated in policy language, so both the team publishing the number and the department reading it can check it against the same document.

02

Measurement Method Note

States which business-hours calendar, which pause rule per metric, and which reopen rule per metric produced the published breach rate, with the documented source behind each choice. The next person to recompute this from the raw export lands on the same number instead of a third one.

03

Breach Procedure

What happens on one miss, the reason gets logged and nothing else, versus a reason that repeats three times in a rolling month, which triggers a real review scoped to the corrected breach count rather than the naive one. A review that turns into a customer-facing incident hands off to the escalation matrix.

04

Performance by Queue and Priority

The naive and corrected Agent Work Time breach rate side by side for every queue and priority segment, so the size of the gap between them is visible rather than only the flattering number.

05

Business-hours Calculation

Five real tickets worked by hand against both methods, including the one that shows a solved ticket reopened a week later carrying 51.5 naive hours against 5.5 corrected hours on the same 16-hour target.

06

Breach Log

One row per real breach against the corrected rule, with a one-line reason and no individual review for a single occurrence. A reason appearing three times in a rolling month is the one that gets escalated, and a recurring reason is easier to spot once tickets already carry categories from the ticket categorization template.

07

Why a target number alone is not a measurement

A target like sixteen business hours looks complete on its own. It is not. It says nothing about which statuses pause the clock or what a reopen does to elapsed time, so two people who answer those questions differently get two different, equally defensible rates from the same export. The same discipline, applied to every metric a business reports rather than just this one, is the metric definitions pack.

How it works

  1. 1

    Send the export and the policy

    The full ticket export with status-change history, not just created and closed timestamps, plus your written SLA policy or your current targets if nothing is written down yet.

  2. 2

    Pin down the three choices

    The business-hours calendar, the pause rule per metric, and the reopen rule per metric, each with the specific source in your policy or your platform's documentation, written once in the Measurement Method Note.

  3. 3

    Reconstruct elapsed time per ticket

    Every ticket's real elapsed time against that rule, with a naive version computed the same way your export's own column already does it, so the two numbers can sit side by side.

  4. 4

    Publish both rates, then log what's next

    The queue and priority rollup states the naive and corrected breach rate together, and every future breach gets logged with a reason so a repeated cause triggers the review Breach Procedure defines.

Frequently asked questions

Why do two SLA reports on the same ticket export show different breach rates?

Because a raw export under-determines the number. The business-hours calendar, which statuses pause a given metric, and what a reopen does to elapsed time are three separate choices the timestamps alone do not make. Two people who make them differently get two different, equally defensible rates from identical data.

Does my ticketing platform already exclude Pending or On-hold time from its SLA numbers?

Only for the metrics its own documentation says pause on that status, and that answer is not the same for every metric: Zendesk's Agent Work Time pauses on Pending and On-hold, its Requester Wait Time pauses on Pending only. Applying one metric's rule to another is a common way a report goes wrong.

What happens to elapsed time when a solved ticket gets reopened?

It depends on the metric and the platform's documented behavior, and reports routinely get it wrong in one of two directions: resetting the clock to zero, or counting the whole calendar gap as active work. This pack reconstructs whichever rule the policy actually specifies and states it in the Measurement Method Note.

Is the naive elapsed-time number my export already shows me simply wrong?

Not wrong, incomplete. It is a real, documented computation, usually wall clock or flat business hours with no pause or reopen handling applied, and it is often what the policy intends for a straightforward reply-time metric. The gap only opens up on a metric that is supposed to pause or reactivate.

How is this different from a customer support SLA or an internal service SLA template?

Those set the target itself for a queue, whether external tickets or internal requests, the way the internal service SLA template sets one from historic response times. This pack assumes a target already exists and fixes a separate problem: two people computing the breach rate against that target from the same export land on different numbers, depending on assumptions nobody wrote down.

Does this work if I use Freshdesk, Intercom, or another platform instead of Zendesk?

Yes. The three questions are the same regardless of vendor: which business-hours calendar, which statuses pause which metric, and what a reopen does to elapsed time. Check your own platform's SLA documentation for its specific answers, then apply the same reconstruction this pack uses for Zendesk's.

What if breaches are caused by being understaffed, not a process problem?

This pack finds the breach and its logged reason. It does not ask whether the queue had enough people scheduled in the first place. When a repeat reason traces back to short coverage rather than a single bad ticket, the staffing model template checks required coverage against your actual roster hour by hour, which is usually where a chronic breach really starts.

Report the breach rate your policy actually specifies

Take the documents and sheets blank, or install this pack in River and send it your ticket export's full status history plus your written SLA policy.

Edit with AI