Systems Library / Customer Service / How to Create Automated SLA Tracking and Alerts
Customer Service ticket management

How to Create Automated SLA Tracking and Alerts

Track SLA compliance automatically and alert before deadlines are missed.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

An automated sla tracking alert system for support prevents breaches before they happen. I build these for teams managing tickets with contractual response and resolution time commitments. Instead of checking manually, the system monitors every open ticket and alerts when SLA deadlines approach.

The alert fires at 75% of the SLA window. Not when it is too late.

What You Need Before Starting

Step 1: Define Your SLA Rules

SLA_RULES = {
    "critical": {"first_response_hours": 1, "resolution_hours": 4},
    "high": {"first_response_hours": 4, "resolution_hours": 24},
    "medium": {"first_response_hours": 12, "resolution_hours": 48},
    "low": {"first_response_hours": 24, "resolution_hours": 72},
}

CUSTOMER_OVERRIDES = {
    "enterprise": {"multiplier": 0.5},  # Half the normal SLA times
    "business": {"multiplier": 0.75},
}

Step 2: Build the SLA Calculator

from datetime import datetime, timedelta

def get_sla_deadline(ticket):
    priority = ticket["priority"]
    customer_tier = ticket.get("customer_tier", "standard")
    created_at = datetime.fromisoformat(ticket["created_at"])

    rules = SLA_RULES.get(priority, SLA_RULES["medium"])
    multiplier = CUSTOMER_OVERRIDES.get(customer_tier, {}).get("multiplier", 1.0)

    response_deadline = created_at + timedelta(hours=rules["first_response_hours"] * multiplier)
    resolution_deadline = created_at + timedelta(hours=rules["resolution_hours"] * multiplier)

    return {
        "first_response_by": response_deadline,
        "resolve_by": resolution_deadline,
    }

Step 3: Monitor Open Tickets

Run a check every 5 minutes against all open tickets:

import sqlite3

def check_sla_compliance():
    conn = sqlite3.connect("tickets.db")
    open_tickets = conn.execute(
        "SELECT * FROM tickets WHERE status IN ('open', 'pending', 'in_progress')"
    ).fetchall()

    now = datetime.now()
    alerts = []

    for ticket in open_tickets:
        deadlines = get_sla_deadline(ticket)

        if not ticket["first_response_at"]:
            time_left = (deadlines["first_response_by"] - now).total_seconds() / 3600
            if time_left < 0:
                alerts.append({"ticket": ticket["id"], "type": "response_breached", "overdue_hours": abs(time_left)})
            elif time_left < deadlines_threshold(deadlines["first_response_by"], ticket["created_at"]):
                alerts.append({"ticket": ticket["id"], "type": "response_warning", "hours_left": time_left})

        time_to_resolve = (deadlines["resolve_by"] - now).total_seconds() / 3600
        if time_to_resolve < 0:
            alerts.append({"ticket": ticket["id"], "type": "resolution_breached"})
        elif time_to_resolve < deadlines_threshold(deadlines["resolve_by"], ticket["created_at"]):
            alerts.append({"ticket": ticket["id"], "type": "resolution_warning", "hours_left": time_to_resolve})

    return alerts

Step 4: Send Alerts to the Right People

import requests

def send_sla_alert(alert):
    ticket = get_ticket(alert["ticket"])
    assignee = ticket.get("assignee", "unassigned")

    if "breached" in alert["type"]:
        channel = "#sla-breaches"
        emoji = "🚨"
        message = f"{emoji} SLA BREACHED: Ticket #{alert['ticket']} ({alert['type']}). Assigned to: {assignee}"
    else:
        channel = "#sla-warnings"
        emoji = "⚠️"
        message = f"{emoji} SLA Warning: Ticket #{alert['ticket']} has {alert.get('hours_left', 0):.1f} hours left. Assigned to: {assignee}"

    requests.post(os.getenv("SLACK_WEBHOOK"), json={
        "channel": channel,
        "text": message
    })

Step 5: Build the Compliance Dashboard

Track SLA performance over time:

def get_sla_report(days=7):
    conn = sqlite3.connect("tickets.db")
    start = (datetime.now() - timedelta(days=days)).isoformat()

    total = conn.execute("SELECT COUNT(*) FROM tickets WHERE created_at > ?", (start,)).fetchone()[0]
    breached = conn.execute(
        "SELECT COUNT(*) FROM sla_events WHERE type LIKE '%breached%' AND created_at > ?", (start,)
    ).fetchone()[0]

    return {
        "period_days": days,
        "total_tickets": total,
        "sla_breaches": breached,
        "compliance_rate": round((total - breached) / total * 100, 1) if total else 100
    }

What to Build Next

Add SLA pause rules. When a ticket is waiting on the customer (status: "pending"), pause the SLA clock. Resume it when they respond. This prevents false breaches from slow customer replies.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems