ds@mcpanalytics.aiEmail your data and your question and get an answer about your own data, with the method shown.Email your data and question. Get an answer.

SLA and Ticket Resolution Analysis: Find Where Your Support Pipeline Breaks

By MCP Analytics Team | Published , updated

Your support team resolves hundreds of tickets a month, but are they meeting SLA targets? Which priority levels have the highest breach rates? Which ticket types take the longest to resolve? Which channels perform best? This module takes your ticket data and produces a complete SLA compliance report (breach rates by priority, resolution time distributions, channel comparisons, bottleneck rankings, and statistical tests) all from a single CSV export of your help desk system.

Worked Example: Did the Breach Rate Differ by Priority?

Question: In a set of sample tickets, did the share of tickets that missed their time limit differ across the four priorities?

Inputs: Simulated data, seed 23. The script draws 20 resolution times for each of four priorities (80 tickets). The limits are 4 hours for Critical, 8 for High, 24 for Medium and 48 for Low. These are not real tickets.

Method: Compare each ticket time with its own priority's limit and count the misses. The 90th percentile is the time below which 90% of the tickets fall. Then compare the breach rates with a chi-square test. Its null claim is that the share of missed tickets is the same in every priority. The p-value is the chance of seeing a spread in breach rates at least this large if that claim and the test's rules hold. The test also assumes the tickets are independent of each other.

What the script builds in: Times are lognormal with typical (median) values of 3, 7, 20 and 38 hours, set against limits of 4, 8, 24 and 48. That gives each priority a built-in chance of missing its limit of about 30%, 40%, 37% and 34% (the script prints them), so the four chances are close to each other by design. Times differ across priorities because the typical times and the limits were set to differ. That is why a test on the hours alone would answer the wrong question for an SLA: each priority has its own limit, so the breach rate is the fair comparison.

Result: Overall, 28.7% (23 of 80) missed their limit. By priority the rates were 30%, 25%, 30% and 30%. The median time was 9.59 hours and the 90th percentile was 36.48 hours. The chi-square test gave p = 0.980, so this run shows no sign of a difference in breach rates. With only 20 tickets per priority the test has little power, so a missed gap would not be proof that no gap exists.

Limit: These sample times show how the steps work. They do not show how a real team performs.

import math
import numpy as np
from scipy.stats import chi2_contingency, norm

SEED = 23
rng = np.random.default_rng(SEED)
priorities = ["Critical", "High", "Medium", "Low"]
limits = {"Critical": 4, "High": 8, "Medium": 24, "Low": 48}
scales = {"Critical": 3, "High": 7, "Medium": 20, "Low": 38}
hours = {
    name: rng.lognormal(mean=np.log(scales[name]), sigma=0.55, size=20)
    for name in priorities
}
all_hours = np.concatenate([hours[name] for name in priorities])
all_breaches = np.concatenate(
    [hours[name] > limits[name] for name in priorities]
)

print(f"Simulated data, seed {SEED}")
print("Tickets: 80 total, 20 per priority")
print("SLA limits (hours): Critical 4, High 8, Medium 24, Low 48")
print(
    f"Overall breach rate: {all_breaches.mean():.1%} "
    f"({all_breaches.sum()}/{len(all_breaches)})"
)
print(f"Median resolution time: {np.median(all_hours):.2f} hours")
print(
    f"90th percentile resolution time: "
    f"{np.percentile(all_hours, 90):.2f} hours"
)
for name in priorities:
    group = hours[name]
    breaches = int(np.sum(group > limits[name]))
    print(
        f"{name}: {breaches}/20 breaches ({breaches/20:.1%}); "
        f"median {np.median(group):.2f} hours"
    )

print("Built-in chance of missing the limit (lognormal, sigma 0.55):")
for name in priorities:
    chance = 1 - norm.cdf(math.log(limits[name] / scales[name]) / 0.55)
    print(
        f"  {name}: typical time {scales[name]} h against a "
        f"{limits[name]} h limit: {chance:.1%}"
    )
table = [
    [int(np.sum(hours[n] > limits[n])), int(np.sum(hours[n] <= limits[n]))]
    for n in priorities
]
chi2, p, dof, _ = chi2_contingency(table)
print(
    f"Breach rate across priorities: chi-square={chi2:.3f}, "
    f"df={dof}, p={p:.3f}"
)

