← All Tutorials

ViciDial LAGGED agents: root cause analysis and debugging

Monitoring & Observability Intermediate 17 min read #100 Published

Agents stuck in LAGGED status show no calls, drop inbound traffic, and fail to reconnect: identify the socket, session, and database state causing the freeze in under five minutes.

LAGGED status means the agent's web session has disconnected from the Asterisk realtime socket or the ViciDial telephony daemon (ViciDial_Agent.pl) has lost the agent's active record. The agent appears logged in but receives no calls. The fix depends on which layer broke: kill the hung PHP session, restart the daemon, force a database update, or rebuild the SIP channel registration. Most LAGGED events trace to session timeout, daemon memory leak, or a stale vicidial_live_agents row with no matching active call context in Asterisk.

Tested on ViciDial 2.14 (SVN 3555+), Asterisk 16/18, MariaDB 10.5+, with Apache 2.4 and PHP 7.4.

Prerequisites

What "LAGGED" means in ViciDial

An agent in LAGGED status has lost the real-time bidirectional link between their web browser (the agent screen) and the ViciDial backend processes. The agent's record exists in the vicidial_live_agents table, and their PHP session file still exists on disk, but the websocket or TCP connection that carries call events, caller ID, and disposition codes has timed out or been killed.

When LAGGED, the agent sees no incoming calls in the dialpad, cannot click buttons to accept or reject calls, and the admin reports show no active calls for that extension. Meanwhile, the ViciDial_Agent.pl daemon cannot locate the agent's session state and either ignores new inbound calls or routes them to a fallback destination (voicemail, IVR, or another agent).

The customer experience: dial an advertised number, wait on hold, hear silence, and disconnect when the LAGGED agent's queue times out.

Prerequisites for investigation

Before you start, gather:

  1. The agent's vicidial_user account name and assigned extension
  2. The timestamp when LAGGED was first observed (from web admin or agent report)
  3. The server hostname and any load balancer address
  4. Recent /var/log/asterisk/messages lines around that time
  5. The agent's assigned campaign, dial method, and call list

How to identify which agents are LAGGED

Log into the ViciDial admin web interface at /vicidial/admin.php (or direct to /vicidial/admin/users.php). In the "Active Agents" or "Realtime Agents" panel, any agent showing LAGGED in the "Status" column is disconnected.

Alternatively, query the database directly:

SELECT vicidial_user, status, last_update, calls_today, extension FROM vicidial_live_agents WHERE status = 'LAGGED' ORDER BY last_update DESC;

The last_update timestamp tells you how long they have been stuck. If last_update is more than 5 minutes old, the connection was lost well before the current time.

Also check for orphaned SIP channels on the Asterisk side:

asterisk -rx "sip show channels" | grep -i "SIP/vicidial"

If you see SIP/vicidial-XXXX channels with no matching agent in vicidial_live_agents or with a LAGGED status, that channel is orphaned and likely wasting memory.

Layer 1: PHP session and web connection diagnostics

The first layer to investigate is the agent's web session (the PHP session file on disk and the HTTP/WebSocket connection to the browser).

Why do PHP sessions expire and trigger LAGGED status?

A PHP session is a file stored on disk (usually in /var/lib/php/sessions or /tmp) that holds the agent's login state, assigned call lists, and campaign parameters. ViciDial web scripts check this file on every page load. If the session file is missing or corrupted, or if the browser tab closes without sending a "log out" message, the next refresh will prompt a re-login.

Some agent browsers sit idle. After 10 to 30 minutes with no requests, Apache or PHP may close the connection. When the agent tries to click a button or open a new screen, the request fails because there is no active session. The ViciDial backend then receives no updates and assumes the agent has disconnected.

Check for active PHP sessions for a specific user

SSH to the ViciDial server. List the session files for the target user:

ls -la /var/lib/php/sessions/ | grep -i "$(grep -h vicidial_user /var/www/html/vicidial.php 2>/dev/null || echo '__')"

A more direct approach: query the process list to find the agent's browser session:

ps auxww | grep "[a]gent"

Look for PHP-CGI or Apache worker processes labeled with the agent's user account or session ID.

To dump the session file and check its contents:

cat /var/lib/php/sessions/sess_<SESSION_ID_HERE>

You will see serialized PHP data. Check that vicidial_user, user_id, and extension are present. If the file is empty or contains only a timestamp, the session is dead.

Force an agent to re-login by clearing their session

If you determine a session is corrupted, delete it:

rm -f /var/lib/php/sessions/sess_<SESSION_ID_HERE>

