How to check thread count per process in Linux

Tech reviewed: Deepak Prasad
How to check thread count per process in Linux

Linux can show a process as one line, but that process may have many execution threads inside it. When you troubleshoot Java, Python, web servers, databases, or any service with a thread pool, checking only the process PID is not always enough. You often need to know how many threads the process owns and which thread IDs are visible to the kernel.

This guide shows tested commands to check thread count per process in Linux. The sample outputs below were captured on a Linux host using a temporary Python process with 5 threads: 1 main thread and 4 worker threads.


Quick commands

Replace <PID> with the process ID you want to inspect.

Goal Command
Count threads from /proc grep '^Threads:' /proc/<PID>/status
Count thread directories find /proc/<PID>/task -mindepth 1 -maxdepth 1 -type d | wc -l
Count threads with ps ps -o nlwp= -p <PID>
Show each thread with ps ps -T -p <PID> -o pid,spid,psr,stat,comm
Show each thread with top top -H -p <PID>
Show thread tree pstree -p <PID>

For process basics and PID discovery, see how to list processes in Linux. For CPU/core/thread terminology, see CPU, processors, cores and threads explained.


Prepare a test process

You can test the commands with any existing process. For repeatable output, this article uses the following temporary Python process. It starts 4 worker threads and then sleeps. The total thread count should be 5 because the process also has one main thread.

console
$ python3 - <<'PY' &
import threading, time, os
print(os.getpid(), flush=True)
for i in range(4):
    threading.Thread(target=time.sleep, args=(90,), name=f"worker-{i}").start()
time.sleep(90)
PY
$ PID=$!
$ echo "$PID"
54699

Keep this process running while you test the commands below. Stop it at the end with:

console
$ kill "$PID"

Method 1: Count threads from /proc/<PID>/status

The quickest count-only method is the Threads: field in /proc/<PID>/status:

console
$ grep '^Threads:' /proc/$PID/status
Threads:	5

For scripts, print only the number:

console
$ awk '/^Threads:/ {print $2}' /proc/$PID/status
5

Use this method when you only need the total thread count and do not need individual thread IDs.


Method 2: List thread IDs under /proc/<PID>/task

Linux exposes each thread of a process under /proc/<PID>/task/. Each directory name is a thread ID.

console
$ ls /proc/$PID/task
54699
54701
54702
54703
54704

Count those directories:

console
$ find /proc/$PID/task -mindepth 1 -maxdepth 1 -type d | wc -l
5

The first ID, 54699, is the process ID and also the main thread ID for this process. The remaining IDs are worker threads.

This method is useful when you want to inspect per-thread files such as /proc/<PID>/task/<TID>/status.


Method 3: Count threads with ps and NLWP

The ps command can print NLWP, which means the number of lightweight processes. For Linux process inspection, this is the process thread count.

console
$ ps -o pid,ppid,nlwp,comm -p $PID
    PID    PPID NLWP COMMAND
  54699   54677    5 python3

For script output, print only NLWP:

console
$ ps -o nlwp= -p $PID
   5

You can also count the thread rows from ps thread mode:

console
$ ps hH p $PID | wc -l
5

For a broader introduction to ps, see ps command examples in Linux.


Method 4: Show each thread with ps -T

Use ps -T when you want one line per thread for a specific PID:

console
$ ps -T -p $PID -o pid,spid,psr,stat,comm
    PID    SPID PSR STAT COMMAND
  54699   54699   1 Sl   python3
  54699   54701   0 Sl   python3
  54699   54702   0 Sl   python3
  54699   54703   0 Sl   python3
  54699   54704   0 Sl   python3

Important columns:

Column Meaning
PID Process ID, also called the thread-group ID for the process
SPID Thread ID shown by this ps format
PSR CPU where the thread last ran
STAT Process/thread state
COMM Command name

In other ps formats, the thread ID may appear as LWP instead of SPID.


Method 5: Show all thread rows with ps -eLf

The ps -eLf command shows thread information for the whole system. Filter it to one PID when you only want one process:

console
$ ps -eLf | awk -v pid="$PID" 'NR==1 || $2==pid {print}'
UID          PID    PPID     LWP  C NLWP STIME TTY          TIME CMD
root       54699   54677   54699  1    5 17:02 ?        00:00:00 python3 -
root       54699   54677   54701  0    5 17:02 ?        00:00:00 python3 -
root       54699   54677   54702  0    5 17:02 ?        00:00:00 python3 -
root       54699   54677   54703  0    5 17:02 ?        00:00:00 python3 -
root       54699   54677   54704  0    5 17:02 ?        00:00:00 python3 -

Here LWP is the thread ID and NLWP is the total number of threads in the process. Every row for this PID reports NLWP=5.


Method 6: Show threads with pstree

The pstree command is helpful when you want a visual tree. Threads are displayed in braces under the process:

