DEV Community

Jason Shouldice
Jason Shouldice

Posted on • Originally published at vicistack.com

The $1,200/Hour Problem: How Untracked Pause Time Kills Call Center Productivity

Here's the math nobody wants to do: an agent who's paused costs you roughly $4/minute in lost dialing capacity. Five agents milking their breaks on a 50-seat floor burns $1,200/hour. And if pause codes aren't set to FORCE, you have no idea who's doing it or how long they've been gone.

This is the operational leak that VICIdial gives you every tool to fix — but most admins never configure properly.

The One Setting That Makes Everything Else Work

In your campaign settings, find Agent Pause Codes Active and set it to FORCE. Not Y, not NFORCE.

When set to Y, agents can pause without selecting a reason. When set to FORCE, they must pick a code from the dropdown before the pause takes effect. Without this, your agent_log data is full of blank pause codes and your reporting is useless.

To check your current state across all campaigns:

SELECT campaign_id, agent_pause_codes_active
FROM vicidial_campaigns
WHERE active = 'Y';
Enter fullscreen mode Exit fullscreen mode

If any campaign shows Y or N, fix it through Admin > Campaigns > Detail. Do it through the GUI so the change gets logged in vicidial_admin_log.

Designing Codes That Actually Tell You Something

Most default VICIdial installations come with BREAK, LUNCH, and BATHROOM. That's not enough to answer the question you actually care about: "Is this agent doing something acceptable right now?"

Here's the code set I recommend for 25+ agent teams:

Acceptable productive pauses:

Code Name Max Duration Notes
TRAIN Training/Meeting 60 min Scheduled events only
COACH 1-on-1 Coaching 30 min Supervisor-initiated
TECH Technical Issue 15 min Workstation/headset/software
SYSDN System Down Unlimited Mass event, supervisor confirms

Acceptable personal pauses:

Code Name Max Duration Notes
BRK Break 15 min Scheduled breaks per shift
LUNCH Lunch Break 30 min One per shift
BATH Bathroom 10 min No pre-approval needed
PERS Personal 5 min Quick personal matter

Tracked admin pauses:

Code Name Max Duration Notes
ADMIN Admin Task 20 min Data entry, paperwork
ESCAL Escalation Work 30 min Working escalated issue
QA QA Review 15 min Listening to own calls

Create these through Admin > Pause Codes and set the campaign to --ALL-- if you want them system-wide. Mark productive/admin codes as billable and personal codes as non-billable.

The key design question for every code is: "What is this agent doing right now, and is it acceptable?" If you can't answer that from the pause code alone, the code isn't specific enough.

The DISPO Loophole

This is the one agents figure out fast: DISPO time doesn't get flagged the same way as explicit pauses. When an agent finishes a call and enters the disposition screen, VICIdial records pause time with code DISPO until they select a disposition and go back to READY. An agent who camps in the dispo screen for 4 minutes between every call is effectively on break without triggering any pause alerts.

Average dispo time for most outbound campaigns should be 5-15 seconds. An agent averaging 45+ seconds is either struggling with the interface or deliberately stalling. Compare individual agents against the campaign median to spot outliers:

SELECT user,
    ROUND(AVG(dispo_sec), 1) AS avg_dispo_seconds,
    ROUND(MAX(dispo_sec), 1) AS max_dispo_seconds,
    COUNT(*) AS total_dispos,
    ROUND(SUM(dispo_sec) / 60, 1) AS total_dispo_minutes
FROM vicidial_agent_log
WHERE event_time >= CURDATE()
  AND campaign_id = 'SALESCAMP'
  AND dispo_sec > 0
GROUP BY user
ORDER BY avg_dispo_seconds DESC;
Enter fullscreen mode Exit fullscreen mode

Fix this two ways:

  1. Set Dispo Max in campaign settings (through Admin > Campaigns > Detail) to 60 seconds. After 60 seconds, VICIdial auto-moves the agent back to READY or PAUSED.
  2. Flag outliers — anyone over 2x the campaign median needs a conversation.

Pause Code Reporting That Finds Problems

Daily Pause Summary by Agent

Pull each agent's total time in each pause code for the current day:

SELECT val.user, vu.full_name AS agent_name,
    val.sub_status AS pause_code,
    COUNT(*) AS pause_instances,
    SUM(val.pause_sec) AS total_pause_seconds,
    ROUND(SUM(val.pause_sec) / 60, 1) AS total_pause_minutes,
    MAX(val.pause_sec) AS longest_pause_seconds
FROM vicidial_agent_log val
JOIN vicidial_users vu ON val.user = vu.user
WHERE val.event_time >= CURDATE()
  AND val.pause_sec > 0
  AND val.sub_status != ''
GROUP BY val.user, val.sub_status
ORDER BY val.user, total_pause_seconds DESC;
Enter fullscreen mode Exit fullscreen mode

Excessive Pause Detection

Find anyone who exceeded thresholds on non-exempt codes:

SELECT val.user, vu.full_name AS agent_name,
    val.sub_status AS pause_code, val.pause_sec,
    ROUND(val.pause_sec / 60, 1) AS pause_minutes,
    val.event_time
FROM vicidial_agent_log val
JOIN vicidial_users vu ON val.user = vu.user
WHERE val.event_time >= CURDATE()
  AND val.pause_sec > 1200
  AND val.sub_status NOT IN ('LUNCH', 'TRAIN', 'SYSDN')
ORDER BY val.pause_sec DESC;
Enter fullscreen mode Exit fullscreen mode

Campaign-Level Health Check

Healthy outbound campaigns typically show 55-70% talk time, 10-20% pause time, 5-15% wait time, and 5-10% dispo time. If pause percentage exceeds 25%, you have an accountability problem across the team, not just a few bad apples.

