·11 min·48 views

5 Call Center KPIs That Actually Drive Revenue (The Rest Is Noise)

Most call centers track 50+ metrics and act on none. Here are the 5 KPIs that predict churn, reveal agent problems, and directly impact your bottom line — with Asterisk configs to measure each one.

A
Astervis
Engineering & product team
5 Call Center KPIs That Actually Drive Revenue (The Rest Is Noise)

Every call center dashboard I've seen has the same problem: too many numbers, not enough insight.

Managers proudly show me screens with 40+ metrics, color-coded charts, blinking alerts. Then I ask: "Which three numbers did you act on last week?" Silence.

Here's my take: 5 KPIs drive 80% of your call center's performance. Everything else is decoration. Track these five obsessively, act on them daily, and you'll outperform call centers with ten times your budget.

I've seen this pattern across dozens of Asterisk-based call centers. The ones that focus on fewer metrics consistently outperform the ones drowning in data. If you want to understand why having 200 metrics is actually a problem, I wrote about that separately.

Let's get into the five that matter.

1. Service Level — The Only Metric Your Boss Cares About

Formula: (Calls answered within X seconds ÷ Total incoming calls) × 100%

The industry standard is 80/20 — 80% of calls answered within 20 seconds. For premium support: 90/15.

My take: The 80/20 standard was invented in the 1980s for landline switchboards. In 2026, caller expectations are higher. If you're running an e-commerce support line, you should target 85/20. If you're running B2B technical support where callers expect to wait a bit, 70/30 is fine.

The point isn't hitting a universal number. It's picking YOUR number and never dropping below it.

How to Measure Service Level in Asterisk

Asterisk tracks this natively through queue_log. Your queues.conf needs the servicelevel parameter:

; queues.conf [support] servicelevel = 20 ; 20-second SLA threshold strategy = rrmemory timeout = 15 retry = 1

With this set, Asterisk records whether each call was answered within your SLA window. You can query it from queue_log:

-- Service Level from queue_log SELECT DATE(time) AS day, COUNT(*) AS total_calls, COUNT(CASE WHEN event = 'CONNECT' AND data1::int <= 20 THEN 1 END) AS within_sla, ROUND(100.0 * COUNT(CASE WHEN event = 'CONNECT' AND data1::int <= 20 THEN 1 END) / NULLIF(COUNT(*), 0), 1) AS service_level_pct FROM queue_log WHERE event IN ('CONNECT', 'ABANDON') AND time >= NOW() - INTERVAL '7 days' GROUP BY DATE(time) ORDER BY day;

Red flag: Service Level below 70% for more than 2 consecutive hours. That's not a blip — that's a staffing problem. Your supervisor dashboard should flash red when this happens.

Real-World Benchmarks by Industry

IndustryTarget SLWhy
E-commerce85% in 20sCallers will buy from competitors
Telecom80% in 20sRegulated, contractual SLAs
Banking80% in 30sComplex calls, callers expect slight wait
Tech support70% in 30sCallers know their issue needs time
BPO / OutsourcedPer client SLADifferent rules apply

2. First Call Resolution — The Silent Revenue Driver

Formula: (Calls without repeat contact within 7 days ÷ Total calls) × 100%

FCR is the KPI most call centers underestimate. Every 1% increase in FCR reduces operational costs by 1-2%. That's not theory — it's documented across thousands of contact centers.

My take: FCR is the single best predictor of customer loyalty. Not CSAT, not NPS — FCR. A customer whose problem gets solved on the first call forgives almost everything else: long wait, grumpy agent, hold music from 2003.

I've written about this in depth: why chasing a 70% FCR target can actually hurt you. The short version: high FCR with low quality is worse than moderate FCR with proper resolution.

Measuring FCR with Asterisk CDR

Asterisk doesn't track FCR natively — you need to correlate CDR records by caller ID:

-- First Call Resolution from CDR WITH calls AS ( SELECT src AS caller, calldate, LEAD(calldate) OVER (PARTITION BY src ORDER BY calldate) AS next_call FROM cdr WHERE disposition = 'ANSWERED' AND dcontext LIKE 'queue-%' AND calldate >= NOW() - INTERVAL '30 days' ) SELECT COUNT(*) AS total_calls, COUNT(CASE WHEN next_call IS NULL OR next_call - calldate > INTERVAL '7 days' THEN 1 END) AS resolved_first_call, ROUND(100.0 * COUNT(CASE WHEN next_call IS NULL OR next_call - calldate > INTERVAL '7 days' THEN 1 END) / NULLIF(COUNT(*), 0), 1) AS fcr_pct FROM calls;