Printed output of that script:

Simulated data, seed 23
Tickets: 80 total, 20 per priority
SLA limits (hours): Critical 4, High 8, Medium 24, Low 48
Overall breach rate: 28.7% (23/80)
Median resolution time: 9.59 hours
90th percentile resolution time: 36.48 hours
Critical: 6/20 breaches (30.0%); median 3.14 hours
High: 5/20 breaches (25.0%); median 5.86 hours
Medium: 6/20 breaches (30.0%); median 21.11 hours
Low: 6/20 breaches (30.0%); median 33.15 hours
Built-in chance of missing the limit (lognormal, sigma 0.55):
  Critical: typical time 3 h against a 4 h limit: 30.0%
  High: typical time 7 h against a 8 h limit: 40.4%
  Medium: typical time 20 h against a 24 h limit: 37.0%
  Low: typical time 38 h against a 48 h limit: 33.6%
Breach rate across priorities: chi-square=0.183, df=3, p=0.980

What Is SLA Analysis?

SLA analysis measures how well your support team meets its Service Level Agreements: the commitments you make about how quickly tickets will be resolved based on their priority. The sample limits above are 4 hours for Critical, 8 for High, 24 for Medium and 48 for Low. Set them to fit your own SLA terms. SLA analysis answers the question: are you actually meeting those targets, and where are you falling short?

The core metric is the breach rate: the percentage of tickets that exceeded their SLA target resolution time. A breach rate of 15% means one in seven tickets missed the target. But the overall breach rate is just the starting point. The real value comes from breaking it down: is the 15% concentrated in Critical tickets (a serious operational issue) or Low-priority tickets (a staffing allocation question)? Is it concentrated in one ticket type (a process issue) or one channel (a tooling issue)?

Beyond breach rates, the analysis examines the full distribution of resolution times. Averages can be misleading, if half your tickets resolve in 1 hour and the other half in 47 hours, the average of 24 hours looks fine but masks a bimodal problem. The resolution time distribution reveals these patterns. The P90 (90th percentile) is especially valuable: it tells you the time within which 90% of tickets are resolved, giving a realistic worst-case expectation that is more robust than the mean.

The worked example above shows the idea on sample tickets: a single overall rate is a starting point, and the breakdown by priority is where the useful questions begin.

When to Use SLA Analysis

Run this analysis whenever you want to evaluate support team performance, justify staffing changes, or identify process improvements. The most impactful use cases are:

Monthly or quarterly SLA reviews: Export your help desk data, upload it, and get a comprehensive compliance report. Use it for team retrospectives, executive reporting, or customer-facing SLA compliance documentation. The report's charts and statistics are ready to present without additional formatting.

Identifying bottlenecks: The bottleneck ranking slide scores each category (ticket type, priority level, channel) by impact: the combination of breach rate and volume. A category with a 50% breach rate but only 10 tickets is less urgent than one with a 20% breach rate and 500 tickets. The impact score helps you prioritize where process improvements will move the needle most.

Channel optimization: If you offer support through multiple channels (email, chat, phone, self-service portal), the channel comparison analysis shows which channels resolve tickets fastest, which have the highest breach rates, and whether the differences are statistically significant. This drives decisions about channel investment and routing strategies.

Staffing justification: When requesting additional headcount, data beats anecdotes. A rising breach rate for Critical tickets, traced to a ticket type that grew in volume, makes a stronger case than a general impression. The statistical tests in the report show whether the differences are larger than chance alone would often produce.

Customer satisfaction correlation: If your help desk data includes satisfaction ratings, the module compares resolution time with customer satisfaction. That can help tie SLA targets to business outcomes rather than arbitrary benchmarks.

What Data Do You Need?

You need a CSV with one row per resolved ticket.

Required: a unique ID for each ticket, the priority level (Critical, High, Medium, Low, or your own scheme), the date and time the ticket was resolved, and the date and time it was created or first responded to. The resolution time is the difference between the two timestamps.

