taskset Cheatsheet - CPU Affinity & Core Pinning Guide
taskset answers one question: which CPUs is this process allowed to run on. Three situations call for it. Latency spikes that do not come with high CPU utilisation, often caused by a multi-threaded process migrating across physical cores or touching memory on a remote NUMA node. Benchmark runs where you want to measure the code rather than the scheduler. And shared machines where pinning your workload to idle cores keeps a noisy neighbour from starving it. The mechanism is narrow, it just rewrites the task CPU affinity mask, which is why you can confirm the result at any time by reading Cpus_allowed_list from /proc/<pid>/status or from jobs -l. Pinning is not automatically faster: too few cores cuts parallelism, and pinning only the main thread of a threaded process achieves little, so the sheet lines up list format, hex masks, retargeting running processes, NUMA commands and the isolcpus kernel parameter for comparison.
Typical Use Case
For performance engineers isolating a noisy neighbour. taskset pins a process to a set of logical CPUs, which is the cheapest possible scheduling intervention - no kernel change, no cgroup, instant and reversible on a running PID. This sheet covers reading and writing affinity masks in both list and hexadecimal form, batch-changing every PID of a service, and the important boundary: taskset binds CPUs, not NUMA nodes, and inside a container it only sees the CPUs the cgroup actually granted.
Basic Usage 6
taskset -p <pid>taskset -c -p <pid>taskset -c 0,1 <command>taskset -c 0-3 <command>taskset -p <mask> <pid>taskset -cp 0,1 <pid>CPU Mask & List Format 7
0x000000010x000000030x0000000f-c 0-c 0,2,4-c 0-3,8-11taskset -c 0xff <command>Pin Running Processes 4
taskset -cp 0 $(pgrep nginx)for p in $(pgrep -f app); do taskset -cp 0-3 $p; donetaskset -cp 0-3 <pid>taskset -ap 0-1 <pid>Affinity & System Info 5
cat /proc/<pid>/status | grep Cpus_allowedcat /sys/devices/system/cpu/onlinenproclscpulscpu | grep NUMANUMA Optimization 5
numactl --hardwarenumactl -c 0 -m 0 ./appnumactl --cpunodebind=0 --membind=0 ./appnumastat -p <pid>numactl --interleave=all ./appPractical Scenarios 5
taskset -c 0-3 ./cpu_intensive_apptaskset -c 4-7 ./realtime_apptaskset -c 0 nginxtaskset -c 1,2 mysqlisolcpus=2,3Related Tools 5
htoptop -1mpstat -P ALL 1pidstat -t -p <pid> 1cset shield -c 4-7Parameter matrix
| Parameter | Effect | Example |
|---|---|---|
-c <list> | CPU-list form of the affinity mask; readable, accepts 0,1, 0-3 and mixed ranges | taskset -c 0-3 <command> |
-p <mask> <pid> | Read or rewrite the affinity of a running process, no restart needed | taskset -cp 0,1 <pid> |
0x0000000f | Hexadecimal mask form, equivalent to CPUs 0-3; taskset parses masks by default | taskset -c 0xff <command> |
-a | Apply to every thread of the process, not just the main one - required for threaded services | taskset -ap 0-1 <pid> |
Cpus_allowed_list | The observable field in /proc/<pid>/status that confirms the binding took effect | cat /proc/<pid>/status | grep Cpus_allowed |
Common pitfalls
Symptomtaskset -cp 0,1 <pid> fails with "Invalid argument", or binding an out-of-range CPU fails outright.
CauseInside a container you see host CPU numbers but the real allowance comes from the cgroup; tasks outside it are refused by the kernel.
FixCheck cat /sys/devices/system/cpu/online and cat /proc/<pid>/status | grep Cpus_allowed first, then pick from that set.
SymptomAfter binding a threaded process, htop still shows threads on other cores.
CauseWithout -a only the main thread (the thread-group leader) is affected.
FixUse taskset -ap 0-1 <pid> to cover every thread.
SymptomPinning made latency worse because the process keeps reading memory across nodes.
Causetaskset pins CPUs but not memory; the process runs on node 1 cores while touching node 0 memory.
FixUse numactl -c 0 -m 0 ./app, or the full form numactl --cpunodebind=0 --membind=0 ./app.
Symptomtaskset -c 0-3 <command> refuses to start, saying the affinity set must contain an online CPU.
CauseThe range contains offline CPUs, or online CPU numbers are not contiguous from 0.
FixRead the real set with nproc and cat /sys/devices/system/cpu/online, then re-pick the values.
Troubleshooting
1Confirm the binding actually took effect
cat /proc/<pid>/status | grep Cpus_allowedCpus_allowed is the mask form, Cpus_allowed_list the list form; both must match taskset -p output.
2Change affinity for every process of a service
for p in $(pgrep -f app); do taskset -cp 0-3 $p; donepgrep -f matches the command line; without -a only the main thread moves, so use taskset -ap 0-3 $p.
3Survey CPU and NUMA topology before pinning
nproc && lscpu | grep NUMA && numactl --hardwareYou need the real online CPU set and node count, otherwise the mask is illegal.
4Watch per-core usage after pinning
mpstat -P ALL 1Requires sysstat. Work should spread only across the intended cores; pidstat -t -p <pid> 1 shows thread-level detail.
Tips
- CPU affinity reduces cache misses and boosts performance, but over-pinning can cause uneven load.
- Real-time apps (HFT, A/V processing) suit isolated cores.
- Under NUMA, binding CPU and memory nodes cuts cross-node access latency.
- taskset -c's CPU-list format is more readable than hex masks; use it daily.
- The isolcpus kernel param isolates CPUs at boot — more thorough than taskset but needs a reboot.
- Multi-threaded processes need -a to set all threads, or only the main thread is affected.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us