Tutorial: GNU parallel tutorial.
sudo dnf -y install parallel # or apt-get install parallel
ls *.jpg | parallel convert {} -resize 50% small/{} # {} = the input; one job per CPU core by default
parallel -j 4 gzip ::: *.log # 4 jobs at a time, arguments after :::
cat hosts.txt | parallel -j 8 ssh {} uptime
find . -name '*.wav' -print0 | parallel -0 ffmpeg -i {} {.}.mp3 # {.} = name without extension
parallel --bar -j 8 ./process.sh ::: data/*.csv # progress bar
parallel --dry-run echo ::: a b c # show commands without running
parallel -S server1,server2 ./job.sh ::: 1 2 3 4 # distribute over SSH hosts
Output from concurrent jobs is kept together per job (grouped), unlike backgrounded shell loops, which interleave. Prefer it over xargs -P when you need retries (--retries), logs (--joblog), or remote execution. See xargs.