Data Cleaning
This guide explains how VoIPmonitor manages data retention for both captured packets (PCAP files) and Call Detail Records (CDRs) in the database. Proper configuration is essential for managing disk space and maintaining long-term database performance.
Overview
VoIPmonitor generates two primary types of data that require periodic cleaning:
- PCAP Files: Raw packet captures of SIP/RTP/GRAPH data stored on the filesystem in the spool directory. These can consume significant disk space.
- CDR Data: Call metadata stored in the MySQL database. Large tables can slow down GUI performance if not managed properly.
The system uses two separate, independent mechanisms to manage the retention of this data:
Filesystem Cleaning (PCAP Spool Directory)
The sensor stores captured call data in a structured directory tree on the local filesystem.
Reducing Data Collection at Source
Before configuring cleanup policies, consider reducing the amount of data captured. This is often the most effective long-term solution for storage management.
Save Only RTP Headers (Major Space Saver)
RTP packets typically contain the full audio payload, which consumes the majority of disk space. If you only need call quality statistics (MOS, jitter, packet loss) and not actual audio playback, switch to saving RTP headers only.
Edit /etc/voipmonitor.conf:
# Change from full RTP to headers only
savertp = header
| Setting | Storage Impact | Use Case |
|---|---|---|
savertp = yes |
High (~10x more) | Requires ability to play back audio from PCAPs |
savertp = header |
Low | Only CDR statistics needed, no audio playback required |
With savertp = header, VoIPmonitor still captures all necessary metadata for MOS scoring, jitter analysis, packet loss statistics, and quality graphs, but does not store the actual audio payload. This can reduce storage consumption by up to 90%.
Important: After changing from savertp = yes to savertp = header, existing PCAP files will remain playable. New calls will only contain RTP headers.
| Critical: Distributed Architecture Consideration | |||||||
|---|---|---|---|---|---|---|---|
packetbuffer_sender Architecture:
|
If you are using the Packet Mirroring/Client-Server mode (
For distributed deployment details, see Client-Server Architecture. | ||||||
For more configuration options, see Sniffer Configuration - Saving Options.
Spool Directory Location
By default, all data is stored in /var/spool/voipmonitor. This location can be changed by setting the spooldir option in voipmonitor.conf.
Relocating the Spool Directory to a Different Partition
If your default partition is running out of space, you can move the spool directory to a larger partition or dedicated disk. This is particularly useful when MySQL Error 28 ("No space left on device") occurs despite retention settings being in place.
| Situation | Recommended Action |
|---|---|
/var/lib/mysql full but other partitions available |
Move spool to larger partition and update spooldir in voipmonitor.conf
|
| Multiple disks available | Use dedicated partition for PCAP storage |
| GUI on same server | Sync GUI SNIFFER_DATA_PATH to match new spooldir
|
Procedure to Relocate Spooldir
- Step 1
- Identify Available Space
Check all partitions to find a suitable location:
df -h
- Step 2
- Create New Spool Directory
Create the directory on the destination partition:
# Example: Use /mnt/pcaps partition
mkdir -p /mnt/pcaps/voipmonitor
# Set correct ownership for both sniffer and GUI access
chown voipmonitor:voipmonitor /mnt/pcaps/voipmonitor
chmod 755 /mnt/pcaps/voipmonitor
- Step 3
- Update VoIPmonitor Configuration
Edit /etc/voipmonitor.conf to point to the new location:
[general]
spooldir = /mnt/pcaps/voipmonitor
- Step 4
- Update GUI Configuration (Critical)
If the GUI runs on the same server, you MUST update the path the GUI uses to access the spool. This is defined in the GUI configuration file:
- Debian/Ubuntu:
/var/www/html/voipmonitor/config/configuration.php - RHEL/CentOS:
/var/www/voipmonitor/config/configuration.php
Edit the GUI configuration file:
// Find and update this line to match your new spooldir
define('SNIFFER_DATA_PATH', '/mnt/pcaps/voipmonitor');
Important: The SNIFFER_DATA_PATH in the GUI config MUST match the spooldir setting in voipmonitor.conf. If these are mismatched, the GUI will be unable to locate and display call recordings.
- Step 5
- Restart Services
Apply all changes by restarting the services:
# Restart the VoIPmonitor sensor
systemctl restart voipmonitor
# If using Apache/Nginx, reload web server
systemctl reload apache2 # Debian/Ubuntu
# or
systemctl reload nginx # RHEL/CentOS
- Step 6
- Verify Configuration
# Check if new spool directory is being used
ls -ld /mnt/pcaps/voipmonitor
# Verify GUI can access the path
grep SNIFFER_DATA_PATH /path/to/gui/config/configuration.php
# Check sensor logs for any spool-related errors
tail -f /var/log/voipmonitor.log
Optional: Move Existing Data
If you want to migrate existing PCAP files to the new location:
# Stop the sensor to prevent writes during migration
systemctl stop voipmonitor
# Move existing data (this may take a long time)
mv /var/spool/voipmonitor/* /mnt/pcaps/voipmonitor/
# Restart the sensor
systemctl start voipmonitor
Retention Configuration
The cleaning process runs automatically every 5 minutes and removes the oldest data based on the rules you define in voipmonitor.conf. You can set limits based on total size (in Megabytes) or age (in days). If both a size and day limit are set for the same data type, the first limit that is reached will trigger the cleaning.
| Parameter | Default Value | Description |
|---|---|---|
maxpoolsize |
102400 (100 GB) | The total maximum disk space for all captured data (SIP, RTP, GRAPH, AUDIO). |
maxpooldays |
(unset) | The maximum number of days to keep all captured data. |
maxpoolsipsize |
(unset) | A specific size limit for SIP PCAP files only. |
maxpoolsipdays |
(unset) | A specific age limit for SIP PCAP files only. |
maxpoolrtpsize |
(unset) | A specific size limit for RTP PCAP files only. |
maxpoolrtpdays |
(unset) | A specific age limit for RTP PCAP files only. |
maxpoolgraphsize |
(unset) | A specific size limit for GRAPH files only. |
maxpoolgraphdays |
(unset) | A specific age limit for GRAPH files only. |
maxpoolaudiosize |
(unset) | A specific size limit for converted audio files (WAV/OGG) only. |
maxpoolaudiodays |
(unset) | An age limit for converted audio files (WAV/OGG) only. |
Understanding Directory Size Differences (SIP vs RTP Retention)
If you configure different retention periods for SIP and RTP data (for example, maxpoolsipdays = 90 and maxpoolrtpdays = 30), you will notice a significant size difference between directories within different time windows.
| Age of Directory | Contents | Size |
|---|---|---|
| 0-30 days | Both SIP and RTP PCAP files | Large |
| 30-90 days | SIP PCAP files only (RTP deleted) | Smaller |
| 90+ days | None (both SIP and RTP deleted) | Empty or absent |
This behavior is expected and by design:
- Directories within the
maxpoolrtpdaysretention window contain both SIP and RTP data, making them significantly larger (often 5-10x larger). - Directories older than
maxpoolrtpdaysbut withinmaxpoolsipdayscontain only SIP data, so they are much smaller. - The automatic cleanup process removes RTP files after
maxpoolrtpdaysand SIP files aftermaxpoolsipdays.
This is not an error or configuration issue. It is the expected result of having different retention periods for different data types.
Diagnosis: Compare Directory Sizes
To verify this behavior, check your spool directory:
cd /var/spool/voipmonitor
# Show directories sorted by size
du -h --max-depth=1 ./ | sort -rh | head -20
# Example output:
# 80G ./2025-01 # Current month (has SIP+RTP)
# 15G ./2024-12 # Previous month (SIP only, RTP deleted)
# 120G .
Compare with your configuration:
grep -E "maxpoolsip|maxpoolrtp" /etc/voipmonitor.conf
# Example configuration:
# maxpoolsipdays = 90 # SIP kept for 90 days
# maxpoolrtpdays = 30 # RTP kept for 30 days
If the size difference matches your retention configuration, this is expected behavior and no action is needed.
Troubleshooting: Disk Full / Files Disappearing
If you see errors when attempting to extract older calls from the GUI, or if call files are disappearing too quickly, your spool directory may have reached its size limit.
Diagnosis: Check Disk Usage
- Identify the sensor/probe responsible for the missing data.
- SSH into the sensor/probe and navigate to the spooldir.
- Check the disk usage:
cd /var/spool/voipmonitor
du -h --max-depth=1 ./
# Example output:
# 150G ./2025-01
# 120G ./2024-12
# 90G ./2024-11
# 360G .
- Compare with the configured limit:
grep maxpoolsize /etc/voipmonitor.conf
# Example output: maxpoolsize = 102400 (100 GB in MB)
Resolution: Increase Spooldir Size
If the actual usage exceeds the configured limit, increase maxpoolsize:
# Edit /etc/voipmonitor.conf
[general]
maxpoolsize = 716800 # 700 GB in MB
maxpooldays = 90 # Optional: Keep data for last 90 days
Apply changes:
systemctl restart voipmonitor
Emergency Cleanup Triggers
Even when your maxpooldays setting appears correct, PCAP files may still be deleted prematurely due to emergency cleanup triggers. These are safety mechanisms that override normal retention settings to prevent system crashes from disk exhaustion.
| Common Cause: Retention Not Working as Expected | |
|---|---|
| Symptom: | You set maxpooldays = 60, but files are deleted after 2 weeks (14 days).
|
| Root Cause: | Emergency cleanup triggered by autocleanspoolminpercent or autocleanmingb.
|
Emergency cleanup is activated when either of these conditions is met:
| Parameter | Default | Description | Behavior |
|---|---|---|---|
autocleanspoolminpercent |
1 | When the partition reaches this threshold (e.g., 99% full), aggressive cleaning starts immediately regardless of maxpooldays setting.
| |
autocleanmingb |
5 | When free space falls below this value (e.g., less than 5 GB left), emergency cleaning is triggered. |
How Emergency Cleanup Works
The cleaning process checks disk space before each operation:
# Check current disk usage
df -h /var/spool/voipmonitor
# Example output:
# Filesystem Size Used Avail Use% Mounted on
# /dev/sdb1 2.0T 1.96T 40G 98% /var/spool/voipmonitor
If Use% exceeds 100 - autocleanspoolminpercent (e.g., 99%), emergency cleanup is triggered.
Emergency cleanup behavior:
- Files are deleted starting from the oldest until the emergency threshold is cleared
- This happens regardless of your
maxpooldaysormaxpoolsizesettings - The normal cleaning cycle (every 5 minutes) is triggered immediately
- Once the threshold is cleared, normal retention rules resume
Diagnosis: Check Emergency Cleanup Triggers
# Check if emergency triggers are set
grep -E "autocleanspoolminpercent|autocleanmingb" /etc/voipmonitor.conf
# Check current disk usage
df -h /var/spool/voipmonitor
# Check available space on the partition
# If Avail is close to autocleanmingb (5GB), emergency cleanup may be triggering
Resolution: Adjust Emergency Triggers or Increase Disk Space
If emergency cleanup is causing premature deletion, you have two options:
- Option 1
- Adjust Emergency Triggers
Increase the thresholds to allow more data before emergency cleanup triggers:
# Edit /etc/voipmonitor.conf
[general]
maxpooldays = 60
# Reduce emergency sensitivity (allow partition to fill more before trigger)
autocleanspoolminpercent = 5 # Default is 1, increase to 5 to allow 95% usage
autocleanmingb = 20 # Default is 5, increase to 20 GB
Apply changes:
systemctl restart voipmonitor
- Option 2
- Increase Disk Space
If the partition is genuinely full, add more storage or move the spooldir to a larger partition (see Relocating Spooldir).
Example Troubleshooting Scenario
User report: "I set maxpooldays = 60 for 60-day retention, but PCAPs are deleted after only 14 days."
Investigation:
# 1. Check retention settings
grep maxpooldays /etc/voipmonitor.conf
# maxpooldays = 60 ✓ Correct
# 2. Check disk usage
df -h /var/spool/voipmonitor
# Filesystem Size Used Avail Use% Mounted on
# /dev/sdb1 500G 498G 2G 99.6% /var/spool/voipmonitor
# 3. Check emergency triggers
grep autoclean /etc/voipmonitor.conf
# autocleanspoolminpercent = 1 (default)
# autocleanmingb = 5 (default)
Root Cause:
- Partition is 99.6% full, which exceeds the 99% threshold (100 - 1)
- Only 2 GB free space remains, below the 5 GB
autocleanmingblimit - Emergency cleanup triggers, deleting files until at least 5 GB is free
Solution:
- Increase
autocleanspoolminpercent = 5to allow 95% usage before emergency trigger - Or increase
autocleanmingb = 20to allow more data before cleanup - Or add more disk space to the partition
For the complete parameter reference, see Sniffer Configuration - Spool Cleaning.
Troubleshooting: Missing Data Due to NFS/Storage Server Issues
If you are using a remote storage solution (NFS, SSHFS, or other network-mounted filesystem) for the spool directory, missing CDRs, PCAP files, or gaps in data for specific time periods may be caused by network connectivity issues between the VoIPmonitor probe and the storage server, rather than data deletion policies.
| Root Cause: Storage Server Connectivity Problems | |
|---|---|
| Symptoms: | Missing CDRs and PCAP files for specific time periods despite retention settings being correct. No deletion-related logs from emergency cleanup or retention policies. |
| Common causes: | Network interruptions between probe and NFS server, NFS server timeouts, storage server not responding during the missing data period. |
Step 1: Check System Logs for NFS Errors
Examine the system logs on the VoIPmonitor probe for NFS-specific error messages around the time of the missing data.
# Check systemd journal for voipmonitor service
journalctl -u voipmonitor --since "YYYY-MM-DD HH:MM:SS" --until "YYYY-MM-DD HH:MM:SS"
# Check system logs for NFS errors
grep -i "nfs" /var/log/syslog | grep "not responding\|timed out"
# Also check dmesg and kernel logs
dmesg | grep -i "nfs"
Look for specific NFS error messages:
nfs: server [IP_ADDRESS] not responding, timed outnfs: server [IP_ADDRESS] OK(indicates the connection recovered)Input/output errorwhen accessing the spool directory
If you see these errors during the time period where data is missing, the probe was unable to write to the storage server, resulting in lost data.
Step 2: Verify Network Connectivity
Test network connectivity between the VoIPmonitor probe and the NFS storage server.
# Test basic connectivity
ping nfs-server.example.com
# Test with packet loss detection
ping -c 100 nfs-server.example.com
# Trace the network path
traceroute nfs-server.example.com
# Check if NFS port is reachable (NFS typically uses port 2049)
nc -zv nfs-server.example.com 2049
Pay attention to:
- High packet loss or latency (intermittent connectivity)
- Route failures or timeouts in traceroute
- Firewall blocking the NFS port
Step 3: Verify NFS Server Status
Ensure the NFS server is running and accessible during the period when data collection should occur.
# From the probe, check if NFS share is mounted
mount | grep nfs
# Check mount status for specific mount point
mountpoint -q /var/spool/voipmonitor
# Test write access to NFS mount
touch /var/spool/voipmonitor/.test_write && rm /var/spool/voipmonitor/.test_write
If the mount is stale (the NFS server went down and came back), you may need to remount:
# Unmount and remount (caution: this may affect active writes)
umount /var/spool/voipmonitor
mount /var/spool/voipmonitor
# Or use lazy unmount if needed (only if safe to interrupt)
umount -l /var/spool/voipmonitor
mount /var/spool/voipmonitor
Step 4: Investigate Network Infrastructure
Common causes of intermittent NFS connectivity issues:
- Network equipment: Switch or router problems between probe and NFS server
- Network congestion: High traffic loads causing packet loss
- Firewall rules: Intermittent blocking of NFS ports
- NFS server load: Storage server overloaded and unable to respond
Work on these issues with your network administrator:
- Verify network stability with continuous monitoring tools
- Check switch logs for errors or port flapping
- Review firewall rules for NFS traffic (port 2049 TCP, plus RPC ports)
- Monitor NFS server performance and load
Step 5: Mitigation Strategies
To prevent future data loss due to NFS connectivity issues:
- Use local spool where possible: Store PCAPs locally and use VoIPmonitor Client-Server mode to send CDRs to a central server, rather than depending on NFS for real-time writes.
- Implement network monitoring: Set up alerts for NFS server availability and network packet loss.
- Consider dedicated storage: Use a storage solution designed for high availability and continuous access.
- NFS mount options: For improved reliability, consider adding NFS mount options like
soft,timeo=50,retrans=3for faster timeout detection, though this may result in some I/O errors being reported earlier.
For local storage instead of NFS, see the Relocating Spooldir and Distributed Architecture guides.
Troubleshooting: Configuration Not Applied (GUI Override)
If your voipmonitor.conf file shows cleanspool = yes but cleaning is still not running, the setting may be overridden by GUI-based configuration.
| Common Cause: GUI Settings Override File Configuration | |
|---|---|
| Symptom: | Configuration set correctly in /etc/voipmonitor.conf (e.g., cleanspool = yes) but the setting is not taking effect.
|
| Root Cause: | mysqlloadconfig = yes (default) loads configuration from the sensor_config database table, which stores GUI settings. These GUI settings override file-based configuration.
|
How Configuration Priority Works
When mysqlloadconfig is enabled (which is the default), VoIPmonitor applies configuration in this order:
| Priority | Source | Description |
|---|---|---|
| 1 (Highest) | GUI Settings | sensor_config database table, configured via Settings > Sensors > wrench icon
|
| 2 (Medium) | Database | Values stored in database but not GUI-managed |
| 3 (Lowest) | /etc/voipmonitor.conf |
File-based configuration (only used if not set elsewhere) |
If a parameter is set in the GUI (sensor_config table), it will override the same parameter in voipmonitor.conf. The file is effectively ignored for that specific parameter.
Diagnosis: Check for GUI Configuration Override
# 1. Check if mysqlloadconfig is enabled
grep mysqlloadconfig /etc/voipmonitor.conf
# Should show: mysqlloadconfig = yes (this is the default)
# 2. Check your file-based cleanspool setting
grep cleanspool /etc/voipmonitor.conf
# Should show: cleanspool = yes
# 3. Verify sensor configuration in GUI
# Navigate to GUI > Settings > Sensors and click the wrench icon for your sensor
# Search for "cleanspool" in the sensor settings dialog
If the GUI shows cleanspool set to a different value than your config file, the GUI setting is being used.
Resolution Options
You have three ways to resolve this conflict:
- Option 1
- Update via GUI (Recommended)
Fix the configuration in the GUI where the sensor stores its settings:
- Log in to the VoIPmonitor GUI
- Navigate to Settings > Sensors
- Click the wrench icon for the sensor
- In the search field, type
cleanspool - Set
cleanspooltoyes - Save the changes (GUI writes to
sensor_configdatabase table)
- Option 2
- Disable Database Configuration
Disable mysqlloadconfig to rely entirely on file-based configuration:
# Edit /etc/voipmonitor.conf
[general]
# Disable loading config from database
mysqlloadconfig = no
Apply changes:
systemctl restart voipmonitor
Note: With mysqlloadconfig = no, GUI sensor settings will no longer apply. You must configure everything in voipmonitor.conf.
- Option 3
- Remove Conflicting Database Entry
Manually remove the conflicting setting from the database:
-- Connect to voipmonitor database
mysql -u root -p voipmonitor
-- Check current sensor_config entries
SELECT * FROM sensor_config WHERE name = 'cleanspool';
-- Delete the conflicting entry (this falls back to voipmonitor.conf)
DELETE FROM sensor_config WHERE name = 'cleanspool';
-- Verify the deletion
SELECT * FROM sensor_config WHERE name = 'cleanspool';
Apply changes:
# Either restart the sensor or use GUI reload button
systemctl restart voipmonitor
Why This Happens
The GUI's GUI sensor configuration feature allows administrators to manage sensor settings without editing config files. When you save settings via Settings > Sensors > wrench icon, the GUI writes those values to the sensor_config table. The sensor reads these table values first before checking voipmonitor.conf.
This design provides flexibility (GUI-based configuration vs file-based) but can cause confusion if both sources contain conflicting values for the same parameter.
Example Troubleshooting Scenario
User report: "I have cleanspool = yes in voipmonitor.conf, but old files are not being deleted."
Investigation:
# 1. Check configuration file
grep cleanspool /etc/voipmonitor.conf
# Output: cleanspool = yes ✓ Correct
# 2. Check if mysqlloadconfig is enabled
grep mysqlloadconfig /etc/voipmonitor.conf
# Output: mysqlloadconfig = yes (default) - CONFIG LOADED FROM DB
# 3. Check GUI Settings > Sensors > wrench icon > search "cleanspool"
# GUI shows: cleanspool = no ✗ CONFLICT
Root Cause:
mysqlloadconfig = yesenables database-based configuration- Previous GUI set
cleanspool = noand stored it insensor_configtable - Database value overrides file value, so
cleanspoolis disabled
Solution:
- Update setting via GUI (
Settings > Sensors > wrench > cleanspool = yes) - Or set
mysqlloadconfig = noinvoipmonitor.conf
Related Configuration Parameters
The following sniffer configuration parameters can be overridden by GUI sensor settings when mysqlloadconfig = yes:
cleanspool- Enable/disable automatic file cleaningmaxpoolsize- Maximum disk space for captured datamaxpooldays- Maximum age for captured datamaxpoolrtpdays- Maximum age for RTP filesmaxpoolsipdays- Maximum age for SIP filesspooldir- Spool directory location- Any other sensor-specific configuration parameters
For the complete sniffer configuration reference, see Sniffer Configuration.
Custom Autocleaning: One-Time Cleanup with Filters
The GUI provides a custom autocleaning feature that allows you to perform one-time cleanup of existing recordings based on specific criteria, such as IP address or telephone number. This is useful when you need to clean up data for a specific subset of calls without affecting global retention settings.
Use Case: Cleaning Old Recordings for a Specific IP
After configuring capture rules to stop recording future calls from a specific IP address, you may still have existing RTP recordings from that IP. Custom autocleaning allows you to remove these old recordings.
Example scenario:
- You configured a capture rule to discard RTP for IP
192.168.1.50 - Only new calls will be affected by this rule
- Existing recordings for this IP must be cleaned up manually
GUI cleanup steps:
- Navigate to Settings > Custom Autocleaning
- Create a new autocleaning rule
- Set the criteria (e.g., "Delete RTP older than 1 day")
- In the Common Filter section, specify the target IP address (
192.168.1.50) - Save and apply the rule
- Once the cleanup is complete, remove the autocleaning rule
This rule will run once and clean up all matching old recordings, then the capture rule will prevent future recordings.
Comparison with Global Retention
| Feature | Custom Autocleaning | Global Retention |
|---|---|---|
| Scope | Targeted (specific IP, number, filter) | All calls |
| Purpose | One-time cleanup of existing data | Ongoing automated cleanup |
| Configuration | GUI with CDR filters | maxpoolsize, maxpooldays
|
| Flexibility | High - can use any CDR filter criteria | Low - time/size only |
Filters Available in Custom Autocleaning
The custom autocleaning interface supports the same filter options as the CDR view, including:
- IP filters - Source or destination IP addresses
- Telephone number filters - Caller or called numbers
- Time-based filters - Calls older than X days
- Other CDR criteria - Duration, MOS, packet loss, etc.
For details on using these filters, see CDR Filtering.
Important Notes
- Custom autocleaning rules should typically be deleted after they have run once
- Leaving a rule active will continuously clean up matching data, which may not be desired
- The cleanup affects PCAP files stored on disk, not CDR records in the database
- For database cleanup, use the global
cleandatabaseparameters
How Cleanspool Works: Filesystem Index vs Database
It is important to understand that the cleanspool feature operates on the filesystem, not the database. This is a critical distinction for configuring data retention correctly.
Filesystem-Based Cleaning
The cleanspool process maintains its own index in the .cleanspool_cache file located in the spool directory. This filesystem index is completely independent of the VoIPmonitor database.
| Aspect | Cleanspool (Filesystem) | Database Cleaning |
|---|---|---|
| Where it operates | Deletes PCAP files from disk | Deletes CDR records from MySQL |
| Index used | .cleanspool_cache (filesystem scan) |
Database tables/partitions |
| Retention limits | maxpoolsize, maxpooldays |
cleandatabase, cleandatabase_size
|
| File selection criteria | Based on filesystem index, NOT database records | Based on calldate in cdr table
|
Key Behavior: Files Not in Database
The cleanspool process will delete files based solely on the filesystem cache index and the maxpoolsize/maxpooldays limits. This means:
- Files will be deleted even if they are not in the database (orphaned PCAPs)
- Files will be deleted even if database records still exist (e.g., after database backup/restore)
- To protect specific data, you must move it outside the spool directory entirely, not just to a different subfolder
The .cleanspool_cache File
When cleanspool runs, it scans the spool directory structure (YYYY-MM-DD/HH) and indexes all PCAP files into .cleanspool_cache. During the next cleaning cycle, it uses this cache to:
1. Sort files by age (oldest first)
2. Delete files until maxpoolsize or maxpooldays limits are met
Important behaviors:
- By default (
maxpool_clean_obsolete = no), cleanspool only deletes files that are indexed in.cleanspool_cache - Files that appear but are not in the cache are ignored until the next full scan updates the cache
- With
maxpool_clean_obsolete = yes, cleanspool will also delete any files in the spool directory that are not in the cache
| Important: Protect Data Moves | |
|---|---|
maxpool_clean_obsolete = no (default):
|
If you manually move files into the spool directory, they will not be indexed immediately. Cleanspool will ignore them until a full scan updates the cache. To prevent deletion, move data outside the spool directory entirely, not to a different subfolder within the spool. |
Configuration Parameter Reference
maxpool_clean_obsolete = no(default)- Cleanspool only deletes files that are indexed in the
.cleanspool_cachefilesystem index. Files that are not in the cache are ignored.
maxpool_clean_obsolete = yes- Cleanspool will delete ALL files in the spool directory, including those not found in the cache. This is useful if you have manually moved files or want to clean orphaned files.
Warning: This parameter controls filesystem cache behavior, not database record matching. Cleanspool always operates independently of the database.
Maintenance: Re-indexing the Spool Directory
VoIPmonitor maintains an index of all created PCAP files to perform cleaning efficiently without scanning the entire directory tree. If this index becomes corrupt, or if you manually move files into the spool, old data may not be deleted correctly.
To trigger a manual re-index via the manager API:
# Open a manager API session
echo 'manager_file start /tmp/vmsck' | nc 127.0.0.1 5029
# Send the re-index command
echo reindexfiles | nc -U /tmp/vmsck
Note: This command requires netcat with support for UNIX sockets (-U). For alternative methods, see the Manager API documentation.
Database Cleaning (CDR Retention)
Managing the size of the cdr table and other large tables is critical for GUI performance.
Partitioning Method (Recommended)
Since version 7, VoIPmonitor utilizes database partitioning, which splits large tables into smaller, daily segments. This is the recommended method for managing database retention.
| Aspect | Description |
|---|---|
| How it works | Set cleandatabase = 30 in voipmonitor.conf to keep the last 30 days of data.
|
| Why it's better | Dropping old partitions is instantaneous (milliseconds), regardless of row count. Zero database load. |
| Requirement | Partitioning is enabled by default on new installations. |
Partition Limit Consideration
MySQL and MariaDB have a hard limit on the number of partitions that can be created for a single table. This limit is approximately 8000 partitions per table.
| Important: Maximum Partitions | |
|---|---|
| MySQL/MariaDB Partition Limit: |
|
For example, with daily partitioning enabled:
cleandatabase = 30creates 30 active partitions (far below limit)cleandatabase = 3650creates 3650 active partitions (10 years of data)cleandatabase = 8000approaches the practical limit (~22 years of data)
Note on CDR Record Limits: While the partition limit constrains retention time, the number of CDR records is not limited by partitions. Modern VoIPmonitor installations use BIGINT for the cdr.ID column, which supports up to 18 quintillion records (far exceeding any practical deployment). For more details on the ID column type, see Migrating Database Primary Keys to BIGINT.
Quick Start: Global Retention
For most deployments, configure one parameter in voipmonitor.conf:
# Keep all records for 30 days
cleandatabase = 30
The cleandatabase parameter acts as a global default for all cleandatabase_* options and applies to:
cdr- Call Detail Recordsmessage- SIP MESSAGE textssip_msg- SIP OPTIONS/SUBSCRIBE/NOTIFY messagesregister_state- SIP registration statesregister_failed- Failed registration attempts
Retention Parameters
| Parameter | Default | Description |
|---|---|---|
cleandatabase |
0 (disabled) | Master retention setting in days. |
cleandatabase_cdr |
0 | Specific retention for cdr and message tables.
|
cleandatabase_rtp_stat |
2 | Retention for detailed RTP statistics. |
cleandatabase_sip_msg |
0 | Retention for OPTIONS/SUBSCRIBE/NOTIFY. |
cleandatabase_size |
(unset) | Alternative: size-based limit in MB (requires version 2024.05.1+). |
partition_operations_enable_fromto |
1-5 | Time window for partition operations (e.g., 1-5 AM). |
Size-Based Database Cleaning
In addition to time-based retention, VoIPmonitor supports size-based database cleanup using cleandatabase_size. This is useful when you want to limit the database size regardless of data age.
# Limit database to 50 GB
cleandatabase_size = 51200
# Force immediate cleanup if size exceeded (required for size-based)
cleandatabase_size_force = true
| Parameter | Description |
|---|---|
cleandatabase_size |
Maximum database size in MB. When exceeded, the oldest partitions are dropped until the size is below this limit. |
cleandatabase_size_force |
Must be set to true to enable size-based cleanup. Without this, cleandatabase_size will not trigger cleanup.
|
Behavior:
- The size check is performed daily during partition operations
- When the size exceeds
cleandatabase_size+ 5% buffer, the oldest partitions are dropped - This ensures the database stays within the specified size limit
- Works independently of
cleandatabase(time-based retention)
Note: Size-based cleanup only affects partitioned tables. Non-partitioned tables are not affected.
More details: Sniffer Configuration - Database Cleaning.
Legacy Method: Manual Deletion (Not Recommended)
For very old, non-partitioned databases, you would need custom scripts with DELETE FROM cdr WHERE calldate < ... queries.
Warning: Manual DELETE on large tables is extremely slow and resource-intensive. A single operation on millions of rows can take hours and impact GUI performance.
Troubleshooting Disk Space Issues
Disk Space Not Reclaimed After Cleanup
If automatic cleanup runs but disk space is not freed from the MySQL data directory, check the innodb_file_per_table setting:
SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';
| Value | Behavior |
|---|---|
| ON | Each table/partition has its own .ibd file. Dropping partitions reclaims space immediately.
|
| OFF | All data in shared ibdata1 file. Dropping partitions does not reduce file size.
|
Solutions
- Option 1
- Enable for Future Tables
Add to /etc/my.cnf or /etc/mysql/my.cnf:
[mysqld]
innodb_file_per_table = 1
systemctl restart mysql
Note: This only affects NEW tables/partitions. Existing data in ibdata1 remains.
- Option 2
- Reclaim Space from Existing Tables
OPTIMIZE TABLE cdr;
Warning: Requires significant free disk space to duplicate table data. May crash if disk is nearly full.
- Option 3
- Export and Re-import
mysqldump -u root -p voipmonitor > voipmonitor_backup.sql
mysql -u root -p -e "DROP DATABASE voipmonitor; CREATE DATABASE voipmonitor;"
mysql -u root -p voipmonitor < voipmonitor_backup.sql
MySQL Error 28: No Space Left on Device
If MySQL repeatedly crashes with "No space left on device" (Error 28) even when standard cleandatabase retention settings are in place, the database is likely filling up faster than time-based retention can clean it.
| Critical: Time-Based vs Size-Based Retention | |
|---|---|
cleandatabase = 30 (Time-based):
|
Keeps data for 30 days. If call volume is high, the database may reach disk capacity well before reaching the 30-day limit. |
cleandatabase_size (Size-based):
|
Limits database to a specific size in MB. Oldest partitions are dropped immediately when the size limit is exceeded, preventing disk exhaustion regardless of data age. |
Diagnosis: Check Disk and Database Size
Identify which partition is full and check database size:
# 1. Check all partitions to find the full one
df -h
# Example output:
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 50G 48G 2.0G 97% /
# /dev/sdb1 1.0T 400G 600G 40% /var/lib/mysql
# 2. Check database directory size
du -hs /var/lib/mysql
# 3. Check spool directory size (separate from database)
du -hs /var/spool/voipmonitor
If /var/lib/mysql is nearly full but other partitions have free space, proceed to size-based database cleaning.
Solution: Enable Size-Based Database Cleaning
Use cleandatabase_size to control database growth by size rather than time.
# Edit /etc/voipmonitor.conf
[general]
# Set maximum database size in MB (example: 500 GB = 512000 MB)
cleandatabase_size = 512000
# CRITICAL: Must be set to true for size-based cleanup to work
cleandatabase_size_force = true
# Optional: Keep time-based retention as a fallback
cleandatabase = 30
| Parameter | Purpose | Required for Size-Based? |
|---|---|---|
cleandatabase_size |
Maximum database size in MB | Yes |
cleandatabase_size_force |
Enables size-based cleanup | Yes (MUST be true) |
Apply changes:
systemctl restart voipmonitor
Behavior:
- Size check runs daily during partition operations
- When database exceeds
cleandatabase_size+ 5% buffer, oldest partitions are dropped until under limit - Works independently of
cleandatabasetime-based retention - Ensures database never grows beyond specified size limit
Additional Resolution: Move Database to Larger Partition
If the database partition cannot accommodate your data requirements, move MySQL to a larger partition.
# 1. Stop MySQL
systemctl stop mysql
# 2. Move database files to new location
mv /var/lib/mysql /mnt/storage/mysql
# 3. Edit MySQL configuration
# Edit /etc/mysql/my.cnf or /etc/my.cnf
[mysqld]
datadir=/mnt/storage/mysql
# 4. Update AppArmor (Ubuntu/Debian) or SELinux (RHEL/CentOS)
# Ubuntu/Debian:
echo '/mnt/storage/mysql/** rwk,' >> /etc/apparmor.d/local/usr.sbin.mysqld
systemctl reload apparmor
# RHEL/CentOS:
semanage fcontext -a -t mysqld_db_t "/mnt/storage/mysql(/.*)?"
restorecon -Rv /mnt/storage/mysql
# 5. Start MySQL
systemctl start mysql
Monitoring Database Health
SQL Queue Metrics
The sensor tracks queue metrics visible in GUI → Settings → Sensors → Status:
| Metric | Description | Healthy Range |
|---|---|---|
| SQLq | CDRs waiting to be written to database | Near 0, sporadic spikes OK |
| SQLf | Failed database write attempts | Zero (not growing) |
- Consistently high/growing SQLq → database cannot keep up
- Non-zero/growing SQLf → database errors or connectivity issues
See SQL Queue Troubleshooting for details.
System Monitoring
# Check system load
cat /proc/loadavg
# Monitor disk I/O (shows only active processes)
iotop -o
High I/O from mysqld processes may indicate slow storage or poorly tuned MySQL settings.
MySQL Performance Settings
For high-performance operation with partitioning:
[mysqld]
# Use 50-70% of available RAM for caching
innodb_buffer_pool_size = 4G
# Flush logs to OS every second (faster, safe for VoIPmonitor)
innodb_flush_log_at_trx_commit = 2
# Enable per-table filespace for easy space reclamation
innodb_file_per_table = 1
For comprehensive tuning, see Scaling and Performance Guide.
See Also
- Sniffer Configuration Reference
- Scaling and Performance Guide
- SQL Queue Troubleshooting
- Sniffer Troubleshooting
AI Summary for RAG
Summary: VoIPmonitor has multiple data retention mechanisms: (1) Filesystem cleaning for PCAP files using maxpoolsize/maxpooldays parameters, running every 5 minutes to delete oldest data first; (2) Database cleaning using cleandatabase parameter with daily partitioning for instant partition drops. Database size is theoretically unlimited but limited by MySQL/MariaDB partition limit of approximately 8000 partitions per table (~8000 days or ~22 years with daily partitioning). CDR record count is not limited by partitions - modern installations use BIGINT for the cdr.ID column supporting up to 18 quintillion records (see Upgrade_to_bigint). (3) Custom autocleaning in GUI for one-time targeted cleanup of specific recordings based on filters (IP, phone number, duration, etc.). Key behavior: directories within maxpoolrtpdays window contain both SIP and RTP (large), while directories within maxpoolsipdays but beyond maxpoolrtpdays contain only SIP (smaller) - this is expected. Custom autocleaning is useful for cleaning up old recordings for specific IPs after configuring capture rules to stop future recording (capture rules only affect new calls, existing recordings must be cleaned separately). Cleanspool operates on the filesystem, NOT the database. The cleanspool process maintains its own index in .cleanspool_cache file and deletes files based solely on this filesystem index and maxpoolsize/maxpooldays limits. Files are deleted even if they are not in the database. The maxpool_clean_obsolete parameter (default: no) controls whether cleanspool deletes files not found in the cache. Troubleshooting covers disk full scenarios (check with df -h and du -hs, analyze which partition is full), space not reclaimed issues (innodb_file_per_table setting), and database health monitoring (SQLq/SQLf metrics). MySQL Error 28 "No space left on device" troubleshooting: when standard cleandatabase time-based retention fails, use cleandatabase_size and cleandatabase_size_force = true for size-based database cleaning as the primary solution. Additional topics: relocating spooldir to different partition, syncing GUI SNIFFER_DATA_PATH configuration, size-based database cleaning via cleandatabase_size and cleandatabase_size_force, saving only RTP headers with savertp=header (up to 90% storage reduction), critical architecture consideration for packetbuffer_sender mode (apply settings on central server, not sensors). Emergency cleanup triggers: autocleanspoolminpercent (default 1%, triggers at 99% disk usage) and autocleanmingb (default 5GB, triggers when free space below 5GB) can override retention settings, causing premature file deletion even when maxpooldays is set correctly. GUI configuration override: when mysqlloadconfig = yes (default), GUI settings in the sensor_config database table override voipmonitor.conf file settings. If cleanspool = yes in config file but cleaning is not running, check GUI Settings > Sensors > wrench icon for conflicting values. Resolution options: update via GUI, disable mysqlloadconfig, or remove conflicting entry from sensor_config table.
Keywords: data retention, cleaning, delete old calls, disk space, spooldir, maxpoolsize, maxpooldays, maxpoolsipdays, maxpoolrtpdays, cleandatabase, partitioning, cleandatabase_size, cleandatabase_size_force, reindexfiles, innodb_file_per_table, SQLq, SQLf, directory size difference, SIP vs RTP retention, relocate spooldir, SNIFFER_DATA_PATH, MySQL Error 28, savertp header, packetbuffer_sender, client server mode, distributed architecture, autocleanspoolminpercent, autocleanmingb, emergency cleanup, retention not working, premature deletion, cleanspool_cache, maxpool_clean_obsolete, filesystem index, database vs filesystem, orphaned files, custom autocleaning, one-time cleanup, targeted cleanup, IP filter cleanup, clean specific IP recordings, mysqlloadconfig, sensor_config, GUI configuration, configuration override, database override, Settings > Sensors, wrench icon, config priority
Key Questions:
- What is the maximum recommended database size and CDR count for VoIPmonitor?
- How do I automatically delete old PCAP files?
- What is the difference between maxpoolsize and maxpooldays?
- My spool directory is full but old files are not deleted - how to fix?
- How do I configure database retention with cleandatabase?
- Why is disk space not reclaimed after MySQL cleanup?
- What do SQLq and SQLf metrics mean?
- Why are recent directories much larger than old ones in my spool?
- Directory size difference with maxpoolsipdays and maxpoolrtpdays
- How do I move the spooldir to a larger partition?
- What is cleandatabase_size and cleandatabase_size_force?
- How do I fix MySQL Error 28 "No space left on device" when standard cleandatabase retention is set?
- Why does MySQL crash even though cleandatabase retention is configured?
- When should I use cleandatabase_size instead of cleandatabase retention?
- What is the difference between time-based and size-based database cleaning?
- How do I stop audio recording and save only RTP headers?
- Where should I apply savertp=header in client-server mode with packetbuffer_sender?
- How do I reduce storage by saving only RTP headers instead of full audio?
- Why are my PCAP files being deleted even though maxpooldays is set to 60?
- What are autocleanspoolminpercent and autocleanmingb?
- How do emergency cleanup triggers override retention settings?
- How do I fix premature file deletion in spool directory?
- Does cleanspool delete files not in the database?
- What is maxpool_clean_obsolete?
- How does cleanspool filesystem index differ from database records?
- Will cleanspool delete files that are not indexed in the database?
- How do I clean up old recordings for a specific IP address?
- What is custom autocleaning in VoIPmonitor GUI?
- How do I delete old recordings after configuring capture rules to stop recording?
- Can I clean up recordings based on specific filters like IP or phone number?
- What is the difference between custom autocleaning and global retention settings?
- How to fix: cleanspool = yes in config file but cleaning not working?
- What is mysqlloadconfig and how does it affect cleanspool settings?
- How do GUI sensor settings override voipmonitor.conf configuration?
- What is the sensor_config database table?
- How do I resolve configuration conflicts between GUI and voipmonitor.conf?
- How do I find cleanspool setting in GUI Settings > Sensors?