Datasets and jq builtins
A resource document of the JProfiler MCP server. Back to the tool and resource reference.
For agent consumption, this page is also available as raw Markdown.
Content of the MCP resource jprofiler://datasets of the JProfiler MCP server, see the tool and resource reference for the full list of tools and resources.
All datasets of the query tool with their arguments, row formats and examples, and the jq builtins
available in the query expression. Availability depends on the recorded data, check_status reports
the catalog of the current session with availability flags and session-specific notes.
performance.hotspots
Aggregated hotspots for a subsystem, sorted by time. Pass the expansionId of a hotspot to the expand(expansionId) jq builtin for its back trace. If the top hotspot is in a JDK or framework package, drill down to find the application method responsible for calling it before answering.
Args: subsystem (required top-level parameter, from availableSubsystems; automatic if only one subsystem was recorded), threadStatus (optional, one of all, running, waiting, blocked, net_io, default running for cpu and all (wall clock) for probes), aggregation (optional, one of method, class, package, component, default method), thread (optional, 'all' default, 'virtual' or a thread id from threads.list), threadGroup (optional, a group from threads.list, cannot be combined with thread), packageFilter (optional string, comma-separated class filter on the method frames of cpu views and probe call trees), payloadFilter (optional string, comma-separated contains filter on payload descriptions like SQL statements or URLs for probe subsystems, applied before the row cutoffs), metric (optional, 'duration' default or a metric from the probeMetrics section of check_status for probe subsystems that record a size or token measurement, the value properties are then named by the metric unit, for example bytes instead of micros)
Rows: hotspots[]: {method, micros, count, percent, expansionId} - probe hotspot rows are keyed by name (the payload description, e.g. the SQL statement or file name) instead of method - type marks non-method nodes: url_split (HTTP server probe, method is "HTTP:
Example: .hotspots[] | select(.method == "com.mycompany.SomeClass") | {micros, percent}
Requires: performance data: record cpu or probe subsystems, then check_status again
performance.callTree
Structural call tree for a subsystem. Pass the expansionId of a node to the expand(expansionId) jq builtin for its subtree. If the top node is in a JDK or framework package, drill down to find the application method responsible for calling it before answering. With async tracking recorded, the call tree header's inlinedExecutionSites reports how many execution sites were inlined, 0 comes with a warning.
Args: subsystem (required top-level parameter, from availableSubsystems; automatic if only one subsystem was recorded), threadStatus (optional, one of all, running, waiting, blocked, net_io, default running for cpu and all (wall clock) for probes), aggregation (optional, one of method, class, package, component, default method), thread (optional, 'all' default, 'virtual' or a thread id from threads.list), threadGroup (optional, a group from threads.list, cannot be combined with thread), packageFilter (optional string, comma-separated class filter on the method frames of cpu views and probe call trees), payloadFilter (optional string, comma-separated contains filter on payload descriptions like SQL statements or URLs for probe subsystems, applied before the row cutoffs), metric (optional, 'duration' default or a metric from the probeMetrics section of check_status for probe subsystems that record a size or token measurement, the value properties are then named by the metric unit, for example bytes instead of micros)
Rows: callTree[]: {method, micros, count, percent, children[] (omitted on leaf nodes, iterate as (.children // [])[]), expansionId, childrenBelowCutoff, expandableChildren} - deeper levels come from expand(expansionId) on a node, not from recursive children projections - type marks non-method nodes: url_split (HTTP server probe, method is "HTTP:
Example: .callTree[] | select(.percent > 50) | {method, percent}
Requires: performance data: record cpu or probe subsystems, then check_status again
threads.list
All threads of the recording with their per-state time breakdown: the lookup table for the thread and threadGroup parameters of the performance datasets and for the threadId values of the monitor datasets. runnableMicros/waitingMicros/blockedMicros/netIoMicros show where each thread's time went - high blockedMicros points to lock contention (monitor.stats), high netIoMicros to slow network, file or database I/O.
Args: limit (optional integer, default 1000, max 10000, threads with the earliest start time are kept)
Rows: threads[]: {threadId, name, group, startSeconds, endSeconds (dead threads only), state, creatingThreadId, creatingThread, runnableMicros, waitingMicros, blockedMicros, netIoMicros, cpuMicros, virtualAggregator}, plus threadsTotal when the list was capped - the per-state time fields are only present when thread status history was recorded, cpuMicros only with instrumentation CPU time measurement, the per-state times are counted from the first status sample and sum to less than the thread lifetime for threads that were already alive when the recording started, virtualAggregator marks the single row aggregating all virtual threads, seconds are relative to the recording start
Example: .threads | sort_by(-.blockedMicros) | .[0:5] | map({threadId, name, blockedMicros})
Requires: thread data: recorded in JProfiler sessions and present in JFR recordings, not available in plain heap dumps
heap.classes
Class histogram of the heap dump: instances and shallow size per class, sorted by size.
Args: packageFilter (optional string, comma-separated packages to focus on), generation (optional, new or old: objects allocated after or before the last markHeap action, or after allocation recording started when no mark was set)
Rows: classes[]: {name, count, shallowSize}, plus classesTotal when the histogram was capped
Example: .classes[] | select(.name == "java.lang.String") | .count
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
heap.biggestObjects
Biggest objects in the heap dump by retained size.
Args: packageFilter (optional string, comma-separated packages to focus on), generation (optional, new or old: objects allocated after or before the last markHeap action, or after allocation recording started when no mark was set)
Rows: biggestObjects[]: {id, class, retainedSize, shallowSize}, plus biggestObjectsTotal when the list was capped
Example: .biggestObjects | sort_by(-.retainedSize) | .[0:3] | map({id, class, retainedSize})
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
heap.instances
Instances of a single class or of an exposed object set in the heap dump, sorted by retained size.
Args: class (required top-level parameter, a name from heap.classes) or set (an object set from a previous heap result), limit (optional integer, default 200, max 2000), value filter (optional): field is a field path like customer.name or orders[].id, op is one of contains, startsWith, endsWith, equals, regexp (string fields), null, nonNull (object fields) or equals with from and to for a numeric range, value is the comparison value, ignoreCase (optional boolean) for string comparisons (only with class), filterScript (optional): a Java script per object for predicates the value filter cannot express, filterPath (optional) navigates a field path before the script runs - read the jprofiler://api/heap-scripts resource for the script API, generation (optional, new or old: objects allocated after or before the last markHeap action, or after allocation recording started when no mark was set)
Rows: instances[]: {id, class, name, shallowSize, retainedSize, ageMillis}, plus instancesTotal when the list was capped - for the combined size of the complete set beyond the cap use heap.sizes with the same class and filter; the top-level set value exposes the (filtered) object set for heap.sizes, heap.inspectionResult and the referrersByClass/referencesByClass builtins
Example: .instances[] | sort_by(-.retainedSize) | .[0:5] | map({id, name, retainedSize})
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
heap.sizes
Combined size analysis of a complete object set - the dataset form of the sizes() builtin for a whole class with optional value filter, filterScript and generation, or for an exposed object set via the set parameter. Unlike sizes([ids]) it covers the complete filtered set, not only the rows delivered within the instance limit of heap.instances.
Args: class (required top-level parameter, a name from heap.classes), value filter (optional): field is a field path like customer.name or orders[].id, op is one of contains, startsWith, endsWith, equals, regexp (string fields), null, nonNull (object fields) or equals with from and to for a numeric range, value is the comparison value, ignoreCase (optional boolean) for string comparisons, filterScript (optional): a Java script per object for predicates the value filter cannot express, filterPath (optional) navigates a field path before the script runs - read the jprofiler://api/heap-scripts resource for the script API - or set (optional top-level parameter, an object set from a previous heap result) for the size analysis of that set, generation (optional, new or old: objects allocated after or before the last markHeap action, or after allocation recording started when no mark was set)
Rows: a single object: {count, shallowBytes, retainedBytes, deepBytes} - retainedBytes is the impact number, what would be freed if these objects became unreachable; deepBytes is the upper bound, including objects shared with the rest of the heap
Example: .
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
heap.inspections
Catalog of heap inspections (wasted memory from strings, arrays and primitive wrappers, class loader analytics, thread locals, reference anomalies).
Rows: inspections[]: {id, description}
Example: .inspections | map(.id)
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
heap.inspectionResult
Result groups of one inspection: identifier with instance count and shallow size per group. Not cached, each query re-calculates. Without a class, packageFilter or set the whole heap is inspected. The custom_grouping inspection groups objects by the key its groupScript returns.
Args: inspection (required top-level parameter, an id from heap.inspections), class (optional, restricts the inspection to instances of one class), packageFilter (optional, comma-separated packages to inspect), set (optional, an object set from a previous heap result to inspect instead of the whole heap), groupScript (required for custom_grouping, a Java script returning the group key per object)
Rows: groups[]: {identifier, count, shallowSize, set} - the set of a group feeds the set parameter of heap.sizes, heap.instances and heap.inspectionResult and the referrersByClass/referencesByClass builtins; inspections without groups return class rows and one top-level set for their whole result set
Example: .groups | sort_by(-.shallowSize) | .[0:5]
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
heap.objectCounts
Class histogram from JFR object_count events, with sizes per recording dump.
Args: packageFilter (optional string, comma-separated packages to focus on)
Rows: classes[]: {name, count[], totalSize[]}
Example: .classes[] | select(.name == "java.lang.String") | .count
Requires: a JFR recording with object_count events or a JFR snapshot
allocation.hotspots
Allocation hot spots over the entire recording, including objects that have already been garbage collected. Sampled data: allocation events may be sampled by the source recording mechanism, counts and bytes are estimates and small counts are unreliable.
Args: aggregation (optional, one of method, class, package, component, default method)
Rows: hotspots[]: {method, bytes, count, percent, id} - expand back traces with the expand jq builtin, or pass the id to allocatedClasses for what is allocated there - with aggregation, rollup rows use the level as the key (class, package or component) instead of method
Example: .hotspots | sort_by(-.bytes) | .[0:10] | map({method, bytes, percent})
Requires: performance data: record cpu or probe subsystems, then check_status again
allocation.callTree
Allocation call tree over the entire recording. Sampled data: allocation events may be sampled by the source recording mechanism, counts and bytes are estimates and small counts are unreliable.
Args: aggregation (optional, one of method, class, package, component, default method)
Rows: callTree[]: {method, bytes, count, percent, id, callers[] (omitted on leaf nodes, iterate as (.callers // [])[])} - depth-limited, expand nodes with the expand jq builtin, allocatedClasses(id) shows the classes allocated at a node - in expand output, callers[] ends with a {capped, hiddenCallers} marker row when branches were pruned (below 1% of the expanded value or beyond the row cap) and moreAvailable replaces callers[] at the depth limit - with aggregation, rollup rows use the level as the key (class, package or component) instead of method
Example: .callTree | .[0:5] | map({method, bytes, callers: (.callers | length)})
Requires: performance data: record cpu or probe subsystems, then check_status again
heap.allocationHotspots
Allocation hot spots of the objects in a heap scope that were live at heap dump time. Only survivors are included, already collected objects are not. bytes is the shallow size of the surviving objects, not their retained size, for retention impact use the objectsAllocatedAt or heap.sizes builtins. See allocation.hotspots for the recording-wide view. Sampled data: allocation events may be sampled by the source recording mechanism, counts and bytes are estimates and small counts are unreliable.
Args: class or packageFilter (optional top-level parameters, restrict the analysis to one class or package), aggregation (optional, one of method, class, package, component, default method)
Rows: hotspots[]: {method, bytes, count, percent, id} - pass the id to the objectsAllocatedAt jq builtin for the biggest instances or to allocatedClasses for the class histogram - with aggregation, rollup rows use the level as the key (class, package or component) instead of method
Example: .hotspots | sort_by(-.bytes) | .[0:10] | map({method, bytes})
Requires: performance data: record cpu or probe subsystems, then check_status again
heap.allocationCallTree
Allocation call tree of the objects in a heap scope that were live at heap dump time. bytes is the shallow size of the surviving objects, not their retained size, for retention impact use the objectsAllocatedAt or heap.sizes builtins. Sampled data: allocation events may be sampled by the source recording mechanism, counts and bytes are estimates and small counts are unreliable.
Args: class or packageFilter (optional top-level parameters, restrict the analysis to one class or package), aggregation (optional, one of method, class, package, component, default method)
Rows: callTree[]: {method, bytes, count, percent, id, callers[] (omitted on leaf nodes, iterate as (.callers // [])[])} - pass ids to objectsAllocatedAt or allocatedClasses - in expand output, callers[] ends with a {capped, hiddenCallers} marker row when branches were pruned (below 1% of the expanded value or beyond the row cap) and moreAvailable replaces callers[] at the depth limit - with aggregation, rollup rows use the level as the key (class, package or component) instead of method
Example: .callTree | .[0:5] | map({method, bytes})
Requires: performance data: record cpu or probe subsystems, then check_status again
telemetry.list
Catalog of all recorded telemetries with per-line statistics: VM telemetries (heap, cpu, threads, classes, gc), memory pools, GC collectors, custom MBean/script telemetries and probe telemetries. A single call is enough to assess the recording, fetch series for a subset afterwards.
Rows: telemetries[]: {id, name, kind, unit, parent, sumsOfSubFeeds, startSeconds, endSeconds, lines[]: {name, points, stats{first, last, min, max, avg}}} - sumsOfSubFeeds: the sub-feeds (entries with this id as parent) add up to the lines of this telemetry with the same name, all times are seconds since recording start
Example: .telemetries[] | select(.kind == "vm") | {id, unit, lines: [.lines[].name]}
Requires: telemetry data: recorded by default in JProfiler sessions, not in plain heap dumps or HPROF files
telemetry.series
Time series of one telemetry, consolidated into equal-width buckets: v is the average per bucket, min and max are added when the bucket varies, so peaks survive the consolidation. Narrow the window and lower maxPoints when the result is too large.
Args: telemetry (required top-level parameter, an id from telemetry.list), line (optional, one line name from telemetry.list), from and to (optional, time window in seconds since recording start), maxPoints (optional integer, consolidated points per line, default 120, max 500)
Rows: lines[]: {name, stats, points[]: {t, v, min, max}} - t is seconds since recording start, one point per non-empty bucket
Example: .lines[] | select(.name == "used") | .points | sort_by(-(.max // .v)) | .[0:3]
Requires: telemetry data: recorded by default in JProfiler sessions, not in plain heap dumps or HPROF files
gc.collections
Individual garbage collections of the gc subsystem (the JFR-based GC probe): every GC with its cause, pause times, phases and heap/metaspace usage before and after, plus the GC configuration and flags of the JVM in the header. The entry point for GC pause and cause analysis: find pause outliers with sort_by(-.longestPauseMicros), explain them with cause and phases, and read the leak slope from heapUsedAfterBytes over time. The snapshotInfo.gcInfo block of check_status holds the aggregates. Rows have no back traces and gc has no performance.* or probe.* datasets - correlate causes like "G1 Humongous Allocation" with the allocating code via allocation.hotspots.
Rows: configuration: {category/attribute: value}, flags[]: {name, value, origin}, collections[]: {id, startSeconds, durationMicros, collector, cause, longestPauseMicros, sumOfPausesMicros, softRefs, weakRefs, finalRefs, phantomRefs, heapUsedBeforeBytes, heapUsedAfterBytes, heapCommittedBytes, metaspaceUsedBeforeBytes, metaspaceUsedAfterBytes, phases[]: {name, level, durationMicros}} - startSeconds is seconds since recording start and collections are sorted by it, absent fields are omitted (heap summaries and phases depend on the recorded JFR events, reference counts only appear when non-zero), at most 10000 collections are written, when collectionsTotal reports more the collections with the longest pauses are kept
Example: .collections | sort_by(-.longestPauseMicros) | .[0:5] | map({startSeconds, longestPauseMicros, cause})
Requires: GC probe data: recorded by default in sessions started through this server, in JProfiler UI sessions only while GC recording was active, present in most JFR recordings, not available in plain heap dumps
monitor.stats
Monitor and lock usage statistics aggregated over the recorded monitor events: block and wait counts and durations per monitor, thread or monitor class. The entry point for contention analysis: find the hot monitor or thread here, then drill down with monitor.history. Lock contention is invisible in CPU data.
Args: groupBy (optional, one of monitors, threads, classes, default monitors), from and to (optional, time window in seconds since recording start)
Rows: stats[]: {name, monitorId or threadId when grouped that way, blockCount, blockDurationMicros, waitCount, waitDurationMicros}, sorted by total lost time
Example: .stats | .[0:5] | map({name, blockDurationMicros})
Requires: monitor data: record monitors with attach or prepare_profiling ("recordingConfig": {"recordMonitors": true}), or load a snapshot that contains monitor recording
monitor.timeline
Monitor event density over time: one line per event type (blocked, waiting, parked) with event counts and total durations consolidated into equal-width buckets. Use it to find contention bursts, then zoom in with from/to on monitor.stats, monitor.history or monitor.graph.
Args: from and to (optional, time window in seconds since recording start), maxPoints (optional integer, consolidated points per line, default 120, max 500)
Rows: lines[]: {name, totalCount, totalDurationMicros, points[]: {t, count, micros}} - t is seconds since recording start, one point per non-empty bucket
Example: .lines[] | select(.name == "blocked") | .points | sort_by(-.micros) | .[0:3]
Requires: monitor data: record monitors with attach or prepare_profiling ("recordingConfig": {"recordMonitors": true}), or load a snapshot that contains monitor recording
monitor.history
Recorded monitor events as rows with stack traces, sorted by duration. The drill-down for monitor.stats: filter by monitorId or threadId from a stats row to see the individual locking situations and where they happen in the code. The header always reports totalCount and matchedCount and the duration distribution of the matching set, cutoffDurationMicros tells you the smallest shown duration when limit applies, so nothing is silently hidden.
Args: eventType (optional, one of blocked, waiting, parked), monitorId and threadId (optional, ids from monitor.stats rows), minDurationMicros (optional), from and to (optional, time window in seconds since recording start), limit (optional integer, default 100, max 1000, top events by duration)
Rows: events[]: {timeSeconds, durationMicros, type, monitorId, monitorClass, waitingThreadId, waitingThreadName, owningThreadId, owningThreadName, waitingStack[], owningStack[]}
Example: .events | .[0:3] | map({type, monitorClass, waitingThreadName, durationMicros})
Requires: monitor data: record monitors with attach or prepare_profiling ("recordingConfig": {"recordMonitors": true}), or load a snapshot that contains monitor recording
monitor.graph
Cumulated locking graph for a time window: thread and monitor nodes with waitsOn edges (count and total duration per thread/monitor/type) and ownedBy edges. lockOrderInversions reports cycles of up to 5 threads in this graph: threads that acquired the same monitors in opposite order, a structural deadlock risk even when no deadlock occurred. Observed deadlocks come from monitor.current, not from history data.
Args: monitorId and threadId (optional, ids from monitor.stats rows), from and to (optional, time window in seconds since recording start)
Rows: threads[]: {id, name}, monitors[]: {id, class}, edges[]: {waitingThread, monitor, type, count, totalDurationMicros} or {monitor, ownerThread, count}, lockOrderInversions[]: {path[], threads[], monitors[], variantCount} - cycles with the same thread set are grouped, path is the shortest variant, variantCount (absent when 1) the number of distinct cycles in the group
Example: .lockOrderInversions | map(.path)
Requires: monitor data: record monitors with attach or prepare_profiling ("recordingConfig": {"recordMonitors": true}), or load a snapshot that contains monitor recording
monitor.current
The latest monitor dump: threads blocked, waiting or parked right now, with stack traces, plus deadlocks detected as cycles in the current wait/own graph. For live sessions use attached_action with action monitorDump, this dataset serves dumps saved in snapshots.
Rows: events[] like monitor.history, deadlocks[]: {path[], threads[], monitors[], variantCount}
Example: .deadlocks | map(.path)
Requires: a monitor dump saved in a snapshot: take one with attached_action action monitorDump in a live session before stopping the recording, or load a snapshot that contains one
threads.dumps
Thread dumps saved in the snapshot, captured by threadDump trigger actions or attached_action: point-in-time states and stack traces of all threads, grouped like in the JProfiler thread dumps view. The entry point for stall and hang analysis: expand a dump and sort its groups by count to find where the thread population is parked, or compare two dumps to find threads stuck at the same stack trace. Thread dumps carry no lock ownership data, for deadlocks and lock analysis use monitor.current or attached_action with action monitorDump.
Rows: dumps[]: {expansionId, timeSeconds, label, type (platform|virtual), threadCount, groupCount, states{...}, skippedThreads} - timeSeconds is seconds since recording start. expand(expansionId) returns {dump, grouping, children[], nodesTruncated} with node kinds threadGroup/container/platformThreads ({kind, name, threadCount, children[]}), group ({kind, count, states, representative{name, threadId, state, stack[]}, names (further members, capped at 50), namesTruncated}) and thread ({kind, name, threadId, state, stack[], virtual when true}), the dump lists at most 1000 group and thread nodes with nodesTruncated counting the omitted ones, smallest groups and single threads are dropped first, stack[] lists the top 50 frames. states are lowercased ThreadStatusType values for platform dumps (runnable, blocked, waiting, net_io, native, dead) and Thread.State values for virtual dumps (runnable, blocked, waiting, timed_waiting, new, terminated). State is not part of the grouping key, the states objects count the group members. Find the biggest groups with [.. | objects | select(.kind == "group")] | sort_by(-.count)
Example: .dumps | map({expansionId, timeSeconds, label, type, threadCount})
Requires: thread dump data: capture thread dumps with a threadDump action in recordingConfig.triggers of attach or prepare_profiling, take one with attached_action action threadDump in a live session before stopping the recording, or load a snapshot that contains thread dumps
mbean.snapshots
MBean snapshots saved in the snapshot: JMX MBean attribute values captured with an mbeanSnapshot trigger action or attached_action. Without arguments returns the catalog of snapshots, with snapshot the MBean names of one snapshot, with snapshot and name the attribute values of one MBean.
Args: snapshot (optional integer, an index from the catalog), name (optional string, an MBean object name, requires snapshot)
Rows: catalog: snapshots[]: {index, label, timeSeconds, mbeanCount} - timeSeconds is seconds since recording start; with snapshot: domains[]: {name, mbeans[]}; with snapshot and name: attributes[]: {name, type, value}
Example: .snapshots | map({index, label, mbeanCount})
Requires: MBean snapshot data: take one with attached_action action mbeanSnapshot in a live session before stopping the recording, configure an mbeanSnapshot action in recordingConfig.triggers of attach or prepare_profiling, or load a snapshot that contains one
performance.outliers
Per-method invocation time statistics for finding outliers: methods whose slowest invocation deviates strongly from their average. The entry point for exceptional-invocation analysis: copy a method value into recordingConfig.advanced.exceptionalMethods and re-record to keep the slowest invocations as separately expandable nodes in performance.callTree. The times are measured in the thread state of the recordingConfig.advanced.exceptionalTimeType setting (all = wall clock by default), re-record with that setting to analyze a different thread state.
Args: minMaxMicros (optional integer, only methods whose slowest invocation took at least this many microseconds, default 10000), minCount (optional integer, only methods with at least this many invocations, default 10)
Rows: outliers[]: {method (spec format com.foo.Bar.method(long, java.lang.String)), count, totalMicros, avgMicros, maxMicros, outlierCoefficient}, sorted by outlierCoefficient descending - threadStatus names the thread state the times are measured in
Example: .outliers | .[0:5] | map({method, maxMicros, outlierCoefficient})
Requires: CPU data recorded with instrumentation: record with recordingConfig.advanced.methodCallRecordingType 'instrumentation', or load a snapshot recorded that way
probe.events
Individual recorded probe events of one probe subsystem: SQL executions, HTTP requests, file reads and similar. The filter arguments select globally over all recorded events before the maxEvents page is collected, the jq expression only sees the returned page, never the full event set. totalCount and matchedCount report the selection sizes, truncated marks a page cut by maxEvents. For per-statement aggregates over all events use performance.hotspots instead. Custom probes of the profiled application appear as custom:
Args: subsystem (required top-level parameter, a probe subsystem from availableSubsystems with recorded events, see the probeEvents section), sort (optional, duration (default, keeps the slowest events) or startTime (keeps the most recent events)), maxEvents (optional integer, default 1000, max 10000), from and to (optional, time window in seconds since recording start), minMicros and maxMicros (optional, duration range in microseconds), types (optional, comma-separated event type names or a JSON array of names, values from the type values of previous rows), text (optional, text filter on the description and all text payloads), matchMode (optional, one of contains, startsWith, endsWith, equals, wildcard, regex, default contains), ignoreCase (optional boolean, default false), threadId (optional integer, restrict to one thread id from threads.list), controlObjectId (optional integer, restrict to the events of one control object, a controlObjectId from probe.controlObjects or previous rows)
Rows: events[]: {startSeconds, durationMicros, type, description, threadId, thread, expansionId, probe-specific payload properties, secondaryEvents[]} - sorted by the sort argument, throughput added for file and socket probes, controlObjectId for probes with open/close events, expansionId only on events with a recorded back trace, expand it with the expand(expansionId) jq builtin
Example: .events | map({description, durationMicros})
Requires: recorded probe events: event recording is off by default - record with attach or prepare_profiling and recordingConfig.advanced.probeConfig, e.g. {"jdbc": {"events": true}}, or load a snapshot that contains recorded probe events
probe.eventHistogram
Duration or throughput distribution of the recorded events of one probe subsystem as an adaptive histogram over all matching events: percentile estimation, outlier judgment (is 300 ms anomalous here?), bimodality detection, and choosing a minMicros threshold for a follow-up probe.events query. The filter arguments of probe.events (from, to, minMicros, maxMicros, types, text, matchMode, ignoreCase, threadId) apply globally before aggregation.
Args: subsystem (required top-level parameter, a probe subsystem with recorded events), column (optional, duration (default), throughput for file/socket probes, or a numeric payload property name), maxBuckets (optional integer, default 100, max 1000), plus the probe.events filter arguments
Rows: {column, matchedCount, eventCount, missingCount, bucketSize, buckets[]: {from, count}} - from is the bucket start in the column unit (microseconds for duration), cumulative counts give percentile estimates
Example: .buckets | map({from, count})
Requires: recorded probe events: event recording is off by default - record with attach or prepare_profiling and recordingConfig.advanced.probeConfig, e.g. {"jdbc": {"events": true}}, or load a snapshot that contains recorded probe events
probe.eventTimeline
Event rate and duration of one probe subsystem over time, consolidated into equal-width buckets: localize incidents (when did slow SQL statements occur?), correlate with telemetry.series on the same time axis, then zoom in with from/to on probe.events. The filter arguments of probe.events (from, to, minMicros, maxMicros, types, text, matchMode, ignoreCase, threadId) apply globally before aggregation.
Args: subsystem (required top-level parameter, a probe subsystem with recorded events), maxPoints (optional integer, default 120, max 500), plus the probe.events filter arguments
Rows: points[]: {t, count, micros, maxMicros} - t is the bucket start in seconds since recording start, micros the summed duration of the bucket, one point per non-empty bucket; header reports totalCount and matchedCount
Example: .points | sort_by(-.micros) | .[0:5]
Requires: recorded probe events: event recording is off by default - record with attach or prepare_profiling and recordingConfig.advanced.probeConfig, e.g. {"jdbc": {"events": true}}, or load a snapshot that contains recorded probe events
probe.controlObjects
Open and closed control objects of one probe subsystem: JDBC connections, open files, sockets, processes. The leak analysis entry point: the objects still open, oldest first, are the leak candidates, expand the openExpansionId of a candidate for the stack trace of the open call (the leak site). With jdbc leak recording, state collectedWithoutClose also lists the connections that were garbage collected without close. Most probes have no control objects, the subsystems with recorded control objects are listed in the probeControlObjects section of check_status. For the individual operations on an object use probe.events with its controlObjectId argument.
Args: subsystem (required top-level parameter, a probe subsystem from the probeControlObjects section of check_status), state (optional, open (default), closed or all, collectedWithoutClose (jdbc connections garbage collected without close, from leak recording)), maxObjects (optional integer, default 200, max 2000, per state), text (optional, text filter on the name and text properties), matchMode (optional, one of contains, startsWith, endsWith, equals, wildcard, regex, default contains), ignoreCase (optional boolean, default false)
Rows: objects[]: {controlObjectId, name, state, openSeconds, ageSeconds, closeSeconds (closed only), type (custom open types only), eventCount, totalMicros, probe-specific properties, openExpansionId} - open objects first, oldest first, then closed objects, most recently closed first; ageSeconds is how long the object has been or was open; eventCount and totalMicros aggregate the events of the object; openExpansionId is present when event recording captured the open event, expand it with the expand(expansionId) jq builtin for the open stack trace; controlObjectId joins to the controlObjectId of probe.events rows and its controlObjectId argument; header reports openCount and closedCount over all objects and matchedCount for the selected state - with state collectedWithoutClose (jdbc leak recording, see the probeLeaks section of check_status) objects[] instead lists connections garbage collected without closing them, oldest first: {name, state, openSeconds, ageSeconds, className, openExpansionId} - no controlObjectId and no event aggregates exist for them, 'all' does not include them, ageSeconds is a lower bound because the collection time is not recorded, and the header reports collectedWithoutCloseCount whenever leak data is present
Example: .objects | map({name, ageSeconds, eventCount})
Requires: recorded probe control objects: only probes with open/close resources record them (jdbc connections, files, sockets, processes) - record such a probe with attach or prepare_profiling, or load a snapshot that contains control object data
javascript.origins
Origins of browser requests: the JavaScript call stacks and DOM events that triggered XHR or fetch requests to the profiled application, reported by the JProfiler browser extension. The splitId of a row joins to the splitId of javascript_split nodes in the performance datasets to attribute server-side time to frontend code.
Args: limit (optional integer, default 100, max 1000), scope (optional, recorded (default) or all: recorded lists only the origins whose requests reached the profiled application, all lists every origin the extension reported, with a recorded flag per row)
Rows: origins[]: {splitId, event (DOM event that triggered the request, absent without event tracking), stack[] (JavaScript frames with source locations, innermost first), recorded (scope all only)} - plus originsTotal when the list was capped
Example: .origins | map({splitId, event})
Requires: JavaScript origin data: a recording made while the JProfiler browser extension reported XHR and fetch call stacks from a browser driving the profiled application. Not produced by MCP recordings, load a snapshot recorded with the JProfiler UI and the browser extension
complexity.methods
Complexity analysis: how the invocation time of the configured methods scales with an input-size value computed per invocation by a script (for example a collection size). This is the second step after performance.hotspots has identified a suspicious method whose inputs vary in size: re-record with recordingConfig.advanced.complexityMethods pointing at that method, then read the points and curve fits here to answer 'is this method O(n^2) in the payload size'. bestFit names the curve type with the highest rSquared, the points allow verifying the fit yourself.
Rows: methods[]: {method (spec format com.foo.Bar.method(long, java.lang.String)), bucketSize, points[]: {input, totalMicros, count, avgMicros} (sorted by input, at most 1000 with pointsTruncated counting the rest), fits[]: {type, parameters, rSquared} (sorted by rSquared descending, type one of constant, linear, quadratic, cubic, exponential, logarithmic, n_log_n, the fitted y is the per-invocation average time, weighted by count, parameters are a and c of af(x)+c, exponential is exp(ax)+c, rSquared 1 is a perfect fit and <= 0 no better than constant), bestFit} - fits and bestFit require at least 3 points, and a fit type is dropped when the point count does not exceed its penalized parameter count, so with 3 points only perfect fits (rSquared 1) survive
Example: .methods | map({method, bestFit})
Requires: complexity data: record with recordingConfig.advanced.complexityMethods in attach or prepare_profiling (the second step after performance.hotspots has identified a suspicious method whose inputs vary in size), or load a snapshot recorded with complexity analysis
jq builtins
expand(expansionId)
Takes an expansionId or openExpansionId from performance.hotspots, performance.callTree, probe.events, probe.controlObjects or threads.dumps. Returns the back trace of a hotspot, probe event, control object open call or allocation node, the children of a call tree node, or the grouped thread tree of a thread dump.
Requires: performance data or thread dumps: record cpu or probe subsystems, or capture thread dumps with a threadDump trigger action or attached_action, then check_status again
threads(expansionId)
Takes an expansionId from a cpu performance.hotspots or cpu performance.callTree query. Returns the threads contributing to the hotspot or call tree node, with their share of its time.
Rows: threads[]: {threadId, name, group, micros (samples for JFR), percent} sorted by micros desc, capped at 50 with threadsTotal - pass a threadId as the thread parameter of the performance datasets to restrict them to that thread, threads.list has each thread's overall state breakdown - a node under a collapsed recursion cannot be attributed, use an ancestor node
Requires: cpu performance data and thread data in a single-snapshot session: record or load cpu data - heap dumps carry no thread attribution and snapshot comparisons cannot attribute threads
retained(id)
Takes the id of a biggest object from heap.biggestObjects. Returns the retained class histogram of that object.
Rows: retainedStats and classes[] rows like heap.classes: {name, shallowSize, count}; the set value exposes all objects retained by the biggest object for the set parameter of heap.instances, heap.sizes and heap.inspectionResult
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
sizes([ids])
Takes an array of up to 10000 object ids from heap.instances, heap.biggestObjects or a reference result. Returns the combined size analysis of the object set.
Rows: a single object: {count, shallowBytes, retainedBytes, deepBytes} - retainedBytes is the impact number, what would be freed if these objects became unreachable and less than the sum of the individual retained sizes when the objects overlap; deepBytes is the upper bound, including objects shared with the rest of the heap; for the complete set of one class or a value-filtered subset use the heap.sizes dataset instead of ids
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
incoming(id; optional filter)
Takes an object id from heap.instances, heap.biggestObjects or a reference result. Returns the referrers of the object.
Rows: referrers[]: {id, class, shallowSize, via, type} - via names the field, e.g. 'field referent of java.lang.ref.WeakReference'; moreAvailable: true when capped at 100. With a filter argument, all referrers of one group are returned: pass a class name from a referrersByClass row or a field descriptor from a referrersByField row, e.g. incoming(5; "java.lang.String") or incoming(5; "field next of com.x.Node")
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
outgoing(id; optional filter)
Takes an object id from heap.instances, heap.biggestObjects or a reference result. Returns the references of the object.
Rows: references[]: {id, class, shallowSize, via, type} rows like incoming(). With a filter argument, all references of one group are returned: pass a class name from a referencesByClass row or a field descriptor from a referencesByField row
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
pathToRoot(id)
Takes an object id from heap.instances, heap.biggestObjects or a reference result. Returns the paths from the object to its GC roots.
Rows: paths[]: {path[], length} - path[0] is the GC root (marked "root": true), the last element holds the queried object, via names the field; dominators[]: {class, shallowSize, retainedSize} - the unique dominator chain root-first, every link is necessary, removing any reference in it makes the object garbage collectable
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
preview(id)
Takes an object id from heap.instances, heap.biggestObjects or a reference result. Returns the string value or field contents of the object.
Rows: preview: the string value or comma-separated field contents of the object
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
referrersByClass(id or "class.name")
Takes an object id from heap.instances, heap.biggestObjects or a reference result, a set value from a previous heap result, or a fully qualified class name to aggregate over all its instances. Returns the referrers aggregated by class, complete even when incoming() is capped.
Rows: array rows: {class, referrers, instances} - instances counts the referrer objects of that class, referrers how many of the queried objects they reference; use when incoming() reports moreAvailable or the referrer classes matter more than single objects
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
referencesByClass(id or "class.name")
Takes an object id from heap.instances, heap.biggestObjects or a reference result, a set value from a previous heap result, or a fully qualified class name to aggregate over all its instances. Returns the referenced objects aggregated by class, complete even when outgoing() is capped.
Rows: array rows: {class, references, sources} - references counts the distinct referenced objects of that class, sources how many of the queried objects reference them
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
referrersByField(id or "class.name")
Takes an object id from heap.instances, heap.biggestObjects or a reference result, a set value from a previous heap result, or a fully qualified class name to aggregate over all its instances. Returns the referrers aggregated by the field they reference through.
Rows: array rows: {field, referrers, instances} - field names like 'field beanFactory of org.springframework...X'; instances counts the referrer objects sharing that field, revealing the retention mechanism
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
referencesByField(id or "class.name")
Takes a fully qualified class name to aggregate over all its instances, an object id, or a set value. Returns the referenced objects aggregated by the referencing field, the collective shape of a class's instances.
Rows: array rows: {field, references, sources} - for a container class this shows its structure, e.g. 'field key of ConcurrentHashMap$Node' with the counts of distinct keys
Requires: heap dump data: create one with create_heap_dump or load a snapshot that contains one
objectsAllocatedAt(id)
Takes an id from heap.allocationHotspots or heap.allocationCallTree rows. Returns the objects allocated at that call site, still live in the heap dump.
Rows: allocatedAt and instances[]: {class, name, shallowSize, retainedSize} rows like heap.instances, capped at 40
Requires: allocation data: record allocations with attach or prepare_profiling ("recordingConfig": {"recordAllocations": true}), or analyze a heap dump with allocation info
allocatedClasses(id)
Takes an id from allocation.hotspots, allocation.callTree, heap.allocationHotspots or heap.allocationCallTree rows. Returns the class histogram of the objects allocated at that call site.
Rows: allocatedAt, totalBytes and classes[]: {class, bytes, count, percent} sorted by bytes desc, capped at 40 with classesBelowCutoff; percent is the share of the call site; allocation.* covers all recorded objects including garbage collected ones (sampled estimates, can exceed the row bytes while the recording runs), heap.allocation* only objects still live at dump time
Requires: allocation data: record allocations with attach or prepare_profiling ("recordingConfig": {"recordAllocations": true}), or analyze a heap dump with allocation info