The kernel's scheduler already handles the normal case - sharing the CPU fairly among everything runnable - without any intervention. nice and renice exist for the exception: deliberately telling the scheduler that one process matters less (or more) than its peers.

The niceness scale

Niceness runs from -20 (highest priority) to 19 (lowest priority), with 0 as the default for anything started normally. Confusingly, a lower niceness number means higher priority - the name refers to how "nice" a process is being to everything else: a process at niceness 19 is being very nice, yielding the CPU readily to others.

ps -eo pid,ni,comm | head -5   # niceness column ("ni") for running processes
top                             # niceness shown live as "NI"

Starting a process with a chosen priority

nice -n 10 ./backup-script.sh     # start with lower priority (niceness 10)
nice -n -5 ./latency-sensitive.sh # start with higher priority (needs root/CAP_SYS_NICE)

Only root (or a process with the CAP_SYS_NICE capability) can set a negative niceness - lowering an already-running process's priority is unprivileged, but raising it above default requires elevated rights, to stop ordinary users starving each other's processes on a shared system.

Changing a process that's already running

renice -n 15 -p 4821       # lower priority of PID 4821
sudo renice -n -10 -p 4821 # raise priority (root required)

A common real-world use: a backup or batch job discovered to be degrading interactive performance on a shared machine can be deprioritized in place with renice, without stopping and restarting it.

ionice: the same idea for disk I/O

CPU niceness doesn't affect how much disk I/O bandwidth a process gets - ionice is the equivalent knob for that, with its own scheduling classes:

ionice -c3 -p 4821          # class 3 (idle): only use disk I/O when nothing else wants it
ionice -c2 -n 7 rsync -a /data /backup/   # class 2 (best-effort), low priority within it

Class 3 (idle) is the useful one for background jobs like backups or updatedb - it lets them use the disk freely whenever the system is otherwise quiet, and get out of the way immediately once something else needs it.

Where this stops being enough

nice/ionice are relative hints within the default scheduler, not hard limits - a niceness-19 process still gets some CPU time if nothing else wants it, and there's no way to cap a process at, say, "never use more than 20% of one core." For actual resource limits and guarantees, the kernel's cgroups mechanism is the modern answer - systemd uses it automatically to sandbox services (see systemd and Services), and exposes it directly through unit directives like CPUQuota= and MemoryMax= for anything that needs a hard ceiling rather than a soft hint. It's also the same mechanism containers are built on - see Containers vs. Virtual Machines.