Process Management¶
Torrentarr runs Arr automation as in-process worker tasks inside Torrentarr.Host. Each Arr instance gets a search task and a torrent task (the WebUI still shows {name}-search / {name}-torrent rows). Tasks are isolated from each other with their own loops and restart limits so a stuck torrent loop does not block search. This is the .NET equivalent of qBitrr’s multiprocessing design — Host does not spawn Torrentarr.Workers as OS processes.
Overview¶
Torrentarr's process management provides:
- Task isolation: Search and torrent loops run concurrently per Arr instance
- Automatic Restart: Failed tasks are automatically restarted
- Restart Limits: Prevents infinite restart loops
- Real-Time Monitoring: Track task status via WebUI or logs
- Graceful Shutdown: Clean cancellation of all worker tasks
Architecture¶
Process Structure¶
Torrentarr.Host
├── Web UI (Kestrel, always online)
├── Per-Arr ArrWorkerManager tasks
│ ├── Radarr search task + torrent task
│ ├── Sonarr search task + torrent task
│ ├── Lidarr search task + torrent task
│ └── Readarr search task + torrent task
├── QBit-only category tasks
├── Free space / failed / recheck orchestrator
└── Auto-update background service
Why in-process tasks?¶
Benefits: - ✅ Isolation of loops: Search is not blocked behind torrent processing - ✅ WebUI stays up: Host does not die if a worker task faults - ✅ Shared WAL database: SQLite retry replaces qBitrr’s cross-process db_lock - ✅ Crash recovery: Individual instance tasks restart without recycling the Host
Trade-offs vs qBitrr pathos forks: - ⚠️ Not a separate OS process per Arr instance (intentional architecture) - ⚠️ Torrentarr.Workers exists for a standalone entry point but is unused by Host
Auto-Restart Configuration¶
Configuration Options¶
Add these settings to your config.toml under [Settings]:
[Settings]
# Enable automatic process restart (default: true)
AutoRestartProcesses = true
# Maximum restarts within the restart window (default: 5)
MaxProcessRestarts = 5
# Time window for counting restarts in seconds (default: 300 = 5 minutes)
ProcessRestartWindow = 300
# Delay before restarting a failed process in seconds (default: 5)
ProcessRestartDelay = 5
How It Works¶
- Process Failure Detection: Torrentarr detects when an Arr process terminates unexpectedly
- Restart Attempt: If
AutoRestartProcesses = true, Torrentarr waitsProcessRestartDelayseconds - Restart Count Tracking: Restart timestamp is recorded for the process
- Window Check: Torrentarr checks if restarts exceed
MaxProcessRestartswithinProcessRestartWindow - Decision:
- ✅ Within Limits: Process is restarted
- ❌ Exceeds Limits: Auto-restart is disabled for that process (prevents infinite loops)
Restart Window Explained¶
The restart window prevents infinite restart loops when a process has a persistent issue:
Example: - MaxProcessRestarts = 5 - ProcessRestartWindow = 300 (5 minutes)
Scenario 1: Transient Failure (Restarts Allowed)
00:00 - Process starts
00:05 - Process crashes → Restart #1
00:10 - Process crashes → Restart #2
00:15 - Process crashes → Restart #3
00:20 - Process stable (no more crashes)
Result: Restarts continue (within limits)
Scenario 2: Persistent Failure (Restarts Disabled)
00:00 - Process starts
00:05 - Process crashes → Restart #1
00:10 - Process crashes → Restart #2
00:15 - Process crashes → Restart #3
00:20 - Process crashes → Restart #4
00:25 - Process crashes → Restart #5
00:30 - Process crashes → Auto-restart DISABLED (5 restarts in 30 seconds)
Result: Process remains stopped to prevent loop
Configuration Examples¶
Example 1: Default Settings (Balanced)¶
[Settings]
AutoRestartProcesses = true
MaxProcessRestarts = 5
ProcessRestartWindow = 300 # 5 minutes
ProcessRestartDelay = 5 # 5 seconds
Use Case: General use, balances availability with protection against restart loops
Example 2: High Availability (Aggressive Restart)¶
[Settings]
AutoRestartProcesses = true
MaxProcessRestarts = 10 # Allow more restarts
ProcessRestartWindow = 600 # 10-minute window
ProcessRestartDelay = 3 # Restart faster
Use Case: Critical setups where downtime must be minimized, even with frequent transient failures
Example 3: Conservative (Prevents Loops)¶
[Settings]
AutoRestartProcesses = true
MaxProcessRestarts = 3 # Fewer restarts allowed
ProcessRestartWindow = 180 # 3-minute window
ProcessRestartDelay = 10 # Wait longer before restart
Use Case: Setups prone to configuration issues, prevents rapid restart loops
Example 4: Manual Management (No Auto-Restart)¶
Use Case: Debugging, development, or when using external process managers (systemd, Docker restart policies)
Monitoring Processes¶
Via WebUI¶
Navigate to the Processes tab in the WebUI:
- Process Status: Running, Stopped, or Restarting
- Restart Count: Number of restarts in the current window
- Uptime: How long the process has been running
- Last Restart: Timestamp of the last restart
→ WebUI Processes View Documentation
Via Logs¶
Main Log (Main.log):
INFO - Starting Radarr-Movies process (PID: 12345)
WARNING - Radarr-Movies process (PID: 12345) terminated unexpectedly
INFO - Restarting Radarr-Movies process (attempt 1/5)
INFO - Radarr-Movies process restarted successfully (PID: 12346)
Category-Specific Logs (Radarr-Movies.log):
INFO - Radarr-Movies manager starting
ERROR - Connection to Radarr failed: [Errno 111] Connection refused
INFO - Radarr-Movies manager shutting down
Via CLI¶
Check Process Status:
# Docker
docker exec torrentarr ps aux | grep "Torrentarr"
# Native (systemd)
systemctl status torrentarr
# Native (direct)
ps aux | grep "Torrentarr"
Restart Triggers¶
Automatic Restart Triggers¶
Torrentarr automatically restarts processes when:
- Unexpected Process Termination: Process exits with non-zero code
- Segmentation Fault: Process crashes due to memory error
- Unhandled Exception: Python exception propagates to process level
NOT Restarted For: - ❌ Manual stop via WebUI - ❌ Graceful shutdown (SIGTERM) - ❌ Configuration change requiring restart
Manual Restart¶
Via WebUI: 1. Navigate to Processes tab 2. Click Restart next to the process name 3. Confirm restart action
Via Docker:
Via systemd:
Graceful Shutdown¶
Torrentarr implements graceful shutdown to ensure data consistency:
Shutdown Sequence¶
- Signal Received: SIGTERM or SIGINT
- WebUI Shutdown: Flask server stops accepting requests
- Arr Process Shutdown: Each Arr process completes current operation
- Database Flush: Pending database writes are committed
- Process Termination: All processes exit cleanly
Shutdown Timeout¶
If a process doesn't terminate within 30 seconds, it's forcefully killed (SIGKILL).
Troubleshooting¶
Process Won't Start¶
Symptoms: Process immediately crashes after start
Common Causes: 1. ✅ Invalid Arr API key or URI 2. ✅ Arr instance is down or unreachable 3. ✅ Port conflict (qBittorrent already connected by another client) 4. ✅ Missing dependencies (ffprobe, etc.)
Solutions: 1. Check category-specific log (~/logs/Radarr-Movies.log) 2. Verify Arr connectivity:
Restart Loop (Auto-Restart Disabled)¶
Symptoms: Process stops restarting after several attempts
Explanation: MaxProcessRestarts limit reached within ProcessRestartWindow
Solutions: 1. ✅ Check logs for root cause:
2. ✅ Fix underlying issue (connectivity, configuration, etc.) 3. ✅ Manually restart Torrentarr after fixing: 4. ✅ IncreaseMaxProcessRestarts or ProcessRestartWindow if transient issues are expected High Memory Usage¶
Symptoms: Torrentarr consuming excessive RAM
Explanation: Each Arr process runs a separate Python interpreter
Memory Estimates: - Base process: ~100MB - Per Arr process: ~50-100MB - Total (3 Arr instances): ~250-400MB
Solutions: 1. ✅ Monitor per-process memory:
2. ✅ Disable unused Arr instances (Managed = false in config) 3. ✅ Reduce search limits (SearchLimit) to lower memory pressure Process Hangs (Unresponsive)¶
Symptoms: Process running but not processing torrents
Common Causes: 1. ✅ Event loop blocked by long-running operation 2. ✅ Database lock contention 3. ✅ Network timeout waiting for API response
Solutions: 1. ✅ Enable debug logging:
2. ✅ Check for database locks: 3. ✅ Restart process via WebUI or CLIBest Practices¶
Production Deployments¶
- Enable Auto-Restart:
AutoRestartProcesses = true - Set Reasonable Limits: Default settings (5 restarts in 5 minutes) work for most cases
- Monitor Logs: Set up log aggregation or alerts for restart events
- Use External Health Checks: Monitor Torrentarr's WebUI endpoint (
/api/health) with Uptime Kuma, Healthchecks.io, etc.
Development/Debugging¶
- Disable Auto-Restart:
AutoRestartProcesses = false - Enable Debug Logging:
ConsoleLevel = "DEBUG" - Run Single Arr Instance: Simplify debugging by managing one Arr at a time
- Use
--no-detachFlag: Run in foreground for immediate feedback (systemd/native installs)
Docker Considerations¶
Restart Policy:
services:
torrentarr:
image: feramance/torrentarr:latest
restart: unless-stopped # Container-level restart
environment:
- TORRENTARR_CONFIG=/config/config.toml
# Process restart: set in config.toml [Settings] AutoRestartProcesses = true
Layered Restart: - Docker Restart Policy: Restarts container if it crashes - Torrentarr Auto-Restart: Restarts individual Arr processes
Recommendation: Enable both for maximum availability.
Integration with External Tools¶
systemd¶
Torrentarr Service (torrentarr.service):
[Unit]
Description=Torrentarr - qBittorrent and Arr Integration
After=network.target
[Service]
Type=simple
User=torrentarr
WorkingDirectory=/home/torrentarr
ExecStart=/usr/local/bin/torrentarr
Restart=on-failure # systemd restart on failure
RestartSec=10s # Wait 10 seconds before restart
StartLimitBurst=5 # Max 5 restarts
StartLimitIntervalSec=300 # Within 5 minutes
[Install]
WantedBy=multi-user.target
Combined with Torrentarr Auto-Restart: - systemd restarts Torrentarr if main process crashes - Torrentarr restarts individual Arr processes if they crash
Docker Compose¶
Health Check Example:
services:
torrentarr:
image: feramance/torrentarr:latest
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6969/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
environment:
- TORRENTARR_CONFIG=/config/config.toml
# Auto-restart: set in config.toml [Settings] AutoRestartProcesses = true
Monitoring Tools¶
Prometheus/Grafana: - Scrape Torrentarr metrics endpoint (future feature) - Alert on process restart count
Uptime Kuma:
# Monitor Torrentarr WebUI
- name: Torrentarr
type: HTTP
url: http://localhost:6969/api/health
interval: 60
Healthchecks.io:
# Cron job to ping healthchecks.io if Torrentarr is running
*/5 * * * * curl -fsS --retry 3 http://localhost:6969/api/health && curl -fsS https://hc-ping.com/YOUR-UUID
Advanced Configuration¶
Per-Instance Restart Limits (Not Currently Supported)¶
Future Feature: Configure restart limits per Arr instance instead of globally.
Workaround: Run multiple Torrentarr instances (one per Arr) with different restart settings.
Custom Restart Delay¶
Adjust ProcessRestartDelay based on failure type:
[Settings]
# Fast restart for transient issues
ProcessRestartDelay = 3
# Slower restart if Arr startup is slow
ProcessRestartDelay = 15
Logging¶
Process management events are logged to Main.log:
INFO - Starting Radarr-Movies process (category: radarr-movies, role: manager)
INFO - Radarr-Movies process started with PID 12345
WARNING - Radarr-Movies process (PID 12345) terminated with code 1
INFO - Scheduling restart for Radarr-Movies in 5 seconds (attempt 1/5)
INFO - Restarting Radarr-Movies process
INFO - Radarr-Movies process restarted successfully (PID 12346)
ERROR - Radarr-Movies process exceeded restart limit (5 restarts in 300 seconds)
ERROR - Auto-restart disabled for Radarr-Movies; manual intervention required
API Endpoints¶
Get Process Status:
Response:
{
"processes": [
{
"name": "Radarr-Movies",
"category": "radarr-movies",
"status": "running",
"pid": 12345,
"uptime": 3600,
"restart_count": 2,
"last_restart": "2024-01-15T10:30:00Z"
}
]
}
Next Steps¶
- Monitor Processes: WebUI Processes View
- View Logs: WebUI Logs View
- Troubleshooting: Common Issues
- Advanced Topics: Development Guide - Architecture