SELECT val.campaign_id,
    ROUND(SUM(val.talk_sec) / 3600, 1) AS total_talk_hours,
    ROUND(SUM(val.pause_sec) / 3600, 1) AS total_pause_hours,
    ROUND(SUM(val.talk_sec) * 100.0 /
        NULLIF(SUM(val.talk_sec) + SUM(val.pause_sec) + SUM(val.wait_sec) + SUM(val.dispo_sec), 0),
        1) AS talk_pct,
    ROUND(SUM(val.pause_sec) * 100.0 /
        NULLIF(SUM(val.talk_sec) + SUM(val.pause_sec) + SUM(val.wait_sec) + SUM(val.dispo_sec), 0),
        1) AS pause_pct
FROM vicidial_agent_log val
WHERE val.event_time >= CURDATE()
GROUP BY val.campaign_id;
Enter fullscreen mode Exit fullscreen mode

Real-Time Alerts That Actually Work

End-of-day reports are too late. By the time you see that Agent X was paused for 47 minutes yesterday, you've already lost the money. You need alerts that fire while agents are still paused.

Simple Cron-Based Alert Script

A cron job running every 2 minutes can query vicidial_live_agents for anyone paused beyond threshold and push it to Slack:

#!/bin/bash
# /opt/scripts/pause_alert.sh — run every 2 minutes via cron
# */2 * * * * /opt/scripts/pause_alert.sh

ALERT_THRESHOLD=900  # 15 minutes in seconds
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"

RESULTS=$(mysql -u cron -p'yourpass' asterisk -N -B -e "
SELECT va.user, vu.full_name, va.pause_code,
    UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(va.last_state_change) AS seconds_paused,
    va.campaign_id
FROM vicidial_live_agents va
JOIN vicidial_users vu ON va.user = vu.user
WHERE va.status = 'PAUSED'
  AND UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(va.last_state_change) > ${ALERT_THRESHOLD}
  AND va.pause_code NOT IN ('LUNCH', 'TRAIN', 'SYSDN', 'COACH')
ORDER BY seconds_paused DESC;
")

if [ -n "$RESULTS" ]; then
    MESSAGE="*Pause Alert* — Agents over $(($ALERT_THRESHOLD / 60)) minutes:\n"
    while IFS=$'\t' read -r user name code seconds campaign; do
        MINUTES=$((seconds / 60))
        MESSAGE="${MESSAGE}\n- *${name}* (${user}): ${code:-NO CODE}${MINUTES} min [${campaign}]"
    done <<< "$RESULTS"

    curl -s -X POST "$WEBHOOK_URL" \
        -H 'Content-type: application/json' \
        -d "{\"text\": \"${MESSAGE}\"}"
fi
Enter fullscreen mode Exit fullscreen mode

Tiered Severity

Different pause durations trigger different responses:

Duration Severity Action
10 min (personal code) Info Slack message to supervisor
20 min (any non-exempt code) Warning Slack + direct message to agent
30+ min Critical Slack + supervisor phone alert

The Wallboard Trick

Nothing motivates an agent to unpause faster than seeing their name at the top of a wallboard with a running timer:

SELECT vu.full_name, va.pause_code AS code,
    ROUND((UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(va.last_state_change)) / 60, 1) AS minutes_paused
FROM vicidial_live_agents va
JOIN vicidial_users vu ON va.user = vu.user
WHERE va.status = 'PAUSED'
ORDER BY (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(va.last_state_change)) DESC
LIMIT 5;
Enter fullscreen mode Exit fullscreen mode

Display this with color coding: green under 5 minutes, yellow 5-15, red over 15. Social pressure works. Agents who know their break time is visible to the floor tend to keep it reasonable.

The Efficiency Score

The single most useful metric for agent accountability is efficiency percentage: talk time as a fraction of total logged time.

Efficiency % Rating Action
65%+ Excellent Recognize and reward
55-64% Good Standard performance
45-54% Below Average Coaching conversation
Below 45% Poor Immediate intervention

The availability_score (100 minus pause percentage) is a quick number to display on wallboards. Agents see their own score and know immediately where they stand.

Track frequency too, not just duration. Twenty 3-minute breaks is as damaging as one 60-minute break:

SELECT user, COUNT(*) AS pause_count,
    ROUND(SUM(pause_sec) / 60, 1) AS total_minutes,
    ROUND(AVG(pause_sec), 0) AS avg_seconds_per_pause
FROM vicidial_agent_log
WHERE event_time >= CURDATE()
  AND pause_sec > 0
  AND sub_status NOT IN ('', 'LOGIN', 'DISPO', 'LAGGED', 'DEAD')
GROUP BY user
ORDER BY pause_count DESC;
Enter fullscreen mode Exit fullscreen mode

Track weekly trends too. An agent whose efficiency drops 5+ points day-over-day is either dealing with a personal issue, a system issue, or a motivation issue. The data tells you something changed — the supervisor's job is to find out what.

Using Pause Data in Coaching

When pause data backs up a coaching conversation, it stops being opinion. "Your efficiency was 42% last week compared to the team average of 61%. You had 14 break pauses averaging 12 minutes each." That's specific, measurable, and defensible.

Use it positively too. Agents who consistently maintain 60%+ efficiency with correct pause code usage should be recognized. Post the top 5 efficiency scores weekly. Tie bonuses to efficiency alongside conversion metrics.

Review your pause code set quarterly. If agents are consistently using ADMIN for tasks that should have their own code (like CRM updates), create a specific code for it. If a code is never used, remove it to simplify the agent interface.

For the full implementation guide including scorecard queries, multi-shift analysis, and policy templates, see ViciStack's pause code accountability guide.


Originally published at https://vicistack.com/blog/vicidial-pause-codes-accountability/

Top comments (0)