Tell the agent to refresh their browser. They will be asked to log in again. Once logged in, a new session file will be created and the agent should no longer show LAGGED.

Layer 2: ViciDial daemon socket and memory state

The second layer is the ViciDial_Agent.pl daemon, which runs on the server and holds an in-memory copy of every active agent's state: their status (READY, PAUSED, INCALL), assigned phone, SIP extension, and the file descriptor for their socket connection.

Does the ViciDial daemon have the agent in memory?

Connect to the ViciDial admin port (default 6100, configurable in /etc/asterisk/asterisk.conf or vicidial.conf) using telnet or a custom admin tool:

telnet localhost 6100

You will get a ViciDial command prompt. Use the STATUS command to list all active agents:

STATUS

Press Enter. The daemon will print a line for each agent in memory. Look for your target agent's extension or username. If you do not see it, the daemon has no record of that agent, and the agent must re-login to be re-registered.

If the agent appears in the STATUS output, note their assigned handler process ID and socket number. This tells you the daemon thinks they are still active.

Exit telnet by typing QUIT or Ctrl+D.

Check the ViciDial daemon logs

The ViciDial_Agent.pl daemon logs to a dedicated file, usually /var/log/ViciDial_Agent.log or /var/log/asterisk/ViciDial_Agent.log (depends on the installation). Tail the last 100 lines and search for the agent's extension:

tail -100 /var/log/ViciDial_Agent.log | grep -i "extension_XXXX"

Look for socket timeout warnings or "closing connection" messages near the timestamp when the agent went LAGGED.

If you see messages like "Socket timeout on extension XXXX after 300 seconds", the daemon closed the connection because no keep-alive packet arrived from the browser in 5 minutes. This is a sign that the browser is not polling the server or has lost network connectivity.

Restart the ViciDial daemon

If the daemon is consuming excessive memory or has accumulated stale agent records, restart it:

sudo systemctl restart ViciDial_Agent

or

sudo /etc/init.d/ViciDial_Agent restart

Restarting will drop all agent sessions. All agents logged in will be disconnected and must log back in. Coordinate this restart during a low-traffic period.

To restart without killing agents: edit the daemon config to reduce socket timeout from 300 seconds to 30 seconds, then tell the daemon to reload:

sudo kill -HUP $(pidof ViciDial_Agent.pl)

This tells the daemon to reread config. However, this does not drop existing agent connections.

Layer 3: ViciDial_live_agents database state

The third layer is the vicidial_live_agents table, which is the source of truth for which agents are currently logged in. Each row represents one active agent session. When an agent logs in, a row is inserted. When they log out, the row is deleted. If the row exists but the corresponding daemon socket and PHP session are gone, the agent is LAGGED.

Inspect the agent row in vicidial_live_agents

Query the table for the agent in question:

SELECT 
  vicidial_user,
  user_id,
  extension,
  status,
  last_update,
  lead_id,
  calls_today,
  session_id,
  server_ip
FROM vicidial_live_agents
WHERE vicidial_user = 'AGENT_USERNAME_HERE'
LIMIT 1;

Note the values:

Force-update the agent to PAUSED to clear LAGGED

If the database row is stale but the agent is still in the browser, you can force the status to PAUSED without deleting the row:

UPDATE vicidial_live_agents
SET status = 'PAUSED', last_update = NOW()
WHERE vicidial_user = 'AGENT_USERNAME_HERE';

The agent's browser should detect the change and refresh their dialpad. If they remain LAGGED after this, the browser has no active connection to the server.

Delete the agent row to force re-login

If the agent is truly stuck, delete their row from vicidial_live_agents:

DELETE FROM vicidial_live_agents
WHERE vicidial_user = 'AGENT_USERNAME_HERE';

The agent will be logged out immediately. Have them log back in. A new row will be inserted, a new PHP session created, and the daemon will re-register them.

Be careful: if the agent is currently on a call, deleting their row will orphan the call and may charge you for a call that never completed properly.

Layer 4: Asterisk SIP channel and state

The fourth layer is Asterisk itself and the SIP channels registered for the agent's extension.

List SIP channels for an agent extension

Ask for all active SIP channels:

asterisk -rx "sip show channels"

Output will resemble:

Peer             User/ANR    Call ID              Duration Recv-Q Lost %   Jitter FromTag
SIP/1001-00000ab agent1      sip:[email protected]    00:02:35    0    0    0.0   12345abc
SIP/1002-00000ac agent2      sip:[email protected]    00:00:15    0    0    0.0   67890def

