Running an Asterisk-based call center is like tuning a race car. The engine (Asterisk) is incredibly powerful, but without proper optimization, you're leaving performance — and money — on the table.
Most Asterisk call center guides focus on either basic setup or narrow technical tuning. This guide is different. We'll cover everything: from Asterisk system-level performance tuning to queue configuration, agent management, call flow optimization, monitoring strategies, and operational best practices that directly impact your bottom line.
Whether you're running 10 agents or 200, this guide will help you squeeze maximum performance from your Asterisk call center.
Why Asterisk Call Center Optimization Matters
Before diving into the how, let's quantify the why:
| Optimization Area | Typical Impact | Revenue Effect |
|---|---|---|
| Queue wait time reduction | 30-50% decrease | 15-25% fewer abandonments |
| Agent utilization improvement | 15-20% increase | Same output, fewer agents needed |
| First call resolution boost | 10-15% improvement | 20-30% fewer repeat calls |
| System performance tuning | 2-3x concurrent call capacity | Delayed hardware upgrades |
| Call routing optimization | 20-30% faster resolution | Higher CSAT, lower churn |
For a 50-agent call center handling 500 calls/day, even a 10% improvement in efficiency translates to $50,000-$150,000 in annual savings.
Part 1: Asterisk System-Level Performance Tuning
1.1 Hardware and OS Optimization
Before touching Asterisk configuration, ensure your foundation is solid:
CPU Considerations:
- —Asterisk is primarily single-threaded for call processing but uses multiple threads for PJSIP and Stasis
- —G.711 (ulaw/alaw) codecs use minimal CPU; G.729 transcoding is CPU-intensive
- —Rule of thumb: 1 modern CPU core handles ~200 concurrent G.711 calls
- —For call centers with recording enabled, add 30% CPU overhead
Memory:
- —Base Asterisk: ~50-100 MB
- —Per concurrent call: ~2-4 MB (with recording: ~8-10 MB)
- —CDR/CEL processing: ~50-100 MB buffer
- —Recommendation: 4 GB minimum for 50 agents, 8 GB for 100+
Storage:
- —Call recordings: Plan for 1 GB/hour of recorded calls (G.711)
- —CDR database: ~1 KB per call record
- —Use SSDs for CDR database and active recordings
- —Archive older recordings to HDD or cloud storage
Linux Kernel Tuning:
# /etc/sysctl.conf - Essential tuning for Asterisk call centers
# Increase file descriptor limits
fs.file-max = 655350
# Network buffer optimization
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 65536
net.core.wmem_default = 65536
# Increase connection tracking for SIP
net.netfilter.nf_conntrack_max = 131072
# Reduce TIME_WAIT sockets
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
# Disable swap aggressiveness (keep Asterisk in RAM)
vm.swappiness = 10# /etc/security/limits.conf
asterisk soft nofile 65536
asterisk hard nofile 65536
asterisk soft nproc 8192
asterisk hard nproc 81921.2 PJSIP Threadpool Optimization
The PJSIP threadpool directly controls how fast Asterisk processes SIP transactions:
; pjsip.conf - [system] section
[system]
type=system
; For a call center with 50+ agents
threadpool_initial_size=20
threadpool_auto_increment=5
threadpool_idle_timeout=120
threadpool_max_size=100
; Reduce SIP timer for faster failure detection
timer_t1=100
timer_b=6400Sizing guide by call center size:
| Agents | Initial Size | Max Size | Auto Increment |
|---|---|---|---|
| 10-25 | 10 | 50 | 5 |
| 25-50 | 20 | 100 | 5 |
| 50-100 | 30 | 150 | 10 |
| 100-200 | 50 | 200 | 10 |
| 200+ | 80 | 300 | 15 |
1.3 Stasis Message Bus Tuning
The Stasis bus handles AMI events, CDR processing, and ARI — all critical for call center monitoring:
; stasis.conf
[threadpool]
initial_size = 10
idle_timeout_sec = 120
max_size = 60Pro tip: If you don't need AMI (because you're using a dedicated analytics tool), disabling res_manager reduces CPU overhead by 5-10% on busy systems.
1.4 Endpoint Identification Order
A small but impactful optimization — process registered phones first:
; pjsip.conf - [global] section
[global]
type=global
; Phones register (username), trunks use IP
endpoint_identifier_order=username,ip,anonymousThis avoids scanning IP-based rules for every registered phone, saving milliseconds per transaction that compound at scale.
Part 2: Queue Configuration Optimization
Queue configuration is where most call centers have the biggest optimization opportunities. A misconfigured queue can waste 20-30% of agent time.
2.1 Queue Strategy Selection
Choosing the right ring strategy dramatically affects agent utilization and caller wait times:
; queues.conf
[sales]
strategy = rrmemory ; Round-robin with memory
timeout = 15 ; Ring agent for 15 seconds
retry = 1 ; Retry immediately after timeout
wrapuptime = 10 ; 10-second wrap-up between calls
maxlen = 50 ; Maximum 50 callers in queue
[support]
strategy = fewestcalls ; Route to agent with fewest calls
timeout = 20 ; Slightly longer ring for support
retry = 1
wrapuptime = 30 ; More wrap-up time for complex calls
maxlen = 30Strategy comparison for call centers:
| Strategy | Best For | Pros | Cons |
|---|---|---|---|
ringall | Small teams (<5) | Fastest answer | Uneven distribution |
rrmemory | General queues | Even distribution | Doesn't consider skill |
fewestcalls | Support queues | Balanced workload | New agents get flooded |
leastrecent | High-volume sales | Ensures rest between calls | May leave skilled agents idle |
random | Overflow queues | Prevents gaming | Unpredictable load |
wrandom | Skill-based routing | Weighted control | Complex to configure |
2.2 Queue Timeout and Retry Optimization
The interaction between timeout, retry, and wrapuptime is critical:
Total cycle time = timeout + retry + wrapuptime
For a queue with timeout=15, retry=1, wrapuptime=10:
- —Each agent attempt takes 26 seconds maximum
- —A caller waiting for 3 available agents to be tried: ~78 seconds worst case
Optimization targets by queue type:
| Queue Type | Timeout | Retry | Wrapup | Rationale |
|---|---|---|---|---|
| Sales (inbound) | 12s | 1s | 5s | Speed is everything |
| Technical Support | 20s | 1s | 30s | Agents need documentation time |
| Billing | 15s | 1s | 15s | Moderate complexity |
| VIP/Priority | 10s | 0s | 5s | Fastest possible answer |
| Overflow | 25s | 1s | 0s | Maximize answer chance |
2.3 Queue Weight and Priority
For multi-queue environments, weights ensure high-priority queues are served first:
; queues.conf
[vip-support]
weight = 10 ; Highest priority
strategy = ringall
[standard-support]
weight = 5
strategy = rrmemory
[overflow-support]
weight = 1 ; Lowest priority
strategy = leastrecentWhen an agent is a member of multiple queues, higher-weight queues deliver calls first. This is essential for SLA management.
2.4 Dynamic Queue Membership
Static queue membership wastes capacity. Dynamic membership allows real-time optimization:
; queues.conf
[support]
member => PJSIP/agent101,0,Agent 101,SIP/agent101 ; Static (backup)
; Dynamic members added via:
; CLI: queue add member PJSIP/agent102 to support
; AMI: QueueAdd action
; Dialplan: AddQueueMember()Dialplan for agent login/logout:
; extensions.conf
[agent-controls]
; *51 = Login to queue
exten => *51,1,Answer()
same => n,AddQueueMember(support,PJSIP/${CALLERID(num)})
same => n,Playback(agent-loginok)
same => n,Hangup()
; *52 = Logout from queue
exten => *52,1,Answer()
same => n,RemoveQueueMember(support,PJSIP/${CALLERID(num)})
same => n,Playback(agent-loggedoff)
same => n,Hangup()
; *53 = Pause (break time)
exten => *53,1,Answer()
same => n,PauseQueueMember(support,PJSIP/${CALLERID(num)},,Break)
same => n,Playback(beep)
same => n,Hangup()
; *54 = Unpause (back from break)
exten => *54,1,Answer()
same => n,UnpauseQueueMember(support,PJSIP/${CALLERID(num)})
same => n,Playback(beep)
same => n,Hangup()2.5 Queue Announcements Optimization
Poorly configured announcements waste agent time and frustrate callers:
[support]
; Position/hold time announcements
announce-frequency = 60 ; Every 60 seconds
announce-holdtime = once ; Tell estimated hold time once
announce-position = yes ; "You are number X in line"
min-announce-frequency = 30 ; Don't announce more than every 30s
; Periodic announcements
periodic-announce = custom/thank-you-for-waiting
periodic-announce-frequency = 45
; Music on hold
musicclass = support-moh ; Dedicated MOH for this queue
; Join/leave announcements for agents
announce-to-first-user = yesAnti-pattern to avoid: Setting announce-frequency=15 with a 10-second announcement. This creates a loop where the caller hears announcements back-to-back, which increases abandonment by 20-40%.
Part 3: Call Routing Optimization
3.1 IVR Optimization: Reduce Layers, Increase Resolution
Every IVR layer costs you callers. Industry data shows:
| IVR Depth | Caller Completion Rate |
|---|---|
| 1 level | 95% |
| 2 levels | 80% |
| 3 levels | 60% |
| 4+ levels | <40% |
Optimized IVR structure:
; extensions.conf
[ivr-main]
exten => s,1,Answer()
same => n,Set(TIMEOUT(response)=5)
same => n,Background(custom/welcome-short) ; Keep under 8 seconds
same => n,WaitExten(3)
; Direct to department - ONE level deep
exten => 1,1,Goto(queue-sales,s,1) ; Sales
exten => 2,1,Goto(queue-support,s,1) ; Support
exten => 3,1,Goto(queue-billing,s,1) ; Billing
exten => 0,1,Goto(queue-reception,s,1) ; Operator
; Timeout/invalid → route to general queue (don't loop!)
exten => t,1,Goto(queue-support,s,1)
exten => i,1,Goto(queue-support,s,1)Key IVR optimization rules:
- —Maximum 2 IVR levels
- —Welcome message under 8 seconds
- —Always provide a "press 0 for operator" option
- —Timeout goes to a queue, not a replay
- —Track IVR completion rates — if below 80%, simplify
3.2 Skill-Based Routing
Route calls to agents with the right skills, reducing transfers and handle time:
; queues.conf
[support-english]
strategy = wrandom
; Penalty-based skill routing:
; penalty 0 = primary skill, penalty 5 = secondary, penalty 10 = backup
member => PJSIP/agent101,0 ; Native English speaker
member => PJSIP/agent102,0 ; Native English speaker
member => PJSIP/agent103,5 ; Intermediate English
member => PJSIP/agent104,10 ; Basic English (last resort)
[support-spanish]
strategy = wrandom
member => PJSIP/agent103,0 ; Native Spanish speaker
member => PJSIP/agent104,0 ; Native Spanish speaker
member => PJSIP/agent101,10 ; Basic Spanish (backup)Dialplan with penalty escalation (progressive routing):
[queue-support]
exten => s,1,Answer()
same => n,Set(QUEUE_MAX_PENALTY=0) ; Try primary agents first
same => n,Queue(support,,,,30) ; Wait 30s for primary
same => n,Set(QUEUE_MAX_PENALTY=5) ; Escalate to secondary
same => n,Queue(support,,,,30) ; Wait 30s more
same => n,Set(QUEUE_MAX_PENALTY=10) ; Include all agents
same => n,Queue(support,,,,60) ; Final attempt
same => n,VoiceMail(support@default,u) ; Voicemail fallback
same => n,Hangup()3.3 Time-Based Routing
Route calls based on business hours, holidays, and staffing levels:
[inbound-handler]
exten => s,1,Answer()
same => n,GotoIfTime(09:00-18:00,mon-fri,,?business-hours,s,1)
same => n,GotoIfTime(09:00-13:00,sat,,?saturday-hours,s,1)
same => n,Goto(after-hours,s,1)
[business-hours]
exten => s,1,Goto(ivr-main,s,1)
[saturday-hours]
exten => s,1,Set(QUEUE_MAX_PENALTY=0) ; Only primary agents on Saturday
same => n,Queue(support,,,,60)
same => n,VoiceMail(support@default,u)
same => n,Hangup()
[after-hours]
exten => s,1,Playback(custom/after-hours-message)
same => n,VoiceMail(support@default,u)
same => n,Hangup()3.4 Caller ID-Based Priority Routing
Recognize returning callers and VIP customers:
[inbound-handler]
exten => s,1,Answer()
; Check if VIP customer (from database or file)
same => n,Set(VIP=${DB(vip/${CALLERID(num)})})
same => n,GotoIf($["${VIP}" = "yes"]?vip-queue,s,1)
; Check if returning caller within 24 hours
same => n,Set(RECENT=${DB(recent/${CALLERID(num)})})
same => n,GotoIf($["${RECENT}" != ""]?priority-queue,s,1)
; Standard routing
same => n,Goto(ivr-main,s,1)
[vip-queue]
exten => s,1,Queue(vip-support,,,,120) ; VIP queue with longer timeout
same => n,Hangup()Part 4: Agent Performance Optimization
4.1 Agent Status Management
Effective agent status tracking prevents "ghost agents" — logged-in agents who aren't actually available:
; Configure device state monitoring in pjsip.conf
[agent101]
type=endpoint
device_state_busy_at=1 ; Mark busy after 1 active callCritical agent states to monitor:
| State | Description | Optimization Action |
|---|---|---|
| Available | Ready for calls | Ensure even distribution |
| On Call | Active conversation | Monitor talk time |
| Wrap-up | Post-call work | Enforce time limits |
| Paused (Break) | Scheduled break | Track adherence |
| Paused (Training) | In training | Schedule during low volume |
| Unavailable | Not responding | Auto-logout after 3 missed calls |
4.2 Auto-Logout for Unresponsive Agents
Agents who don't answer calls waste queue time for every caller:
; queues.conf
[support]
autopause = yes ; Auto-pause after missed call
autopausedelay = 0 ; Immediately
autopausebusy = no ; Don't pause for busy (might be on another queue call)
autopauseunavail = yes ; Pause for unavailableAdvanced: Auto-logout after N missed calls (via dialplan + AGI):
; Track missed calls per agent
[queue-support]
exten => s,1,Queue(support,,,,30)
same => n,ExecIf($["${QUEUESTATUS}" = "TIMEOUT"]?Set(DB(missed/${MEMBERINTERFACE})=$[${DB(missed/${MEMBERINTERFACE})} + 1]))
same => n,ExecIf($[${DB(missed/${MEMBERINTERFACE})} >= 3]?PauseQueueMember(support,${MEMBERINTERFACE},,AutoPaused-3-missed))4.3 Wrap-Up Time Optimization
Wrap-up time is the #1 hidden capacity killer. Too long = wasted capacity. Too short = poor data entry.
Benchmarks by call type:
| Call Type | Recommended Wrap-up | Notes |
|---|---|---|
| Simple inquiry | 5-10s | Automated disposition |
| Sales call | 10-15s | CRM update required |
| Technical support | 20-30s | Ticket creation |
| Complex escalation | 45-60s | Documentation critical |
Implementation with dispositions:
[post-call]
exten => s,1,Set(WRAPUP_START=${EPOCH})
same => n,Read(DISPOSITION,,1,,,5) ; 5-second timeout for disposition code
same => n,Set(CDR(disposition)=${DISPOSITION})
same => n,Set(WRAPUP_TIME=$[${EPOCH} - ${WRAPUP_START}])
same => n,UserEvent(WrapupComplete,Agent: ${CALLERID(num)},Duration: ${WRAPUP_TIME},Disposition: ${DISPOSITION})
same => n,Hangup()Part 5: Call Quality and Recording Optimization
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.
5.1 Codec Optimization for Call Centers
; pjsip.conf - endpoint template for call center agents
[agent-template](!)
type=endpoint
allow=!all,ulaw,alaw ; G.711 only - lowest CPU, best quality for LAN
dtls_auto_generate_cert=yesCodec selection guide:
| Codec | Bandwidth | CPU | Quality | Use Case |
|---|---|---|---|---|
| G.711 ulaw | 87 kbps | Minimal | Excellent | LAN agents, local trunks |
| G.711 alaw | 87 kbps | Minimal | Excellent | EU standard |
| G.722 | 87 kbps | Low | HD voice | Premium queues |
| G.729 | 31 kbps | High | Good | Remote agents, WAN |
| Opus | Variable | Moderate | Excellent | WebRTC agents |
For call centers: Use G.711 within the LAN (agents) and negotiate with trunks based on their preference. Avoid transcoding if possible — it adds latency and CPU load.
5.2 Call Recording Best Practices
; Record all calls in the support queue
[queue-support]
exten => s,1,Set(MONITOR_FILENAME=/var/spool/asterisk/monitor/${STRFTIME(${EPOCH},,%Y/%m/%d)}/${UNIQUEID})
same => n,MixMonitor(${MONITOR_FILENAME}.wav,b)
same => n,Queue(support)
same => n,StopMixMonitor()Recording optimization tips:
- —Use WAV format during recording (low CPU), convert to MP3 nightly via cron
- —Organize by date (
/YYYY/MM/DD/) for easy archival - —Set recording permissions to prevent agent access to other agents' calls
- —Implement retention policy: 90 days active, 1 year archived, then delete
- —Monitor disk space — alert at 80% utilization
# Nightly conversion cron job
# /etc/cron.d/asterisk-recording-convert
0 2 * * * asterisk find /var/spool/asterisk/monitor/$(date -d yesterday +\%Y/\%m/\%d) -name "*.wav" -exec sox {} {}.mp3 \; -delete5.3 Jitter Buffer Configuration
For remote agents or SIP trunks with variable latency:
; pjsip.conf
[remote-agent-template](!)
type=endpoint
allow=!all,g729,ulaw
; Fixed jitter buffer for consistent call quality
jbimpl=fixed
jbmaxsize=200 ; 200ms max buffer
jbtargetextra=40 ; Extra buffering
jblog=no ; Disable logging in productionPart 6: Monitoring and Analytics — The Optimization Multiplier
All the optimizations above are guesses without data. Monitoring transforms guessing into science.
6.1 Essential Call Center Metrics
Track these metrics in real-time and historically:
Real-Time Dashboard Metrics:
| Metric | Target | Alert Threshold | Action |
|---|---|---|---|
| Calls in Queue | <10 | >15 | Add agents from overflow |
| Longest Wait | <60s | >120s | Escalate immediately |
| Available Agents | >20% of total | <10% | Cancel breaks |
| Service Level | >80% in 20s | <60% | Emergency staffing |
| Abandonment Rate | <5% | >8% | Activate callbacks |
Historical Analysis Metrics:
| Metric | Purpose | Review Frequency |
|---|---|---|
| Average Handle Time (AHT) | Agent efficiency | Daily |
| First Call Resolution (FCR) | Quality indicator | Weekly |
| Agent Utilization | Capacity planning | Weekly |
| Cost Per Call | Financial health | Monthly |
| Customer Satisfaction (CSAT) | Experience quality | Monthly |
6.2 AMI-Based Real-Time Monitoring
Asterisk Manager Interface (AMI) provides real-time event streaming:
; manager.conf
[monitoring]
secret = strong_password_here
permit = 127.0.0.1/255.255.255.255
read = call,agent,reporting
write = command
eventfilter = Event: QueueMember*
eventfilter = Event: QueueCaller*
eventfilter = Event: AgentConnect
eventfilter = Event: AgentCompleteKey AMI events for call center monitoring:
| Event | Data Provided | Use Case |
|---|---|---|
QueueCallerJoin | Queue, position, caller ID | Real-time queue depth |
QueueCallerLeave | Reason (answered, abandoned, timeout) | Abandonment tracking |
AgentConnect | Wait time, agent | Service level calculation |
AgentComplete | Talk time, hold time | AHT analysis |
QueueMemberPause | Reason, duration | Break adherence |
QueueMemberStatus | Device state | Agent availability |
6.3 CDR and CEL Analysis
CDR (Call Detail Records) and CEL (Channel Event Logging) provide the raw data for all historical reporting:
; cdr.conf
[general]
enable=yes
unanswered=yes ; Track unanswered calls too
congestion=yes ; Track congestion events
endbeforehexten=no ; Complete CDR before h extension
; cdr_adaptive_odbc.conf (for database storage)
[asterisk-cdr]
connection=asterisk
table=cdr
alias start => calldate
alias clid => clid
alias src => src
alias dst => dst
alias dcontext => dcontext
alias channel => channel
alias dstchannel => dstchannel
alias lastapp => lastapp
alias lastdata => lastdata
alias duration => duration
alias billsec => billsec
alias disposition => disposition
alias uniqueid => uniqueidSample CDR analysis queries:
-- Hourly call volume pattern (for staffing optimization)
SELECT
EXTRACT(HOUR FROM calldate) AS hour,
COUNT(*) AS total_calls,
COUNT(CASE WHEN disposition = 'ANSWERED' THEN 1 END) AS answered,
COUNT(CASE WHEN disposition = 'NO ANSWER' THEN 1 END) AS abandoned,
ROUND(AVG(CASE WHEN disposition = 'ANSWERED' THEN billsec END), 1) AS avg_talk_time,
ROUND(AVG(duration - billsec), 1) AS avg_wait_time
FROM cdr
WHERE calldate >= CURRENT_DATE - INTERVAL '7 days'
AND dcontext LIKE 'queue-%'
GROUP BY EXTRACT(HOUR FROM calldate)
ORDER BY hour;
-- Agent performance ranking
SELECT
dstchannel AS agent,
COUNT(*) AS calls_handled,
ROUND(AVG(billsec), 1) AS avg_talk_time,
ROUND(AVG(duration - billsec), 1) AS avg_wait_before_answer,
MAX(billsec) AS longest_call,
SUM(billsec) / 3600.0 AS total_hours
FROM cdr
WHERE disposition = 'ANSWERED'
AND dcontext LIKE 'queue-%'
AND calldate >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY dstchannel
ORDER BY calls_handled DESC;
-- Service level calculation (% answered within 20 seconds)
SELECT
DATE(calldate) AS day,
COUNT(*) AS total_calls,
COUNT(CASE WHEN disposition = 'ANSWERED'
AND (duration - billsec) <= 20 THEN 1 END) AS within_sla,
ROUND(
100.0 * COUNT(CASE WHEN disposition = 'ANSWERED'
AND (duration - billsec) <= 20 THEN 1 END)
/ NULLIF(COUNT(*), 0), 1
) AS service_level_pct
FROM cdr
WHERE calldate >= CURRENT_DATE - INTERVAL '30 days'
AND dcontext LIKE 'queue-%'
GROUP BY DATE(calldate)
ORDER BY day;6.4 Why Purpose-Built Analytics Beats DIY
Building dashboards from raw CDR data works, but it takes 40-80 hours to set up and maintain. You need to:
- —Write and maintain SQL queries (updated as Asterisk versions change)
- —Build visualization dashboards (Grafana, custom web apps)
- —Set up alerting rules
- —Handle data retention and archival
- —Build agent performance reports
- —Create real-time wallboards
This is why teams are switching to purpose-built Asterisk analytics tools like Astervis. With a single install command, you get:
- —30+ pre-built charts: heatmaps, agent leaderboards, trunk analytics
- —Real-time dashboards: queue depth, wait times, agent status — live
- —Operator management: KPI tracking, performance scoring, schedules
- —CRM integration: Bitrix24, AmoCRM — calls linked to deals
- —Call recording playback: searchable, filterable, right in the dashboard
- —15-minute setup:
curl -sSL https://get.astervis.io | bash
No SQL queries to write. No Grafana dashboards to maintain. No custom code.
Part 7: Operational Best Practices
7.1 Capacity Planning Framework
Use historical data to predict staffing needs:
Erlang C formula inputs:
- —Average calls per hour (from CDR)
- —Average handle time (talk + wrap-up)
- —Target service level (e.g., 80% in 20 seconds)
Quick staffing table (80/20 SLA):
| Calls/Hour | AHT (min) | Agents Needed | Occupancy |
|---|---|---|---|
| 50 | 4 | 5 | 67% |
| 100 | 4 | 9 | 74% |
| 200 | 4 | 17 | 78% |
| 300 | 4 | 25 | 80% |
| 500 | 4 | 40 | 83% |
Warning: Agent occupancy above 85% leads to burnout. Plan for 75-80% maximum sustained occupancy.
7.2 Queue Overflow Strategy
Don't let callers wait forever. Implement a progressive overflow strategy:
0-30s: Primary queue (skill-matched agents)
30-60s: Secondary queue (same department, lower skill)
60-90s: Overflow queue (any available agent)
90-120s: Callback offer
120s+: Voicemail with callback promise
; extensions.conf - Progressive overflow
[queue-support-overflow]
exten => s,1,Set(QUEUE_MAX_PENALTY=0)
same => n,Queue(support,,,,30) ; 30s: primary agents
same => n,Set(QUEUE_MAX_PENALTY=5)
same => n,Queue(support,,,,30) ; 60s: secondary agents
same => n,Set(QUEUE_MAX_PENALTY=10)
same => n,Queue(support,,,,30) ; 90s: all agents
same => n,Goto(callback-offer,s,1) ; Offer callback7.3 SLA Management
Define and monitor SLAs by queue:
| Queue | SLA Target | Measurement |
|---|---|---|
| VIP Support | 95% in 10s | Zero tolerance for misses |
| Sales | 80% in 20s | Revenue-impacting |
| General Support | 80% in 30s | Industry standard |
| Billing | 70% in 45s | Lower urgency |
| Email/Callback | 24-hour response | Different SLA type |
7.4 Continuous Improvement Cycle
Optimization is not a one-time project. Implement a weekly review cycle:
Weekly optimization review (30 minutes):
- —Service Level Review (5 min): Did we meet SLA targets? Which queues missed?
- —Agent Performance (10 min): Top/bottom performers. Who needs coaching?
- —Call Pattern Analysis (5 min): Any new volume spikes? Seasonal trends?
- —Queue Configuration (5 min): Do timeout/wrapup settings still make sense?
- —System Health (5 min): CPU, memory, disk trends. Any capacity concerns?
Part 8: Common Optimization Mistakes to Avoid
Mistake 1: Over-Optimizing for AHT
Pushing agents to reduce handle time often increases repeat calls. Focus on First Call Resolution instead.
Mistake 2: Too Many Queue Announcements
Position announcements every 15 seconds irritate callers. Set announce-frequency to 45-60 seconds minimum.
Mistake 3: No Overflow Strategy
Callers waiting more than 2 minutes without options will abandon — and they won't call back. Always have a callback or voicemail fallback.
Mistake 4: Static Agent Assignment
Keeping agents in fixed queues wastes capacity during volume fluctuations. Use dynamic queue membership with skill-based routing.
Mistake 5: Ignoring After-Hours Calls
Many businesses lose 15-20% of potential revenue by not handling after-hours calls. Implement voicemail-to-email, callback scheduling, or route to remote agents in different time zones.
Mistake 6: No Monitoring
Flying blind is the biggest mistake. You can't optimize what you can't measure. At minimum, track service level, abandonment rate, and agent utilization daily.
Optimization Checklist
Use this checklist to audit your Asterisk call center:
System Level:
- — Linux kernel tuned (file descriptors, network buffers, swap)
- — PJSIP threadpool sized for your agent count
- — Stasis threadpool configured
- — Endpoint identification order optimized
- — Unnecessary modules disabled
Queue Configuration:
- — Ring strategy matches queue purpose
- — Timeout/retry/wrapup times optimized per queue
- — Queue weights configured for priority
- — Dynamic membership enabled
- — Announcements not too frequent
Call Routing:
- — IVR has maximum 2 levels
- — Skill-based routing implemented
- — Time-based routing configured
- — Overflow strategy in place
- — Callback option available
Agent Management:
- — Auto-pause for missed calls enabled
- — Wrap-up times appropriate per queue
- — Agent status properly tracked
- — Performance metrics visible to supervisors
Monitoring:
- — Real-time dashboard operational
- — Historical reporting configured
- — Alerting rules set for SLA breaches
- — Weekly optimization review scheduled
- — Call recording and quality monitoring active
Key Takeaways
- —Start with measurement. Install monitoring before making changes so you can quantify improvements.
- —System tuning matters. PJSIP threadpool and kernel settings can 2-3x your concurrent call capacity.
- —Queue configuration is the highest-ROI optimization. Strategy, timeouts, and weights directly impact every caller's experience.
- —Skill-based routing reduces transfers by 30-40%, improving both efficiency and customer satisfaction.
- —Agent utilization sweet spot is 75-80%. Higher causes burnout; lower wastes payroll.
- —Progressive overflow prevents abandonment. Never let a caller wait without options.
- —Continuous improvement beats big-bang optimization. Weekly 30-minute reviews compound over time.
Start Optimizing Today
You don't need to implement everything at once. Start with the highest-impact items:
- —Install monitoring to establish baselines
- —Optimize queue timeouts and strategies
- —Implement skill-based routing
- —Set up overflow and callback handling
- —Schedule weekly optimization reviews
For instant visibility into your Asterisk call center performance, try Astervis — 30+ real-time charts, agent tracking, and CRM integration. Install in 15 minutes, no configuration required.
Start your free 14-day trial →
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.
