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.
$ 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:
$ kill "$PID"
Method 1: Count threads from /proc/<PID>/status
The quickest count-only method is the Threads: field in
/proc/<PID>/status:
$ grep '^Threads:' /proc/$PID/status
Threads: 5
For scripts, print only the number:
$ 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.
$ ls /proc/$PID/task
54699
54701
54702
54703
54704
Count those directories:
$ 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.
$ ps -o pid,ppid,nlwp,comm -p $PID
PID PPID NLWP COMMAND
54699 54677 5 python3
For script output, print only NLWP:
$ ps -o nlwp= -p $PID
5
You can also count the thread rows from ps thread mode:
$ 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:
$ 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:
$ 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:
$ 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:
$ top -H -p $PID
For a one-time output that can be pasted into logs or tickets, use batch mode:
$ 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:
$ cat /proc/sys/kernel/threads-max
67016
Check the maximum PID value before PID numbers wrap:
$ cat /proc/sys/kernel/pid_max
4194304
Check the per-user process limit for the current shell:
$ 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.