Look for the agent's extension (e.g., 1001). If you see one channel, they are logged in and Asterisk knows about them. If you see zero or multiple stale channels, that is a clue.

Check the SIP peer registration for the agent

asterisk -rx "sip show peers" | grep -i "1001"

If the peer is listed as "OK" with a recent "Refresh" timestamp, the registration is active. If it shows "UNREACHABLE" or has not refreshed in more than 5 minutes, the phone or endpoint is not responding to SIP REGISTER packets.

Dump a SIP channel state

If you need to see detailed state for a specific channel:

asterisk -rx "sip show channel SIP/1001-00000ab"

This will print codec negotiation, RTP ports, and any pending transactions.

Force Asterisk to reload SIP config

If you edited sip-vicidial.conf or extensions-vicidial.conf, reload without restarting:

asterisk -rx "sip reload"
asterisk -rx "dialplan reload"

Reloading will drop any active SIP channels. Agents will need to re-register.

Layer 5: Real-time state via Asterisk AMI and ViciDial logs

The fifth layer is the Asterisk Manager Interface (AMI), which is the real-time API that ViciDial uses to monitor call state. If AMI is not connected or is lagging, the ViciDial daemon cannot see call events and will mark agents as LAGGED incorrectly.

Check if AMI is running and connected

asterisk -rx "manager list connected"

You should see lines listing connected clients. Look for "vicidial" or "ViciDial" in the client list. If there are zero connections or the connection is very old, the daemon is not talking to Asterisk.

Restart the AMI connection by restarting the daemon:

sudo systemctl restart ViciDial_Agent

Tail the Asterisk full log for AMI errors

tail -50 /var/log/asterisk/full | grep -i "ami\|manager"

Look for connection refused, socket timeout, or authentication error messages. If AMI failed to authenticate, check the manager.conf file:

cat /etc/asterisk/manager.conf | grep -A5 "^\\[vicidial\\]"

Ensure the username and password match what is configured in the ViciDial daemon (usually in /etc/asterisk/vicidial.conf or hard-coded in ViciDial_Agent.pl). If they do not match, the daemon cannot connect and all agents will eventually go LAGGED.

Troubleshooting

Symptom: Agent goes LAGGED within 2 minutes of login

Check the Apache access and error logs:

tail -50 /var/log/apache2/access.log | grep -i "vicidial.php"
tail -50 /var/log/apache2/error.log

If you see 502 Bad Gateway or 503 Service Unavailable, the PHP backend is crashing or overloaded. Restart Apache:

sudo systemctl restart apache2

If PHP crashes again immediately, increase the memory limit in /etc/php/7.4/cgi/php.ini:

memory_limit = 512M

Restart Apache and test again.

Symptom: All agents are LAGGED after a reboot

The ViciDial daemon may not have started. Check if it is running:

ps auxww | grep ViciDial_Agent

If not running, start it manually:

sudo systemctl start ViciDial_Agent

If it fails to start, check the daemon log for startup errors:

tail -20 /var/log/ViciDial_Agent.log

Common startup errors: MySQL connection refused (check if MySQL is running), missing Perl modules (run CPAN or apt install), or stale PID file. Delete a stale PID and retry:

sudo rm -f /var/run/ViciDial_Agent.pid
sudo systemctl start ViciDial_Agent

Symptom: Agents are LAGGED but PhoneType is listed as "NONE"

Check the vicidial_users table. The user may not have a phone device assigned:

SELECT vicidial_user, phone_type, phone_number FROM vicidial_users WHERE vicidial_user = 'AGENT_USERNAME_HERE';

If phone_type is "NONE" or NULL, the agent cannot register a SIP extension. Edit the user record in the web admin and assign a phone type (typically "SIP" for soft phones). Reload SIP and have the agent re-login.

Symptom: LAGGED agents reappear when the web server restarts

Check if /var/lib/php/sessions has sufficient disk space:

df -h /var/lib/php/sessions

If free space is less than 5%, sessions may be getting garbage-collected. Clean up old session files:

find /var/lib/php/sessions -type f -mtime +7 -delete

Then expand the session storage device if possible. Also increase PHP session.gc_maxlifetime in php.ini to match ViciDial's timeout (usually 14400 seconds, 4 hours):

session.gc_maxlifetime = 14400

Symptom: One or two agents are LAGGED, but most others are fine

This is usually a network issue on the agent's side. Have the agent:

  1. Reload the browser tab (Ctrl+F5 or Cmd+Shift+R to bypass cache).
  2. Check their local IP and firewall. Ping the server.
  3. Try a different browser or device if possible.
  4. Check if they are on a corporate proxy or VPN that is blocking websockets or long-polling.