Optional (for richer analysis): the ticket type (Bug, Feature Request, Billing Question, etc.), which allows a breach rate breakdown by type; the ticket status (Resolved, Closed, Open), used for filtering; the support channel (Email, Chat, Phone, Portal), which allows a channel comparison; the product or service area; and a customer satisfaction score, which allows a comparison of satisfaction with resolution time.

Set the time limits to match your own SLA targets.

The module works with exports from any help desk platform: Zendesk, Freshdesk, Jira Service Management, ServiceNow, Intercom, Help Scout, or any system that can export to CSV.

How to Read the Report

The report is structured as a progressive drill-down from high-level KPIs to specific bottlenecks.

The Overview and Data Pipeline slides show total tickets analyzed, date range, and preprocessing steps. The Executive Summary follows immediately, distilling the key findings into actionable headlines.

The SLA Performance KPIs table shows overall metrics: total tickets, overall breach rate, median resolution time, P90 resolution time, and per-priority metrics. This is your dashboard view, if the overall breach rate is below your target, you may not need to dig deeper. If it is above target, the subsequent slides tell you where to focus.

The Resolution Time Distribution bar chart buckets tickets by resolution time (0-1 hours, 1-4 hours, 4-8 hours, etc.) with percentage labels. This reveals whether your resolution times cluster tightly around a norm (good) or spread widely (inconsistent process). A long tail to the right means some tickets take dramatically longer than others: investigate those outliers.

The Performance by Priority chart shows breach rate and average resolution time side by side for each priority level. In a well-functioning support operation, Critical tickets should have the lowest resolution time and the lowest breach rate. If Critical tickets have a higher breach rate than Medium tickets, something is wrong: either the SLA targets are unrealistic, the escalation process is broken, or critical tickets are being misclassified.

The Breach Rate by Ticket Type chart ranks ticket types by breach rate. Types with both high breach rates and high ticket counts are the top improvement opportunities. The Channel Performance chart (if channel data is provided) does the same comparison across support channels.

The Satisfaction vs Resolution Time chart (if satisfaction data is provided) plots average satisfaction against resolution time buckets. In your data, test whether faster fixes link to higher satisfaction. The pattern may vary by team and ticket type. A sharp change in satisfaction across time groups may need a closer look. The chart can show where group averages change. It cannot set a time all customers will accept.

The Statistical Tests table reports whether the performance differences across priorities, types, or channels are larger than chance alone would often produce. A p-value is the chance of seeing results this far from the null claim, if that claim and the test's rules hold. For the Kruskal-Wallis test used on resolution times, the null claim is that the groups have the same distribution of times. Report the effect size too: a p-value alone does not show how large or useful a gap is.

The Top Bottlenecks by Impact chart is the action-oriented capstone. It scores each category by combining breach rate with ticket volume into a single impact score. The highest-impact bottlenecks are your top priorities for process improvement, training, or tooling investment.

When to Use Something Else

If you want to predict which tickets will breach their SLA before they do (rather than analyzing after the fact), you need a predictive model like XGBoost or logistic classification trained on ticket features and historical breach outcomes.

If your primary interest is forecasting future ticket volume (how many tickets will we receive next month?), use the time series forecasting module with daily ticket counts as the value column.

If you want to compare just two channels or two time periods (before/after a process change) rather than a full SLA analysis, a t-test on resolution times gives a focused answer.

If your ticket data has many categorical dimensions and you want to understand which factors most influence resolution time, a Random Forest feature importance analysis can rank predictors by their contribution to resolution time variance.

The R Code Behind the Analysis

Every report names its method and includes the R code that produced it, so you can reproduce, audit and cite it. The method code is fixed, not rewritten for each run, so the same data gives the same analysis every time.

The analysis uses difftime() for resolution time calculations, cut() for time bucket binning, and aggregate() for group-level statistics. Breach rates are computed by comparing resolution times against configurable SLA thresholds. Statistical tests use kruskal.test() for comparing resolution times across groups (a rank-based test that suits skewed times). Impact scores combine breach rate and volume using weighted ranking. Satisfaction correlation uses cor() and grouped aggregation. All visualizations use Plotly for interactive charts. Every step is visible in the code tab of your report, so you or an analyst can verify exactly what was done.

Your turn

Bring your own data and the question you actually need answered.

MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai