Overview
Adaptive worker management automatically adjusts the number of concurrent video conversions based on real-time CPU and memory usage. This prevents system overload during intensive encoding operations while maximizing throughput when resources are available.How It Works
The adaptive system continuously monitors system resources and adjusts worker limits dynamically:- Resource Monitor - Samples CPU and memory every 3 seconds (configurable)
- Threshold Evaluation - Compares metrics against configured thresholds
- Worker Adjustment - Increases or decreases concurrent video workers
- Graceful Scaling - Never interrupts in-flight conversions
Scaling Logic
Scale Down (immediate, after 1 measurement):- CPU usage ≥
cpu_highthreshold (default: 80%) - Available memory ≤
mem_low_percentthreshold (default: 20%) - Reduces workers by 1, down to
minlimit
- CPU usage ≤
cpu_lowthreshold (default: 50%) - Available memory ≥
mem_low_percent + 5%(default: 25%) - Increases workers by 1, up to
maxlimit
The system uses streak counters to prevent oscillation. Scale-down is aggressive (1 sample) to protect system stability, while scale-up is conservative (2 samples) to ensure sustained capacity.
Configuration
Command-Line Flags
Enable adaptive worker management for video conversions
Minimum concurrent video conversions (floor limit)
Maximum concurrent video conversions (ceiling limit)
CPU utilization percentage threshold to reduce workers (0-100)
CPU utilization percentage threshold to increase workers (0-100)
Minimum available memory percentage before reducing workers (0-100)
Seconds between resource monitoring checks
YAML Configuration
~/.media-converter.yaml
Platform-Specific Monitoring
Resource monitoring uses lightweight OS-specific implementations:macOS (Darwin)
CPU Monitoring (resource_darwin.go:13-38):
- Reads system load average via
sysctl -n vm.loadavg - Normalizes by CPU count:
load / NumCPU() * 100
resource_darwin.go:40-104):
- Parses
vm_statoutput for free, inactive, and speculative pages - Calculates available memory:
(free + inactive + speculative) * pageSize - Reads total memory from
sysctl -n hw.memsize
Linux
CPU Monitoring (resource_linux.go:14-36):
- Reads 1-minute load average from
/proc/loadavg - Normalizes by CPU count:
load / NumCPU() * 100
resource_linux.go:38-79):
- Parses
/proc/meminfoforMemTotalandMemAvailable - Calculates percentage:
(MemAvailable / MemTotal) * 100
If resource metrics fail (unsupported platform, permission errors), the system logs a warning once and continues with fixed worker limits.
Examples
Conservative Server Configuration
Ideal for shared servers or systems running other services:Aggressive Desktop Configuration
Maximize throughput on dedicated workstations:Balanced Configuration (Recommended)
Good default for most scenarios:~/.media-converter.yaml
Monitoring Output
The converter logs worker adjustments in real-time:Performance Considerations
When to Enable
Good Use Cases:- Large video batches with varying file sizes/complexities
- Shared systems where other processes may compete for resources
- Systems with limited memory relative to video file sizes
- Long-running conversions where system load fluctuates
- Small batches (< 10 videos) where overhead exceeds benefit
- Dedicated conversion servers with predictable workloads
- When using hardware acceleration (already resource-efficient)
Tuning Guidelines
- Set realistic bounds -
maxshould not exceed physical cores - Leave headroom - Set
cpu_highto 80-85% for system responsiveness - Monitor first - Run with defaults, then adjust based on observed behavior
- Balance thresholds - Keep
cpu_low≤ 60% ofcpu_highto prevent oscillation
Implementation Details
The adaptive system consists of three components (adaptive_workers.go):
ResourceMonitor (adaptive_workers.go:23-106)
Periodically samples system metrics:
- Runs in background goroutine with configurable interval
- Emits
ResourceSnapshotstructs on channel - Logs failures once per metric type to avoid spam
- Drops samples if consumer is behind (non-blocking)
AdaptiveLimiter (adaptive_limiter.go:7-79)
Thread-safe semaphore with dynamic limit adjustment:
Acquire()- Blocks until worker slot availableRelease()- Frees worker slot and signals waitersSetLimit(n)- Updates concurrency limit without interrupting active workers- Uses
sync.Condfor efficient wait/wake coordination
Adaptive Controller (adaptive_workers.go:110-187)
Decision engine that adjusts limiter based on snapshots:
- Maintains
highStreakandlowStreakcounters - Applies hysteresis to prevent rapid oscillation
- Respects configured min/max bounds
- Logs all limit changes with current metrics
The limiter never interrupts in-flight conversions. When reducing the limit, it simply prevents new workers from starting until active count drops below the new threshold.
Troubleshooting
Metrics Unavailable Warnings
max). Install required utilities or disable adaptive mode.
No Worker Adjustments
Check:- Verify
--adaptive-workersflag is enabled - Ensure thresholds are reachable (e.g.,
cpu_low < cpu_high) - Confirm resource metrics are being collected (no warnings in logs)
- Increase logging verbosity to see snapshot values
Excessive Oscillation
Symptoms: Workers constantly increasing/decreasing Solutions:- Widen threshold gap: Reduce
cpu_lowor increasecpu_high - Increase
interval_secondsfor less frequent adjustments - Raise
minto prevent dropping too low
Related Configuration
Performance Tuning
General performance optimization settings
Hardware Acceleration
GPU-based video encoding for efficiency