Help Desk Metrics That Matter (and the SQL Behind Them)

Seven help desk metrics that drive decisions — first response, resolution, SLA attainment, backlog age, reopen rate, reassignments and deflection — with definitions, pitfalls and the queries to compute them.

AAAayush AdhikariAugust 2, 2026 7 min read

The help desk metrics that matter are the ones that change a decision: first-response time, resolution time, SLA attainment, backlog age, reopen rate, reassignment count and deflection. Report each as a median and 90th percentile rather than an average, per request category rather than overall, and compute them from timestamps the system records rather than from what agents report. Seven numbers, well defined, beat a dashboard of forty.

Why fewer, better metrics

Every metric you show creates pressure to improve it, and some improve the number without improving the service — closing tickets early to cut resolution time, or sending "looking into it" replies to meet first-response targets. Choose metrics that are hard to game, pair metrics that pull against each other (resolution time with reopen rate), and keep the list short enough that someone actually acts on it.

Two rules apply to all of them:

  • Percentiles, not averages. Google's SRE book makes the point for latency and it applies to tickets: an average can look healthy while a long tail of requests waits for days. Report the median (p50) for the typical experience and the 90th percentile (p90) for the bad one.
  • Per category. A password reset and a laptop purchase have different natural durations. One blended number hides both.

The queries below assume a requests table with created_at, first_response_at, resolved_at, sla_due_at, status, category_id and team_id — the schema from building an internal help desk with Next.js and Supabase.

1. First-response time

What: time from creation to the first public reply by someone other than the requester.

Why: it's what the requester feels first. A fast acknowledgement buys patience for the rest.

Pitfall: counting internal notes or automatic replies. Only a human, public reply should stop this clock.

select c.name,
  percentile_cont(0.5) within group (order by r.first_response_at - r.created_at) as p50,
  percentile_cont(0.9) within group (order by r.first_response_at - r.created_at) as p90
from requests r join categories c on c.id = r.category_id
where r.created_at >= now() - interval '30 days' and r.first_response_at is not null
group by c.name;

Ideas for improving it are in how to cut first-response time in half.

2. Resolution time

What: time from creation to resolved.

Why: it's whether the problem got fixed.

Pitfall: it rewards closing early. Always read it next to reopen rate. If your desk pauses the clock while waiting on the requester, say so in the report — paused and unpaused numbers aren't comparable.

3. SLA attainment

What: the share of resolved requests resolved on or before their deadline.

Why: it turns targets into a single, honest score per category.

select c.name,
  round(100.0 * count(*) filter (where r.resolved_at <= r.sla_due_at) / count(*), 1) as attainment_pct
from requests r join categories c on c.id = r.category_id
where r.resolved_at >= now() - interval '30 days' and r.sla_due_at is not null
group by c.name;

Pitfall: deadlines edited by hand. Store the deadline when a category is set and never overwrite it manually. The mechanics are in the SLA tracking guide.

4. Backlog age

What: open requests grouped by how old they are — under 1 day, 1–3 days, 3–7 days, over a week.

Why: volume tells you how busy you are; age tells you what's being neglected. Old requests are usually stuck on a dependency or nobody's clear responsibility.

select
  count(*) filter (where now() - created_at < interval '1 day') as under_1d,
  count(*) filter (where now() - created_at between interval '1 day' and interval '3 days') as d1_3,
  count(*) filter (where now() - created_at between interval '3 days' and interval '7 days') as d3_7,
  count(*) filter (where now() - created_at > interval '7 days') as over_7d
from requests where status not in ('resolved', 'closed');

5. Reopen rate

What: the share of resolved requests that are reopened (or followed by a new request on the same issue) within a set window, such as 7 days.

Why: it's the counterweight to resolution time. A falling resolution time with a rising reopen rate means problems are being closed, not solved.

How: record status changes in an events table so you can see a resolved → in_progress transition. You can't compute this from the current status alone.

6. Reassignments

What: how many times a request changed team before resolution.

Why: each handoff restarts the queue wait and burns SLA time. A category with many reassignments has a routing or ownership problem, not a speed problem. See routing requests to the right team.

7. Deflection

What: requests that were never filed because the requester found an answer first — typically measured as knowledge-base article views during request creation followed by abandonment of the form.

Why: the fastest request is the one that didn't need a human.

Pitfall: it's inferred, not observed. Someone who abandons the form may have given up, not been helped. Treat it as a trend, and ask "did this answer your question?" to get a direct signal. More in ticket deflection with a self-service knowledge base.

The data you need before any of this works

Most of these metrics can't be computed from the current state of a request; they need its history. Set this up on day one, because you can't reconstruct it later:

  • Timestamps as columns on the request: created_at, first_response_at, resolved_at, sla_due_at. Stamp them with database triggers, not app code, so every path that changes a request records them the same way.
  • An events table with one row per change: (request_id, actor_id, type, payload, created_at), where type is things like status_changed, team_changed, assigned, commented. Reopen rate and reassignments come from here.
  • Indexes on the columns you group and filter by — created_at, resolved_at, category_id, team_id — or the monthly report gets slower every month.
  • Row-level security on both tables, so an agent's dashboard only aggregates what they're allowed to see. The same query then serves team leads and admins with different scopes; see row-level security vs app-layer authorization.

Reading metrics together

Single metrics mislead; pairs tell stories:

Pattern Likely meaning
Resolution time ↓, reopen rate ↑ Closing too early
First response ↓, resolution flat Faster acknowledgement, same bottleneck downstream
Volume ↑, backlog age ↑, resolution flat Capacity problem, not a process problem
One category with high reassignments and low attainment Routing or ownership problem for that category
Deflection ↑, volume ↓, attainment ↑ Knowledge base is working; keep writing articles

Metrics to avoid (or demote)

  • Tickets closed per agent. It rewards picking easy tickets and punishes the person who takes the hard one. Use it for capacity planning, never for performance reviews.
  • Average handle time on its own. Same gaming problem; always paired with quality.
  • Satisfaction scores with tiny response rates. Five responses a month is anecdote, not data.

A monthly report that fits on one screen

Category Volume First response p50 / p90 Resolution p50 / p90 SLA attainment Reopen rate

Plus two lines: the backlog-age buckets, and the three categories with the most reassignments. That report answers "are we keeping our promises?", "what's rotting?" and "where does work bounce?" — the questions that lead to decisions.

Little's Law is a useful sanity check when volume changes: average number of open requests equals arrival rate times average time in system. If requests arrive faster and resolution time stays flat, the backlog must grow — a clear case for more capacity rather than more effort.

FAQ

What is the most important help desk metric?

If you track only one, track SLA attainment per category: it combines speed with the targets you've promised. Pair it with first-response time, which is the part requesters feel first.

Should I use averages or medians for help desk metrics?

Medians (p50) for the typical experience and 90th percentiles for the bad cases. Averages are skewed by a few very long requests and hide how many people waited too long.

How often should help desk metrics be reviewed?

Monthly for trends and targets, weekly for backlog age. Daily views are for the queue itself — what's due soon — not for metrics.

Can I compute these without a BI tool?

Yes. Every metric here is a single SQL query over the requests table and its events. See an analytics dashboard with plain Postgres.

Sources

AA
Aayush Adhikari

Building Relay — the internal request desk with AI triage and SLA tracking.

Run your internal requests on LetRelay

AI triage, SLA-tracked queues, and bottleneck analytics — the help desk your team actually likes. Free to start.

Try LetRelay free No credit card required
Ad spaceYour Google AdSense unit shows here once approved.

Keep reading