console
$ pstree -p $PID
python3(54699)-+-{python3}(54701)
               |-{python3}(54702)
               |-{python3}(54703)
               `-{python3}(54704)

The process is python3(54699) and the worker threads are shown as {python3} with their thread IDs.


Method 7: Show threads with top -H

Use top -H to show individual threads. For an interactive view, run:

console
$ top -H -p $PID

For a one-time output that can be pasted into logs or tickets, use batch mode:

console
$ top -H -b -n 1 -p $PID | sed -n '1,12p'
top - 17:02:33 up  3:07, 12 users,  load average: 6.30, 7.15, 7.11
Threads:   5 total,   0 running,   5 sleeping,   0 stopped,   0 zombie
%Cpu(s): 35.7 us, 35.7 sy,  0.0 ni, 25.0 id,  0.0 wa,  0.0 hi,  3.6 si,  0.0 st 
MiB Mem :   8467.0 total,    395.9 free,   4821.5 used,   3619.4 buff/cache     
MiB Swap:   1024.0 total,    316.1 free,    707.9 used.   3645.6 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  54699 root      20   0  315356   9228   5928 S   0.0   0.1   0:00.03 python3
  54701 root      20   0  315356   9228   5928 S   0.0   0.1   0:00.00 python3
  54702 root      20   0  315356   9228   5928 S   0.0   0.1   0:00.00 python3
  54703 root      20   0  315356   9228   5928 S   0.0   0.1   0:00.00 python3
  54704 root      20   0  315356   9228   5928 S   0.0   0.1   0:00.00 python3

The Threads: line confirms that top is showing thread-level output for this PID. For more top usage, see top command examples in Linux.


Check Linux thread and process limits

Linux does not usually enforce a separate fixed thread limit per process. Threads consume system resources and are limited by a combination of kernel-wide task limits, per-user limits, memory, and application-specific settings.

Check the kernel-wide thread ceiling:

console
$ cat /proc/sys/kernel/threads-max
67016

Check the maximum PID value before PID numbers wrap:

console
$ cat /proc/sys/kernel/pid_max
4194304

Check the per-user process limit for the current shell:

console
$ ulimit -u
33508

These values are related but not identical:

Limit What it controls
kernel.threads-max Approximate maximum number of tasks/threads the kernel allows system-wide
kernel.pid_max Maximum numeric PID/TID value before wraparound
ulimit -u Maximum processes/threads available to the current user, depending on PAM and shell limits

If an application cannot create more threads, check all three values plus memory pressure and application-level thread pool settings. For global kernel tuning context, see sysctl performance settings.


PID, TID, LWP, SPID and NLWP

Thread output is confusing because tools use different labels:

Term Meaning in this context
PID Process ID. For a multithreaded process, this is also the thread-group leader ID.
TID Thread ID. Each thread has its own ID under /proc/<PID>/task/.
LWP Lightweight process. In ps -eLf, this is the thread ID.
SPID Thread ID label used by some ps -T output formats.
NLWP Number of lightweight processes, meaning number of threads in the process.

So when ps shows PID=54699 and several LWP or SPID values, it is showing one process with multiple schedulable threads.


Troubleshooting

Problem Likely cause Fix
/proc/<PID>/status is missing The process exited or the PID is wrong Recheck the PID with ps or pgrep
Thread count changes between commands Threads are being created or destroyed while you inspect Repeat the command or monitor with top -H
ps -T shows only one row The process is single-threaded, or the wrong PID was used Confirm with /proc/<PID>/status
top -H shows many rows Thread mode is enabled and each thread is displayed separately Press H in interactive top to toggle thread mode
Thread count is high but CPU is low Threads may be sleeping or waiting for I/O Check STAT, %CPU, wait channels, and application logs

For CPU-side troubleshooting, see how to check CPU utilization in Linux. For memory impact, see how to check memory usage per process in Linux.


Frequently Asked Questions

1. What is the fastest way to check thread count for one Linux process?

Use grep '^Threads:' against /proc/PID/status or run ps -o nlwp= -p PID. Both return the number of threads for that process.

2. What is NLWP in ps output?

NLWP means number of lightweight processes. In Linux ps output, it is the thread count for the process.

3. What is the difference between PID, TID, LWP and SPID?

PID identifies the process or thread-group leader. TID identifies an individual thread. ps often labels thread IDs as LWP or SPID depending on the output format.

4. Why does the proc task directory have more than one entry?

Each entry under the proc task directory for a PID represents one thread in that process. A single-threaded process normally has one entry; a multithreaded process has more than one.

5. Does Linux have a separate per-process thread limit?

Linux usually enforces task limits through system-wide settings such as kernel.threads-max and kernel.pid_max plus per-user limits such as ulimit -u. Applications may also impose their own thread pool limits.

6. How can I see individual threads in top?

Use top -H -p PID interactively, or top -H -b -n 1 -p PID for a one-time batch snapshot.

Summary

Use grep '^Threads:' /proc/<PID>/status or ps -o nlwp= -p <PID> when you only need the thread count. Use ps -T, ps -eLf, pstree -p, or top -H when you need to see individual thread IDs.

The most important detail is that Linux exposes threads as schedulable tasks. That is why the same process can have one PID but multiple TIDs, LWPs, or SPIDs in command output.


References

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, …

  • Red Hat Certified System Administrator in Red Hat OpenStack
  • Certified Kubernetes Application Developer (CKAD)
  • Red Hat Certified Specialist in Ansible Automation
  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security