If the issue persists only for that agent, restart their session in the database as described in "Force an agent to re-login by clearing their session" above.

Frequently asked questions

Why does an agent see READY status in the dialpad but show LAGGED in the admin console?

The agent's PHP session is active, so their browser shows READY because it has a cached version of the status. However, the last_update timestamp in vicidial_live_agents is stale, so the admin console shows LAGGED. The web connection is asymmetrical: the browser is still making requests (keeping PHP alive), but the server is not receiving websocket push events or the polling frequency has dropped so low that real-time synchronization is lost. Force a refresh of the agent screen (Ctrl+F5) to resync. If the issue persists, delete the database row and have the agent re-login.

Can I write a cron job to auto-clear LAGGED agents?

Yes, but do so cautiously to avoid interrupting real calls. Create a cron script that runs every 5 minutes and updates any agent whose last_update is older than 5 minutes to PAUSED, then check again after 10 minutes to see if they reconnect. If they remain PAUSED after 15 minutes, delete the row. Example shell loop (place in /usr/local/bin/clear_lagged.sh):

#!/bin/bash
mysql -e "UPDATE vicidial_live_agents SET status = 'PAUSED' WHERE status = 'LAGGED' AND last_update < DATE_SUB(NOW(), INTERVAL 5 MINUTE);"
sleep 600
mysql -e "DELETE FROM vicidial_live_agents WHERE status = 'PAUSED' AND last_update < DATE_SUB(NOW(), INTERVAL 15 MINUTE) AND calls_today = 0;"

Schedule it with crontab -e:

*/10 * * * * /usr/local/bin/clear_lagged.sh

This runs every 10 minutes. Adjust the 5 and 15 minute thresholds to suit your environment. Always test in a staging environment first.

Is LAGGED the same as a dropped call or a no-answer?

No. LAGGED is an agent state, not a call result. A call can have a LAGGED agent and still be transferred, dropped, or forwarded depending on the dial plan. A LAGGED agent cannot answer new calls or adjust their status, but calls already connected to that extension will remain connected until one party hangs up. However, new inbound calls will not ring that agent, so they will not see them in their dialpad and cannot click to accept them.

What causes LAGGED if the agent is sitting idle in the dialpad?

Agents who do not interact with the web page for more than 10 minutes typically lose their polling connection. The browser is still running, but no new HTTP requests are being sent, so the server's keep-alive timer expires and the backend marks them LAGGED. To prevent this, configure a JavaScript keep-alive in the dialpad (ViciDial usually includes this), or reduce the polling timeout in the browser settings. Some deployments use websockets instead of polling to avoid this, but websockets require additional server-side support and can consume more memory per agent.

If I delete a LAGGED agent row from the database, what happens to their active call?

If the agent is not actually on an active call, nothing happens. If they are on a call (lead_id is not null), the call remains connected at the Asterisk level, but the agent's record is gone. The call will not be logged properly in vicidial_log because the agent record is not there to supply user_id and other context. The call will show up as orphaned or with a null user_id. Always check the lead_id field before deleting:

SELECT vicidial_user, lead_id, status FROM vicidial_live_agents WHERE vicidial_user = 'AGENT_USERNAME_HERE';

If lead_id is a positive number, the agent is on a call. In that case, do not delete the row. Instead, try the force-update to PAUSED method first.

Summary

A LAGGED agent is disconnected at the web session, daemon socket, or database level, despite an apparently logged-in record. Investigation starts with the PHP session file and browser connectivity, then moves to the ViciDial daemon's in-memory state and the vicidial_live_agents table, and finally checks Asterisk SIP registration and AMI connectivity.

Standard fixes are:

  1. Delete the agent's PHP session file and ask them to re-login.
  2. Restart the ViciDial daemon if it is consuming excessive memory or has lost AMI connection.
  3. Update or delete the stale row in vicidial_live_agents.
  4. Reload SIP configuration if the agent extension is not registering properly.

To avoid LAGGED in the future: reduce session timeout in PHP and the daemon to match your environment, use keep-alive pings in the dialpad, monitor vicidial_live_agents for stale rows, and ensure the daemon can always reach Asterisk AMI without blocking. Regular log review of /var/log/ViciDial_Agent.log and /var/log/asterisk/messages will catch most issues before they affect more than one agent.

Stuck on something specific?

Book a free 30-minute call. I run ViciDial centers across 3 countries and can usually unblock your setup in one session — or build it for you.

Book a Free Consultation