When a backup, video conversion or big build runs on the same server as your website, it competes for CPU and disk. Linux lets you tell the scheduler which processes matter more. nice values control CPU priority, and ionice controls disk priority. Used together, they keep heavy background jobs from slowing down your users.
Nice values
Every process has a nice value from −20 (highest priority) to 19 (lowest). The default is 0. A “nicer” process (higher number) is more polite. It yields CPU to others when they need it.
Nice values only matter when the CPU is contended. On an idle server, a nice 19 process still uses all available CPU.
See current values:
ps -eo pid,ni,pri,comm --sort=-ni | head
top # NI column
Start a command with a priority: nice
nice -n 19 tar -czf /backup/site.tar.gz /var/www/site
nice -n 10 ./build.sh
nice ./script.sh # default: +10
Only root can set negative values (higher priority):
sudo nice -n -5 ./important-job
Change a running process: renice
renice -n 15 -p 12345 # one process
renice -n 10 -u backupuser # all processes of a user
sudo renice -n -5 -p 12345 # raise priority (root only)
Normal users can only make their processes nicer, not less nice.
Disk priority: ionice
CPU isn’t usually the bottleneck for backups and file operations. Disk I/O is. ionice sets the I/O scheduling class:
| Class | Option | Meaning |
|---|---|---|
| Idle | -c3 |
Only gets disk time when nobody else needs it |
| Best-effort | -c2 -n0..7 |
Default class, 0 = highest within the class |
| Realtime | -c1 |
Always first. Root only, can starve the system |
ionice -c3 rsync -a /var/www/ /backup/www/
ionice -c2 -n7 -p 12345 # change a running process
Combine both for heavy background jobs:
nice -n 19 ionice -c3 tar -czf /backup/site.tar.gz /var/www/site
ionice classes are fully honoured by the BFQ scheduler. With mq-deadline or none, the default on many virtual and NVMe disks, the effect is limited. Check the scheduler with cat /sys/block/vda/queue/scheduler. For those, scheduling jobs off-peak or rate-limiting them (rsync --bwlimit, pv -L) is more reliable.
Cron jobs
30 3 * * * nice -n 19 ionice -c3 /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
See crontab.
systemd services and timers
Set priorities in the unit, so they apply however the service starts:
[Service]
Nice=10
IOSchedulingClass=idle
CPUSchedulingPolicy=batch
For stronger, guaranteed limits, use cgroup settings. They work even when nice values aren’t enough:
[Service]
CPUWeight=20 # default 100; lower = less CPU share under contention
IOWeight=20 # default 100
CPUQuota=50% # hard cap: at most half a core
CPUQuota limits the job even when the CPU is idle, so use it for jobs that must never hog the server. See systemd unit files and systemd timers.
Throttle a running service on the fly:
sudo systemctl set-property --runtime myjob.service CPUQuota=30%
Containers
docker run --cpus=1 --cpu-shares=256 …
docker update --cpus=0.5 container-name
See Docker CPU and memory limits.
Practical examples
| Job | Command |
|---|---|
| Nightly backup | nice -n 19 ionice -c3 backup.sh |
| Image or video processing queue | Nice=10 + CPUWeight=50 in the worker unit |
| Compiling on a production box | nice -n 19 make -j2 |
| Database dump | nice -n 10 ionice -c2 -n7 mysqldump … |
| Log compression (logrotate) | Often already niced. Check its timer |
What nice doesn’t do
- It doesn’t limit memory. Use
MemoryMax=or container limits. - It doesn’t stop a process from using an idle CPU. Use
CPUQuotafor a hard cap. - Negative nice values on everything you care about cancel each other out. Lower the priority of background work instead of raising everything else.
Quick reference
| Task | Command |
|---|---|
| Start low priority | nice -n 19 cmd |
| Change running | renice -n 15 -p PID |
| Disk idle class | ionice -c3 cmd |
| Both | nice -n 19 ionice -c3 cmd |
| In systemd | Nice=10, IOSchedulingClass=idle |
| Hard CPU cap | CPUQuota=50% |
| See nice values | ps -eo pid,ni,comm |
Related: load average and iostat.