Data Retention Policy Guide
Overview
The RAN Monitor application now includes a comprehensive Data Retention Policy system that allows you to manage how long performance metrics, configuration data, and alarm records are stored in InfluxDB. This guide covers everything you need to know about managing data retention.
🎯 Quick Start
Accessing the Retention Policy Dashboard
- Navigate to the Control Panel:
https://localhost:9443 - Click on Data Retention in the navigation menu
- View and manage retention settings for all configured eNodeBs
Setting a Custom Retention Period
- Find the eNodeB in the list
- Update the "Retention Period" field (in hours)
- The setting saves immediately
- Falls back to global default if left empty
Cleaning Old Data
- Click Clean Old Data button to remove records older than the retention period
- Or click Clear All Data to delete all records for that eNodeB (use with caution!)
Screenshot

The Data Retention dashboard showing retention settings and record counts for each eNodeB
📋 Features
Global Retention Settings
- Default Retention Period: 720 hours (30 days)
- Configurable: Change in
config/config.exs - Fallback: Applied to all eNodeBs without custom settings
Per-eNodeB Retention
- Override Global: Set custom retention for specific eNodeBs
- Database Stored: Persisted in the
airscalestable - Real-Time: Takes effect immediately
Automatic Cleanup
- Scheduled: Runs every hour automatically
- Background Worker:
RanMonitor.Data.RetentionCleanupWorker - Per-eNodeB: Respects individual retention settings
- Logged: All cleanups are logged for audit trail
Data Visibility
- Record Counts: See how many records per measurement type:
- Performance Metrics
- Configuration
- Alarms
- Total Summary: View total records per eNodeB
- Real-Time: Updated on page refresh
🖥️ User Interface
Dashboard Layout

