Skip to main content
The threads command analyzes sample distribution across threads, showing which threads are active and consuming resources. It supports optional grouping to aggregate thread pools.

Usage

ap-query threads <file> [flags]

What It Shows

A table of threads ranked by sample count, showing:
  • Thread name
  • Sample count
  • Percentage of total samples
With --group, shows:
  • Thread group name (normalized from thread pool patterns)
  • Number of threads in the group
  • Aggregate sample count
  • Percentage of total samples

Flags

--top
int
default:"0"
Limit output rows. Default 0 means unlimited (show all threads).
--group
boolean
Group threads by normalized name, aggregating thread pools. Useful for understanding thread pool behavior.Grouping rules:
  • Removes numeric segments: pool-1-thread-2pool-thread
  • Strips trailing digits: worker-thread-5worker-thread
  • Handles common separators: -, _, #
  • Examples:
    • http-nio-8080-exec-1http-nio-exec
    • GC Thread#54GC Thread
    • CompilerThread0CompilerThread

Shared Flags

-e, --event
string
default:"cpu"
Event type: cpu, wall, alloc, lock, or hardware counter name.
-t, --thread
string
Filter to threads containing this substring (applied before grouping).
--from
duration
Start of time window (JFR only).
--to
duration
End of time window (JFR only).
--no-idle
boolean
Remove idle leaf frames from analysis.

Examples

Basic Thread List

ap-query threads profile.jfr
THREAD                             SAMPLES     PCT
http-nio-8080-exec-1                  1824  15.1%
http-nio-8080-exec-2                  1653  13.7%
ScheduledExecutor-1                    892   7.4%
GC Thread#0                            543   4.5%
http-nio-8080-exec-3                   498   4.1%
CompilerThread0                        432   3.6%
ScheduledExecutor-2                    398   3.3%
GC Thread#1                            356   3.0%
http-nio-8080-exec-4                   312   2.6%
...

Grouped by Thread Pool

ap-query threads profile.jfr --group
GROUP                              SAMPLES     PCT
http-nio-exec (24 threads)            9432  78.3%
ScheduledExecutor (4 threads)         1456  12.1%
GC Thread (8 threads)                  987   8.2%
CompilerThread (2 threads)             168   1.4%
Use --group to understand thread pool utilization and identify which pools are most active.

Top Threads Only

ap-query threads profile.jfr --top 5
Show only the top 5 threads by sample count.

Top Groups Only

ap-query threads profile.jfr --group --top 3
Show only the top 3 thread groups.

Filter Specific Threads

ap-query threads profile.jfr --thread worker
THREAD                             SAMPLES     PCT
worker-thread-1                       2156  17.9%
worker-thread-2                       1987  16.5%
worker-thread-3                       1543  12.8%
worker-task-processor-1                432   3.6%

Wall-Clock Thread Analysis

ap-query threads profile.jfr --event wall
Show thread distribution for wall-clock time (includes blocking/waiting).

Compare CPU vs Wall by Thread

Run both and compare:
ap-query threads profile.jfr --event cpu --group
ap-query threads profile.jfr --event wall --group
Threads with high wall% but low CPU% are likely blocked on I/O or locks. Threads with similar CPU% and wall% are compute-bound.

Reading the Output

Individual Threads

http-nio-8080-exec-1      1824   15.1%
This thread was sampled 1,824 times, representing 15.1% of all samples.

Grouped Threads

http-nio-exec (24 threads)  9432  78.3%
The http-nio-exec thread pool has 24 threads that collectively account for 9,432 samples (78.3% of total).

Thread Grouping Rules

Grouping normalizes thread names by:
  1. Splitting on separators: -, _, #
  2. Removing numeric segments: 1, 42, 8080
  3. Trimming trailing digits: thread5thread
Examples:
OriginalGrouped
pool-1-thread-2pool-thread
http-nio-8080-exec-1http-nio-exec
GC Thread#54GC Thread
CompilerThread0CompilerThread
worker-5worker
Thread names that don’t follow common patterns (no numbers or separators) remain unchanged and won’t be grouped.

No Thread Info

If the profile lacks thread information:
ap-query threads profile.jfr
no thread info in this file
This can happen with:
  • Collapsed-stack text files (no metadata)
  • Some pprof profiles
  • Profiles with thread tracking disabled

When to Use

Thread Pool Sizing

Identify if thread pools are over/under-provisioned

Workload Distribution

See if work is balanced across threads

Blocking Detection

Compare CPU vs wall events to find blocked threads

GC Analysis

See how much time GC threads consume

Practical Examples

Find Underutilized Thread Pool

ap-query threads profile.jfr --group
If a thread pool has many threads but low sample count, it’s underutilized.

Identify Hot Thread

ap-query threads profile.jfr --top 1
The top thread is consuming the most resources. Investigate with:
ap-query hot profile.jfr --thread <top-thread-name>

Detect Thread Imbalance

If individual threads in the same pool have vastly different sample counts, work is not balanced:
worker-1    5000   41.5%   <- doing most work
worker-2     300    2.5%
worker-3     250    2.1%
This suggests sticky routing or long-running tasks.

Integration with Other Commands

Threads command helps identify threads to investigate:
# 1. Find hot threads
ap-query threads profile.jfr --top 3

# 2. Analyze what the hottest thread is doing
ap-query hot profile.jfr --thread "http-nio-8080-exec-1"

# 3. Deep dive into that thread's call tree
ap-query tree profile.jfr --thread "http-nio-8080-exec-1"

See Also

  • info - Shows thread distribution as part of comprehensive triage
  • hot - Combine with --thread flag to analyze specific threads
  • timeline - Time-based analysis with thread filtering

Build docs developers (and LLMs) love