Warning: This query counts "no callback within 7 days" as resolved. It's an approximation. The caller might have emailed instead, or given up entirely. For accurate FCR, you need post-call surveys or CRM integration — which is why CRM connectors matter for analytics.

Typical FCR Benchmarks

Call TypeGood FCRGreat FCR
Simple inquiries85%92%+
Standard support70%80%+
Technical support60%72%+
Complex B2B50%65%+

3. Average Handle Time — The Most Dangerous Metric

Formula: (Talk time + Hold time + After-call work) ÷ Number of calls

My take: AHT is the metric most likely to destroy your call center if used wrong. I've seen managers pressure agents to keep calls under 4 minutes, and the result is always the same: calls get shorter, callbacks double, and customer satisfaction tanks.

AHT lies to you in at least 3 ways. The average masks the distribution. A team with 3-minute sales calls and 20-minute escalations shows a "healthy" 6-minute AHT that tells you nothing.

Configuring Wrap-Up Time in Asterisk

The wrapuptime parameter in queues.conf directly impacts AHT:

; queues.conf [sales] wrapuptime = 10 ; 10 seconds for simple disposition strategy = rrmemory [support] wrapuptime = 30 ; 30 seconds — agents need to write notes strategy = fewestcalls [escalation] wrapuptime = 60 ; Full minute for complex documentation strategy = leastrecent

Here's the mistake everyone makes: setting wrapuptime = 0 to "maximize efficiency." What actually happens is agents get slammed with the next call before they finish their notes, so they put the next caller on hold to finish — moving wrap-up time into hold time. Net effect: zero improvement, worse experience.

AHT Benchmarks

Queue TypeTarget AHTRed Flag
Informational2-4 min>6 min
Sales inbound4-6 min>8 min
Standard support5-8 min>12 min
Technical support8-12 min>18 min

What to do when AHT spikes: Don't react by pressuring agents. Dig into the data. Is it one agent? One queue? A specific time of day? Usually it's a system issue (slow CRM, broken knowledge base) or a spike in complex calls. Check your call center monitoring dashboard for patterns before blaming people.

Tired of guessing what's happening in your queues?

Astervis gives you 30+ real-time charts, operator KPIs, and CRM integration for your Asterisk PBX. Self-hosted. Install in 5 minutes. From $119/mo flat unlimited operators.

Try Free

4. Abandon Rate — Every Lost Call Has a Dollar Value

Formula: (Abandoned calls ÷ Total incoming calls) × 100%

Industry says under 5% is excellent, 5-8% is normal, above 10% is a problem.

My take: The 5% benchmark is a lie. It ignores context entirely. A 3% abandon rate where all abandons happen in the first 10 seconds (misdialed, changed their mind) is completely different from a 3% abandon rate where callers wait 4 minutes and give up.

You need to track abandon rate BY wait time bucket, not as a single number.

Asterisk Queue Configuration for Abandon Tracking

; queues.conf [support] joinempty = paused,unavailable ; Let callers join even if agents paused leavewhenempty = no ; Don't auto-kick — let them choose to wait announce-holdtime = once ; Tell wait time, but only once announce-position = yes announce-frequency = 45 ; Don't spam announcements

Two settings kill your abandon rate more than anything:

  1. announce-frequency too low (like 15s) — callers hear constant interruptions and hang up
  2. joinempty = strict — callers get rejected instead of queued when agents are paused
-- Abandon rate by wait time bucket from queue_log SELECT CASE WHEN data3::int < 15 THEN '0-15s (short abandon)' WHEN data3::int < 30 THEN '15-30s' WHEN data3::int < 60 THEN '30-60s' WHEN data3::int < 120 THEN '1-2 min' ELSE '2+ min (critical)' END AS wait_bucket, COUNT(*) AS abandons, ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS pct_of_abandons FROM queue_log WHERE event = 'ABANDON' AND time >= NOW() - INTERVAL '7 days' GROUP BY 1 ORDER BY MIN(data3::int);