The Data Retention dashboard showing global settings, per-eNodeB retention periods, and record counts
Layout Overview:
┌─────────────────────────────────────────────────────────────┐
│ Data Retention Policy │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ GLOBAL SETTINGS │ │
│ │ │ │
│ │ Default Retention: 30 days | Total Records: 1.2M │ │
│ │ Auto-Cleanup: ✓ Enabled (runs hourly) │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ eNodeB RETENTION SETTINGS │ │
│ │ │ │
│ │ ┌─ SITE-01 ────────────────────────────────────────┐ │ │
│ │ │ Status: REGISTERED │ │ │
│ │ │ Retention: 720 hours (30 days) │ │ │
│ │ │ │ │ │
│ │ │ Data Records: │ │ │
│ │ │ Performance Metrics: 250,000 │ │ │
│ │ │ Configuration: 5,000 │ │ │
│ │ │ Alarms: 15,000 │ │ │
│ │ │ ──────────────────── │ │ │
│ │ │ Total: 270,000 │ │ │
│ │ │ │ │ │
│ │ │ [Clean Old Data] [Clear All Data] │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ (More eNodeBs below...) │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Status Indicators
- Green (✓): eNodeB registered and active
- Red (✗): eNodeB pending or unregistered
- Disabled: Cannot modify settings for non-registered eNodeBs
Action Buttons
| Button | Action | Effect |
|---|---|---|
| Clean Old Data | Remove old records | Deletes records older than retention period |
| Clear All Data | Complete wipe | Deletes ALL records (⚠️ use with caution!) |
| Refresh | Update display | Re-fetches record counts and settings |
⚙️ Configuration
Global Retention Configuration
Edit config/config.exs:
config :ran_monitor,
ecto_repos: [RanMonitor.Repo],
generators: [context_app: :ran_monitor],
data_retention_hours: 720 # 30 days, adjust as needed
Supported Time Values
| Period | Hours | Days | Recommended For |
|---|---|---|---|
| 1 hour | 1 | 0.04 | Testing only |
| 1 day | 24 | 1 | Short-term metrics |
| 7 days | 168 | 7 | Weekly reports |
| 14 days | 336 | 14 | Bi-weekly reports |
| 30 days | 720 | 30 | Monthly reports (default) |
| 90 days | 2160 | 90 | Long-term trends |
| 180 days | 4320 | 180 | Bi-annual reports |
| 1 year | 8760 | 365 | Annual reports |
Environment Variables
Optionally override at runtime:
export DATA_RETENTION_HOURS=1440 # 60 days
mix phx.server
🔄 How It Works
Data Retention Flow
1. DATA INSERTION
├─ Performance Metrics → InfluxDB
├─ Configuration Data → InfluxDB
└─ Alarms → InfluxDB
2. AUTOMATIC CLEANUP (Hourly)
├─ RetentionCleanupWorker triggers
├─ For each eNodeB:
│ ├─ Get effective retention (per-eNodeB or global)
│ ├─ Calculate cutoff timestamp
│ └─ Delete records older than cutoff
└─ Log results
3. MANUAL CLEANUP (On Demand)
├─ User clicks button in UI
├─ Retention policy applied
├─ Records deleted immediately
└─ Success/error notification shown
4. MONITORING
└─ Record counts displayed in UI
Retention Logic
Per-eNodeB Effective Retention:
effective_retention = case airscale.retention_hours do
nil -> Config.data_retention_hours() # Use global (720h)
hours -> hours # Use per-eNodeB custom value
end
Example:
- Global default: 720 hours (30 days)
- eNodeB "SITE-01" custom: 168 hours (7 days)
- eNodeB "SITE-02" custom: nil → uses global 720 hours
Cleanup Process
Cutoff Timestamp = Now - (retention_hours * 3600 seconds)
Example with 30-day retention:
├─ Current: 2025-12-11 10:00:00
├─ Retention: 720 hours (30 days)
├─ Cutoff: 2025-11-11 10:00:00
└─ Delete all records with timestamp < cutoff
📊 Monitoring & Logging
Log Entries
The system logs all retention activities. Look for:
[RetentionCleanupWorker] Starting retention cleanup worker
[RetentionCleanupWorker] Cleaning data for SITE-01 (retention: 720h)
[RetentionCleanupWorker] Deleted 15,000 records for SITE-01
[RetentionCleanupWorker] Cleanup cycle complete: 5 successful, 0 failed, 75,000 total deleted
Monitoring Record Counts
Real-time Visibility:
- Open Data Retention dashboard
- View current record counts per measurement per eNodeB
- Click "Refresh" to update counts
Historical Tracking:
- Check application logs for cleanup summaries
- Monitor InfluxDB disk usage over time
- Set up alerts based on record count growth
🛠️ Advanced Usage
Programmatic Access
Use the retention policy service in your code:
alias RanMonitor.Data.RetentionPolicy
alias RanMonitor.Database.Nokia
# Get effective retention for an eNodeB
airscale = Nokia.get_airscale!(1)
hours = RetentionPolicy.get_retention_hours(airscale)
# => 720 (or custom value if set)
# Get record counts for an eNodeB
counts = RetentionPolicy.get_record_counts("SITE-01")
# => %{"PerformanceMetrics" => 250000, "Configuration" => 5000, "Alarms" => 15000}
# Get total records
total = RetentionPolicy.get_total_record_count("SITE-01")
# => 270000
# Delete old records manually
{:ok, deleted_count} = RetentionPolicy.delete_old_records("SITE-01", 720)
# => {:ok, 50000} (50k records deleted)
# Clear all records for an eNodeB
{:ok, deleted_count} = RetentionPolicy.clear_all_records("SITE-01")
# => {:ok, 270000} (all 270k records deleted)
Adjusting Cleanup Interval
Edit lib/ran_monitor/data/retention_cleanup_worker.ex:
# Change from 1 hour (3600000ms) to 30 minutes (1800000ms)
@cleanup_interval_ms 1800000 # 30 minutes
Then recompile:
mix compile
Database-Level Queries
View retention settings directly:
SELECT name, retention_hours FROM airscales;
Update retention via database:
UPDATE airscales
SET retention_hours = 168
WHERE name = 'SITE-01';
📈 Best Practices
Retention Period Selection
Short-term (< 7 days)
- Use for: Testing, staging environments
- Not recommended for: Production
- Risk: May delete important historical data
Standard (7-30 days)
- Use for: Production deployments with typical storage
- Best for: Most use cases
- Balance: Good history with manageable storage
Long-term (> 30 days)
- Use for: Trend analysis, compliance requirements
- Cost: Higher storage requirements
- Benefit: Extended historical data
Recommended by Use Case
| Use Case | Retention | Reason |
|---|---|---|
| Daily reports | 7-14 days | Weekly review cycles |
| Weekly reports | 30-60 days | Monthly summaries |
| Monthly reports | 90 days | Quarterly analysis |
| Trend analysis | 180-365 days | Long-term patterns |
| Compliance | As required | Legal/regulatory |
Storage Considerations
Estimate storage needs:
- 1000 records ≈ 1-5 KB (depending on measurement type)
- 1 million records ≈ 1-5 GB
- Retention period × collection rate = total storage
Monitor growth with:
# Check InfluxDB bucket size
influx bucket list
# Or check disk usage
df -h /path/to/influxdb/data
🔐 Security & Compliance
Data Privacy
- No encryption at rest by default
- Network access controlled via InfluxDB security
- Access logs available in application logs
Compliance
- Audit trail: All cleanups logged with timestamp
- Data integrity: Soft deletes, no hard wipes at application level
- Retention proof: Logs show what was retained/deleted
Recommendations
- Enable InfluxDB authentication for production
- Monitor cleanup logs regularly
- Set retention carefully to balance compliance and storage
- Backup before bulk operations if critical data
- Test retention policies in staging first
🐛 Troubleshooting
Issue: Cleanup Not Running
Symptoms:
- Records older than retention period still exist
- No cleanup log entries
Solutions:
- Check application is running:
ps aux | grep mix - Verify
RetentionCleanupWorkerstarted:- Check logs for
[RetentionCleanupWorker] Starting
- Check logs for
- Check InfluxDB connection:
- Visit InfluxDB Status page:
https://localhost:9443/nokia/influx
- Visit InfluxDB Status page:
- Verify retention settings are configured:
- Check
config/config.exsfordata_retention_hours
- Check
Issue: Manual Cleanup Failed
Symptoms:
- Error message when clicking "Clean Old Data"
- Records not deleted
Solutions:
- Check InfluxDB is accessible:
- Test connection in dashboard
- Verify record counts are accurate:
- Click "Refresh" to update
- Check application logs for errors:
- Look for
[RetentionPolicy]error entries
- Look for
- Verify eNodeB is registered:
- Check BTS Status page
Issue: High Memory Usage After Cleanup
Symptoms:
- Application becomes slow after cleanup
- Memory usage spikes
Solutions:
- This is normal for large deletes
- Allow 5-10 minutes for memory to normalize
- Consider reducing cleanup frequency:
- Change
@cleanup_interval_ms(default 1 hour)
- Change
- Or reduce retention period for affected eNodeBs
Issue: Incorrect Record Counts
Symptoms:
- Record counts don't match InfluxDB UI
- "Clean Old Data" shows different numbers
Solutions:
- Click "Refresh" to force update
- Check InfluxDB query:
- May take time to reflect recent deletes
- Wait a minute and try again:
- InfluxDB may be processing delete operations
- Check eNodeB name matches exactly:
- Case-sensitive comparison
📖 Related Documentation
- Operations Guide - Complete operational overview
- Web UI Guide - Control panel reference and features
- Getting Started Guide - Quick start guide
- Common Operations Guide - Day-to-day management tasks
- Grafana Integration Guide - Analytics and dashboards
🔗 Access Points
- Data Retention Dashboard:
https://localhost:9443/nokia/retention - BTS Status:
https://localhost:9443/nokia/status - InfluxDB Status:
https://localhost:9443/nokia/influx - Live Logs:
https://localhost:9443/nokia/logs
💡 FAQ
Q: Will cleanup delete active data?
A: No. Only records older than the retention period are deleted. Currently being collected data is never affected.
Q: Can I set different retention for different eNodeBs?
A: Yes! Each eNodeB can have its own retention setting. If not set, it uses the global default.
Q: How often does automatic cleanup run?
A: Every hour by default. Adjust @cleanup_interval_ms in the worker if needed.
Q: What happens if I clear all data?
A: All records (Performance Metrics, Configuration, Alarms) for that eNodeB are permanently deleted. This cannot be undone.
Q: Can cleanup affect data collection?
A: No. Cleanup and data collection are independent. New data will continue being written while old data is deleted.
Q: How long does cleanup take?
A: Depends on record count:
- Small (< 100k): < 1 second
- Medium (100k-1M): 1-10 seconds
- Large (> 1M): 10-60+ seconds
Q: Can I manually delete specific records?
A: Not via the UI. Only full cleanup or complete clear available. For granular deletions, use InfluxDB CLI or API directly.
Q: What if InfluxDB is unavailable?
A: Cleanup will fail silently and retry next hour. Data collection continues unaffected.
Q: Does cleanup affect performance?
A: Minor impact during cleanup (seconds to minutes depending on data size). Hourly interval chosen to minimize impact.
📝 Implementation Details
Files Modified
| File | Changes |
|---|---|
lib/ran_monitor/database/nokia/airscale.ex | Added retention_hours field |
lib/ran_monitor/config/config.ex | Added data_retention_hours() getter |
config/config.exs | Added global retention config and page route |
lib/ran_monitor/application.ex | Added cleanup worker to supervision tree |
Files Created
| File | Purpose |
|---|---|
lib/ran_monitor/data/retention_policy.ex | Core retention service |
lib/ran_monitor/data/retention_cleanup_worker.ex | Hourly cleanup GenServer |
lib/ran_monitor/web/live/retention_policy_live.ex | Management UI page |
priv/repo/migrations/20251211065257_add_retention_hours_to_airscales.exs | Database migration |
Key Functions
RetentionPolicy Module:
get_retention_hours(airscale)- Get effective retentionget_record_counts(airscale_name)- Fetch record countsget_total_record_count(airscale_name)- Total countdelete_old_records(name, hours)- Clean old recordsclear_all_records(name)- Complete wipe
RetentionCleanupWorker GenServer:
start_link(opts)- Start cleanup workerinit(:ok)- Initialize workerhandle_info(:cleanup, state)- Run cleanup cycle
🚀 Getting Started
Setup (One-Time)
-
Run the migration:
mix ecto.migrate -
Restart the application:
mix phx.server -
Verify installation:
- Navigate to
https://localhost:9443/nokia/retention - Should see Data Retention dashboard
- Navigate to

First Use
-
Check current settings:
- View global retention (default: 720 hours)
- View per-eNodeB retention settings
-
Customize if needed:
- Update global retention in
config/config.exs - Or set per-eNodeB via UI
- Update global retention in
-
Monitor cleanup:
- Watch logs for
[RetentionCleanupWorker]entries - Verify record counts decrease over time
- Watch logs for
📞 Support
Need Help?
- Check logs: Look for
[RetentionPolicy]or[RetentionCleanupWorker]entries - Review this guide: Most issues covered in Troubleshooting section
- Check other docs: Refer to related documentation links above
- Verify setup: Ensure migration ran and worker started
Reporting Issues
Include:
- Error message from UI or logs
- eNodeB name affected
- Current retention settings
- Record counts before/after
- Steps to reproduce
🎓 Learning Resources
Related Concepts
- InfluxDB v2.x: Time-series database with retention policies
- Retention Policy: How long data is kept
- Cleanup: Automated deletion of old data
- Measurement Types: Performance Metrics, Configuration, Alarms