Master ViciDial's three auto-dial modes with production-ready configurations, database tuning, and real-world troubleshooting for enterprise call centers
Prerequisites
Before proceeding, ensure you have:
- ViciDial 2.14+ installed and running (check via
asterisk -rx "core show version") - MySQL/MariaDB access to the asterisk database
- Asterisk 11+ or higher with DAHDI/SIP trunks configured
- Root or sudo access on the ViciDial server
- A working inbound/outbound carrier with available channels
- At least 3-5 agents trained and ready to test
- Backup of your asterisk database (
mysqldump asterisk > backup_$(date +%Y%m%d).sql)
Understanding ViciDial Auto-Dial Modes
ViciDial offers three fundamentally different calling strategies:
- Predictive Dialing: System dials before agent is available. AI-driven pacing predicts agent availability and adjusts dial rate dynamically.
- Ratio-Based Dialing: Fixed multiplier applied to available agents (e.g., 3:1 = 3 dials per agent). Simple, predictable, less sophisticated.
- Progressive Dialing: Agent initiates dial manually or via single-click. Lowest abandonment rates, highest agent idle time.
Each mode has different CPU, database, and channel requirements. Predictive uses the most resources but achieves highest contact rates.
Section 1: Database Configuration & Prerequisites
Create Your Campaign
Access the ViciDial admin interface:
# SSH into your ViciDial server
ssh -i your_key.pem [email protected]
# Verify MySQL connectivity
mysql -u root -p asterisk -e "SELECT * FROM vicidial_campaigns LIMIT 1;"
Insert a new campaign via admin panel (/vicidial/admin.php) or via MySQL:
USE asterisk;
INSERT INTO vicidial_campaigns (
campaign_id,
campaign_name,
campaign_description,
dial_method,
phone_number_format,
dispo_group_id,
campaign_status,
auto_dial_level,
dial_timeout,
call_volume_group,
lead_recycle_method,
drop_percentage,
local_call_time,
min_ingroup_agents,
scheduled_callbacks,
test_call_flag
)
VALUES (
'PREDICTIVE_01',
'Predictive Campaign Test',
'High-volume predictive outbound campaign',
'INBOUND',
'US',
'1',
'ACTIVE',
'0.8',
'45',
'default',
'DISABLED',
'5',
'GMT',
'1',
'ENABLED',
'N'
);
Key field explanations:
dial_method: INBOUND (most common), BLENDED, CALLBACKauto_dial_level: 0.1–1.0 (0.8 recommended for predictive; 0.3 for progressive)drop_percentage: Acceptable % of calls dropped due to no-agent availability (5-10% standard)dial_timeout: Seconds to wait for answer before abandoning
Configure Dialing Parameters
Update the vicidial_campaigns table with auto-dial specifics:
UPDATE vicidial_campaigns
SET auto_dial_level = 0.8,
dial_timeout = 45,
drop_percentage = 8,
scheduled_callbacks = 'ENABLED'
WHERE campaign_id = 'PREDICTIVE_01';
Verify the campaign is properly configured:
mysql -u root -p asterisk -e "SELECT campaign_id, campaign_name, dial_method, auto_dial_level, drop_percentage FROM vicidial_campaigns WHERE campaign_id = 'PREDICTIVE_01';"
Section 2: Asterisk SIP/Carrier Configuration
Configure Outbound Carrier Trunks
Edit the carrier configuration in /etc/asterisk/sip-vicidial.conf:
[CARRIER_OUTBOUND_01](!)
type=friend
host=123.45.67.89
port=5060
secret=YourSecretPassword123
fromuser=vicidial
fromdomain=123.45.67.89
dtmfmode=rfc2833
disallow=all
allow=ulaw,alaw
context=from-internal
qualify=yes
qualify_freq=60
maxcallbitrate=128
nat=no
canreinvite=no
directmedia=no
progressinband=yes
Create a production-safe carrier entry:
[carrier_sirius](CARRIER_OUTBOUND_01)
host=carrier.sirius.com
secret=SiriusCarrierSecret999
fromuser=vicidial_client_001
fromdomain=carrier.sirius.com
Configure Dial Plan Extensions
Edit /etc/asterisk/extensions-vicidial.conf to add outbound dialing routes:
[from-internal]
exten => _1NXXNXXXXXX,1,NoOp(ViciDial Outbound - ${EXTEN})
same => n,Set(CHANNEL(hangup_handler_push)=hangup,s,1)
same => n,Dial(SIP/${EXTEN}@carrier_sirius,45,TtKk)
same => n,Hangup()
same => n,Busy()
same => n,Unavailable()
Load and Verify Asterisk Configuration
# Backup current config
cp /etc/asterisk/extensions-vicidial.conf /etc/asterisk/extensions-vicidial.conf.backup
# Reload Asterisk dialplan
asterisk -rx "dialplan reload"
# Check for syntax errors
asterisk -rx "dialplan show from-internal" | head -20
# Verify carrier registration
asterisk -rx "sip show peers" | grep carrier_sirius
Expected output should show your carrier with UNREACHABLE or OK status (OK is ideal):
carrier_sirius/1234567890 123.45.67.89:5060 D yes yes OK
Section 3: Predictive Dialing Setup
Understanding Predictive Algorithm
ViciDial's predictive dialer uses a dynamic pacing algorithm. The system:
- Monitors agent availability in real-time
- Dials calls ahead of agent availability
- Adjusts dial rate based on answer rates, talk time, and wrap-up time
- Aims to minimize agent idle time while staying within drop percentage limits
Set Campaign to Predictive Mode
Access /vicidial/admin.php → Campaigns → Select your campaign → Edit
Or update via SQL:
UPDATE vicidial_campaigns
SET
dial_method = 'INBOUND',
auto_dial_level = 0.85,
drop_percentage = 8,
scheduled_callbacks = 'ENABLED',
lead_recycle_method = 'DISABLED',
pause_dialing = 'N'
WHERE campaign_id = 'PREDICTIVE_01';
Configure Predictive Parameters in vicidial_settings
Edit the ViciDial system settings table:
UPDATE vicidial_settings
SET
predictive_dialer_flag = '1',
predictive_answer_rate = '45',
predictive_drop_rate_threshold = '3',
predictive_cpu_limit = '90',
outbound_autodial = '1'
WHERE setting_name = 'ViciDial';
Parameter definitions:
predictive_dialer_flag: 1 = enable, 0 = disablepredictive_answer_rate: Expected % of calls that connect (e.g., 45%)predictive_drop_rate_threshold: Pause dialing if drop rate exceeds this %predictive_cpu_limit: CPU threshold before throttling dials
Configure the Predictive Dialer Service
The ViciDial Predictive Dialer runs as a background service. Check if it's active:
# Check if vicidial_dialer.pl is running
ps aux | grep vicidial_dialer.pl | grep -v grep
# If not running, start it manually
/usr/share/astguiclient/vicidial_dialer.pl > /var/log/asterisk/vicidial_dialer.log 2>&1 &
# Make permanent via cron (check root crontab)
crontab -e
# Add this line to restart dialer if it crashes:
* * * * * /usr/share/astguiclient/check_vicidial_process.sh > /dev/null 2>&1
Create Campaign-Specific Lead Lists
Prepare your phone number list. Insert leads into the vicidial_list table:
USE asterisk;
INSERT INTO vicidial_list (
lead_id,
lead_phone_number,
lead_phone_number_2,
first_name,
last_name,
email,
campaign_id,
list_id,
vendor_lead_code,
status,
phone_code,
phone_number_formatted
)
VALUES
(NULL, '5551234567', '', 'John', 'Doe', '[email protected]', 'PREDICTIVE_01', '1', 'CODE001', 'NEW', '555', '555-123-4567'),
(NULL, '5559876543', '', 'Jane', 'Smith', '[email protected]', 'PREDICTIVE_01', '1', 'CODE002', 'NEW', '555', '555-987-6543'),
(NULL, '5552223333', '', 'Bob', 'Johnson', '[email protected]', 'PREDICTIVE_01', '1', 'CODE003', 'NEW', '555', '555-222-3333');
-- Verify insertion
SELECT COUNT(*) FROM vicidial_list WHERE campaign_id = 'PREDICTIVE_01' AND status = 'NEW';
Monitor Predictive Dialing
In real-time, check the dialer status:
# Monitor dialer queue
asterisk -rx "core show channels concise" | wc -l
# Check dial queue depth
mysql -u root -p asterisk -e "SELECT COUNT(*) as pending_dials FROM vicidial_list WHERE campaign_id = 'PREDICTIVE_01' AND status IN ('NEW', 'QUEUE');"
# Monitor predictive drops
mysql -u root -p asterisk -e "SELECT call_result, COUNT(*) as count FROM vicidial_log WHERE campaign_id = 'PREDICTIVE_01' AND call_date > DATE_SUB(NOW(), INTERVAL 1 HOUR) GROUP BY call_result;"
Section 4: Ratio-Based Dialing Setup
Understanding Ratio Dialing
Ratio (or Power) dialing maintains a fixed multiplier between agents and dials:
- 3:1 ratio: For every 1 available agent, system dials 3 calls
- 2:1 ratio: More conservative; 2 dials per available agent
- 5:1 ratio: Aggressive; higher abandonment but maximum throughput
Formula: Dials Per Minute = (Available Agents) × (Ratio) × (Calls Per Agent Per Minute)
Configure Campaign for Ratio Dialing
Set the auto_dial_level to 0.5 for a moderate ratio approach:
UPDATE vicidial_campaigns
SET
dial_method = 'INBOUND',
auto_dial_level = 0.50,
drop_percentage = 12,
scheduled_callbacks = 'ENABLED',
pause_dialing = 'N'
WHERE campaign_id = 'RATIO_01';
In the ViciDial admin panel, under "Dialer Settings," configure:
- Dial Ratio: 3:1
- Dial Timeout: 45 seconds
- Drop Percentage Threshold: 12%
Adjust the Dialing Queue Script
Edit /usr/share/astguiclient/vicidial_dialer.pl (or create a wrapper):
# Around line 850, locate the ratio calculation:
# Example modification for stricter ratio control
my $available_agents = $dbh->selectrow_array(
"SELECT COUNT(*) FROM vicidial_log WHERE campaign_id='$campaign_id'
AND call_date > DATE_SUB(NOW(), INTERVAL 10 SECOND)
AND status IN ('QUEUE', 'INCALL')"
);
my $ratio = 3; # Set your ratio here
my $dials_to_queue = $available_agents * $ratio;
# Queue dials accordingly
for (my $i = 0; $i < $dials_to_queue; $i++) {
queue_dial_for_agent($campaign_id);
}
Monitor Ratio Dialing Performance
# Check current agent count
mysql -u root -p asterisk -e "
SELECT
COUNT(DISTINCT user) as active_agents,
COUNT(*) as total_sessions
FROM vicidial_log
WHERE campaign_id = 'RATIO_01'
AND call_date > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
AND status IN ('QUEUE', 'INCALL');
"
# Calculate real-time dial rate
mysql -u root -p asterisk -e "
SELECT
COUNT(*) as calls_last_minute
FROM vicidial_log
WHERE campaign_id = 'RATIO_01'
AND call_date > DATE_SUB(NOW(), INTERVAL 1 MINUTE);
"
Section 5: Progressive Dialing Setup
Understanding Progressive Dialing
Progressive dialing is the most conservative:
- Agent clicks DIAL button manually (or via macro)
- One call per button click
- Zero abandon rate (no automatic dialing)
- Best for new campaigns or compliance-heavy environments
Configure Campaign for Progressive Mode
UPDATE vicidial_campaigns
SET
dial_method = 'INBOUND',
auto_dial_level = 0.15,
drop_percentage = 0,
scheduled_callbacks = 'ENABLED',
pause_dialing = 'N'
WHERE campaign_id = 'PROGRESSIVE_01';
Configure Agent Macro for One-Click Dialing
Edit the agent's hotkey configuration in /agc/vicidial.php:
Agent users can assign a dial macro. In ViciDial admin, under "User Settings," set:
Dial Prefix: 0 (Agent dials 0 + number, or auto-fills from lead)
Dial Method: PROGRESSIVE
Auto Dial: Disabled
Or configure via database:
UPDATE vicidial_users
SET
auto_dial_mode = 'PROGRESSIVE',
auto_dial_level = 0.15,
auto_call_override = 'OFF'
WHERE user = 'agent_001';
Enable Manual Dial Button in Agent Screen
The standard ViciDial agent screen (/agc/vicidial.php) already includes a DIAL button. Ensure it's enabled:
- Log in as an agent
- Lead information populates from the list
- Agent clicks DIAL button
- Call connects to that single lead
No additional configuration is required for basic progressive dialing.
Section 6: Performance Tuning & Optimization
Database Query Optimization
ViciDial relies on frequent database queries. Optimize with proper indexing:
-- Check existing indexes
SHOW INDEX FROM vicidial_log;
-- Add performance indexes if missing
ALTER TABLE vicidial_list
ADD INDEX idx_campaign_status (campaign_id, status),
ADD INDEX idx_phone_number (lead_phone_number),
ADD INDEX idx_call_date (call_date);
ALTER TABLE vicidial_log
ADD INDEX idx_campaign_call_date (campaign_id, call_date),
ADD INDEX idx_status_date (status, call_date),
ADD INDEX idx_user_date (user, call_date);
-- Optimize tables after adding indexes
OPTIMIZE TABLE vicidial_log;
OPTIMIZE TABLE vicidial_list;
OPTIMIZE TABLE vicidial_closer_log;
Asterisk Channel Configuration
Increase available channels based on your trunking:
; In /etc/asterisk/sip.conf
[general]
maxforwards=20
udpbindaddr=0.0.0.0
tcpenable=yes
tcpbindaddr=0.0.0.0
tlsenable=no
srvlookup=yes
pedantic=no
maxcallbitrate=256000
autocreatepeer=no
relaxdtmf=yes
rtpholdtimeout=300
rtpkeepalive=no
rtptimeout=7200
CPU and Memory Limits
Monitor resource usage:
# Real-time system monitor
top -p $(pidof asterisk)
# Check memory usage
free -h
# Limit ViciDial processes if needed
ulimit -m 2097152 # 2GB memory limit
ulimit -n 65536 # 65K file descriptors
Optimize vicidial_dialer.pl Performance
Edit /usr/share/astguiclient/vicidial_dialer.pl to reduce query frequency:
# Around line 250, adjust loop sleep interval
my $loop_sleep = 0.5; # 500ms between dial checks (higher = less CPU)
# Reduce the number of campaigns processed per cycle
my $campaigns_per_cycle = 10;
# Increase batch dial size for efficiency
my $dial_batch_size = 50;
Section 7: Troubleshooting Common Issues
Issue 1: Dialer Not Making Calls
Symptoms: Campaign active but no calls initiated.
Diagnosis:
# Check if dialer process is running
ps aux | grep vicidial_dialer.pl
# Check error logs
tail -100 /var/log/asterisk/messages | grep -i "dial\|error"
# Verify database connection
mysql -u root -p asterisk -e "SELECT COUNT(*) FROM vicidial_list WHERE campaign_id='PREDICTIVE_01' AND status='NEW';"
# Check Asterisk core
asterisk -rx "core show channels concise" | wc -l
Solutions:
- Restart the dialer:
killall vicidial_dialer.pl && sleep 2 && /usr/share/astguiclient/vicidial_dialer.pl & - Verify carrier registration:
asterisk -rx "sip show peers" - Check campaign status in database:
UPDATE vicidial_campaigns SET pause_dialing='N' WHERE campaign_id='PREDICTIVE_01';
Issue 2: High Call Drop Rate
Symptoms: Drop percentage exceeding threshold; caller disconnect before agent connects.
Diagnosis:
# Check drop rate by call result
mysql -u root -p asterisk -e "
SELECT
call_result,
COUNT(*) as count,
ROUND(COUNT(*) / (SELECT COUNT(*) FROM vicidial_log WHERE campaign_id='PREDICTIVE_01' AND call_date > DATE_SUB(NOW(), INTERVAL 1 HOUR)) * 100, 2) as percentage
FROM vicidial_log
WHERE campaign_id='PREDICTIVE_01'
AND call_date > DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY call_result;
"
# Check agent availability
mysql -u root -p asterisk -e "SELECT user, COUNT(*) FROM vicidial_log WHERE campaign_id='PREDICTIVE_01' AND call_date > DATE_SUB(NOW(), INTERVAL 1 HOUR) GROUP BY user;";
Solutions:
- Reduce
auto_dial_levelfrom 0.85 to 0.70 - Increase
drop_percentagethreshold temporarily - Add more agents to the campaign
- Check agent call handling times:
SELECT user, AVG(LENGTH_OF_CALL) FROM vicidial_log GROUP BY user;
Issue 3: SIP Carrier Errors / Registration Failures
Symptoms: Carrier shows UNREACHABLE; calls fail with SIP 503.
Diagnosis:
# Check SIP registration
asterisk -rx "sip show registry"
# Test carrier connectivity
asterisk -rx "sip show peer carrier_sirius"
# Check carrier logs
tail -50 /var/log/asterisk/messages | grep -i "sirius\|carrier"
Solutions:
- Verify carrier IP and credentials:
cat /etc/asterisk/sip-vicidial.conf | grep -A5 carrier_sirius - Check network connectivity:
ping -c 5 carrier.sirius.com - Restart SIP channel driver:
asterisk -rx "module reload res_sip"
Issue 4: Agent Screen Not Showing Leads
Symptoms: Agent sees blank lead information despite calls in queue.
Diagnosis:
# Check lead list status
mysql -u root -p asterisk -e "SELECT COUNT(*) FROM vicidial_list WHERE campaign_id='PREDICTIVE_01' AND status IN ('NEW', 'QUEUE');";
# Check user campaign assignment
mysql -u root -p asterisk -e "SELECT user, campaign_id FROM vicidial_users WHERE user='agent_001';";
# Verify vicidial.php logs
tail -50 /var/log/apache2/error.log | grep vicidial
Solutions:
- Assign user to campaign:
UPDATE vicidial_users SET campaign_id='PREDICTIVE_01' WHERE user='agent_001'; - Reload agent screen (Ctrl+R or refresh browser)
- Clear browser cache and cookies
Issue 5: Calls Dialing to Wrong Number or Format
Symptoms: Calls connecting to incomplete or malformed numbers.
Diagnosis:
# Check last 10 call attempts
mysql -u root -p asterisk -e "
SELECT
lead_id,
lead_phone_number,
phone_number_formatted,
call_result
FROM vicidial_log
WHERE campaign_id='PREDICTIVE_01'
ORDER BY call_date DESC LIMIT 10;
";
# Check dial plan
asterisk -rx "dialplan show from-internal"
Solutions:
- Verify phone_number_format in campaign: Should be 'US' or 'INTL'
- Ensure lead phone numbers in vicidial_list don't include non-numeric characters (except +)
- Check extensions-vicidial.conf dial pattern:
exten => _1NXXNXXXXXX
Section 8: Production Monitoring & Maintenance
Real-Time Dashboard Query
Create a monitoring script to check campaign health:
#!/bin/bash
# /usr/local/bin/vicidial_monitor.sh
CAMPAIGN="PREDICTIVE_01"
INTERVAL=60
while true; do
echo "=== ViciDial Campaign Status: $CAMPAIGN ==="
echo "Time: $(date)"
mysql -u root -p asterisk -e "
SELECT
'Active Agents' as metric, COUNT(DISTINCT user) as value
FROM vicidial_log
WHERE campaign_id='$CAMPAIGN'
AND call_date > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
AND status IN ('QUEUE', 'INCALL')
UNION ALL
SELECT
'Channels In Use', COUNT(*)
FROM vicidial_log
WHERE campaign_id='$CAMPAIGN'
AND call_date > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
UNION ALL
SELECT
'Leads Pending', COUNT(*)
FROM vicidial_list
WHERE campaign_id='$CAMPAIGN' AND status='NEW'
UNION ALL
SELECT
'Avg Talk Time (sec)', ROUND(AVG(LENGTH_OF_CALL))
FROM vicidial_log
WHERE campaign_id='$CAMPAIGN'
AND call_date > DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND call_result='SALE';
"
echo ""
sleep $INTERVAL
done
Run the script:
chmod +x /usr/local/bin/vicidial_monitor.sh
/usr/local/bin/vicidial_monitor.sh
Regular Database Maintenance
#!/bin/bash
# /usr/local/bin/vicidial_maintenance.sh
# Backup database daily
mysqldump -u root -p asterisk > /backups/asterisk_$(date +%Y%m%d).sql
# Purge old logs (keep 90 days)
mysql -u root -p asterisk -e "
DELETE FROM vicidial_log WHERE call_date < DATE_SUB(NOW(), INTERVAL 90 DAY);
DELETE FROM vicidial_closer_log WHERE call_date < DATE_SUB(NOW(), INTERVAL 90 DAY);
OPTIMIZE TABLE vicidial_log;
OPTIMIZE TABLE vicidial_closer_log;
"
# Report on campaign performance
mysql -u root -p asterisk -e "
SELECT
campaign_id,
DATE(call_date) as date,
COUNT(*) as total_calls,
SUM(CASE WHEN call_result='SALE' THEN 1 ELSE 0 END) as sales,
SUM(CASE WHEN call_result='DROPPED' THEN 1 ELSE 0 END) as dropped,
ROUND(SUM(CASE WHEN call_result='DROPPED' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) as drop_rate_percent
FROM vicidial_log
WHERE call_date > DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY campaign_id, DATE(call_date)
ORDER BY campaign_id, date DESC;
" > /var/log/vicidial_daily_report.txt
Schedule in crontab:
crontab -e
# Add:
0 2 * * * /usr/local/bin/vicidial_maintenance.sh > /dev/null 2>&1
Summary
This tutorial covered the complete setup and tuning of ViciDial's three auto-dial modes:
Predictive Dialing provides the highest contact rate and throughput by predicting agent availability and dialing ahead. Ideal for high-volume campaigns where some call drops are acceptable. Requires careful monitoring of drop rates and CPU usage.
Ratio-Based Dialing maintains fixed dial multipliers (e.g., 3:1) per available agent. More predictable than predictive; suitable for mid-range campaigns. Requires less tuning but achieves lower contact rates than predictive.
Progressive Dialing offers zero abandonment by requiring manual agent dial actions. Best for compliance-heavy environments and new campaigns. Maximizes agent control but minimizes throughput.
Key implementation steps:
- Create campaigns and leads in the asterisk database
- Configure SIP carriers and Asterisk dialplan
- Enable the vicidial_dialer.pl background service
- Set auto_dial_level, drop_percentage, and dial_timeout per mode
- Optimize database indexes and Asterisk channel limits
- Monitor via SQL queries, Asterisk CLI, and real-time dashboards
- Troubleshoot using logs, database diagnostics, and SIP peer status checks
- Maintain via regular backups, log rotation, and performance reports
Production deployments benefit from starting conservative (lower dial rates, higher drop thresholds) and gradually increasing intensity while monitoring agent satisfaction, call quality, and network capacity. Always maintain backups and test configuration changes in a staging environment first.
For enterprise setups, consider implementing load balancing across multiple ViciDial servers and using dedicated trunk capacity with your carrier to ensure reliable, scalable operation.