The real cost: If your average order value is $200 and you lose 20 calls per day to abandonment, that's potentially $4,000/day in lost revenue. Even if only 25% would have converted, that's $1,000/day — $365K/year. I did the detailed cost math here.

The Fix: Queue Callbacks

The single best weapon against abandonment is offering callbacks. For implementation details, see our queue callback monitoring guide.

5. Agent Occupancy — The Metric Nobody Watches Until It's Too Late

Formula: (Time on calls + After-call work) ÷ (Total logged-in time) × 100%

Most KPI articles put CSAT as #5. I don't. Here's why.

My take: CSAT is a lagging indicator — by the time it drops, the damage is done. Agent Occupancy is a leading indicator. When occupancy exceeds 85%, three things happen within 2-4 weeks:

  1. Agent turnover spikes (they're exhausted)
  2. AHT creeps up (tired agents work slower)
  3. FCR drops (rushed agents cut corners)

I've written about how bad monitoring practices cause agent burnout. The bottom line: occupancy above 85% sustained for more than a week is a ticking time bomb.

Tracking Occupancy from Asterisk Data

Occupancy requires correlating agent login time with call time:

-- Agent occupancy from queue_log WITH agent_calls AS ( SELECT agent, SUM(data2::int) AS talk_seconds, SUM(data3::int) AS hold_seconds FROM queue_log WHERE event IN ('COMPLETEAGENT', 'COMPLETECALLER') AND time >= NOW() - INTERVAL '7 days' GROUP BY agent ), agent_login AS ( SELECT agent, SUM(EXTRACT(EPOCH FROM ( LEAD(time) OVER (PARTITION BY agent ORDER BY time) - time ))) AS login_seconds FROM queue_log WHERE event IN ('ADDMEMBER', 'REMOVEMEMBER', 'PAUSE', 'UNPAUSE') AND time >= NOW() - INTERVAL '7 days' GROUP BY agent ) SELECT c.agent, ROUND(c.talk_seconds / 3600.0, 1) AS talk_hours, ROUND(100.0 * (c.talk_seconds + c.hold_seconds) / NULLIF(l.login_seconds, 0), 1) AS occupancy_pct FROM agent_calls c JOIN agent_login l ON c.agent = l.agent ORDER BY occupancy_pct DESC;

Occupancy Sweet Spots

OccupancyStatusAction
Below 60%OverstaffedReduce agents or add queues
60-75%HealthyOptimal zone
75-85%BusyMonitor for burnout signs
Above 85%DangerAdd agents immediately
Above 90%CrisisExpect turnover within weeks

How These 5 KPIs Connect

Metrics don't exist in isolation. Here's how to read the patterns:

PatternWhat It MeansFix
SL drops + Abandons riseNot enough agentsHire, or activate overflow
AHT rises + FCR dropsAgents can't solve problemsTraining or tool issues
AHT drops + Occupancy risesAgents rushingIncrease wrapuptime
FCR high + Occupancy highEfficient but burning outAdd headcount
Abandons spike suddenlySystem issueCheck trunks, check call drops

Your 5-Minute Audit

Check your call center right now:

  • Service Level above 75%?
  • First Call Resolution above 65%?
  • Abandon Rate below 8%?
  • AHT within industry benchmark for your call type?
  • Agent Occupancy between 60-85%?

If 3+ boxes are unchecked, you have a structural problem — not a metric problem.

Stop Guessing, Start Measuring

You can run these SQL queries manually against queue_log and CDR. Build your own Grafana dashboards. Spend 40+ hours setting up alerting.

Or install Astervis in 5 minutes and see all five KPIs on a real-time wallboard — with alerts that fire before problems become crises.

30+ charts. Agent leaderboards. CRM integration. Self-hosted. You can build it yourself, or you can start your free 14-day trial and be tracking KPIs by lunch.


Related guides:

Stop guessing. Start monitoring.

See your Asterisk call center's real performance — queue wait times, agent activity, trunk usage, and 30+ charts. Self-hosted on your server. Install in 5 minutes. No credit card required.

From $119/mo flat. Unlimited operators. 14-day free trial.

Share this article