Skip to main content

Overview

Time-range filtering lets you isolate performance issues to specific moments in a profiling session. Use --from and --to flags to zoom into problem windows identified by timeline.
Time-range filtering is JFR-only. Pprof and collapsed text formats lack per-sample timestamps.

Basic Usage

Window Syntax

Specify durations relative to recording start using Go duration syntax:
# From 5 seconds to 10 seconds
ap-query hot profile.jfr --from 5s --to 10s

# First 30 seconds
ap-query hot profile.jfr --to 30s

# From 2 minutes onward
ap-query hot profile.jfr --from 2m

# Complex durations
ap-query tree profile.jfr --from 1m30s --to 2m15s -m HashMap.resize

Supported Formats

FormatExampleMeaning
Ns5s, 30sSeconds
Nms500ms, 1500msMilliseconds
Nm2m, 5mMinutes
NmNs1m30s, 2m45sCombined
Nh1h, 2h30mHours (rare)
Use timeline first to identify spike timestamps, then apply --from/--to to drill down.

Commands Supporting Time Ranges

All analysis commands accept --from and --to:
  • hot — Hot methods in window
  • tree — Call tree in window
  • trace — Hottest path in window
  • callers — Callers in window
  • lines — Line-level profile in window
  • threads — Thread distribution in window
  • filter — Filter stacks in window
  • collapse — Export window as collapsed text
  • timeline — Timeline of a sub-window

Workflow: Timeline-Driven Analysis

1

Identify spikes with timeline

ap-query timeline profile.jfr
Output:
Event: cpu

0.0s-2.5s       [████████░░░░░░░░░░░░] 1,234 samples  HashMap.resize
2.5s-5.0s       [██████████████████████] 2,891 samples  String.split
5.0s-7.5s       [█████░░░░░░░░░░░░░░░░] 876 samples    Thread.sleep
Spike at 2.5s-5.0s with 2,891 samples.
2

Zoom into spike window

ap-query hot profile.jfr --from 2.5s --to 5.0s --top 20
Shows hot methods only during the spike.
3

Drill into specific method

ap-query tree profile.jfr --from 2.5s --to 5.0s -m String.split --depth 8
Reveals call paths causing the spike.

Time Window Examples

Isolate Startup Phase

# First 10 seconds after start
ap-query hot profile.jfr --to 10s
Useful for:
  • Initialization hotspots
  • Class loading overhead
  • Connection pool warmup

Exclude Warmup

# Skip first 30 seconds
ap-query hot profile.jfr --from 30s
Useful for:
  • JIT-compiled steady state
  • Post-warmup performance
  • Ignoring startup noise

Capture Load Test Window

# 2 minutes into a 5-minute test
ap-query hot profile.jfr --from 2m --to 3m
Useful for:
  • Comparing low vs high load
  • Isolating concurrency issues
  • Steady-state analysis

Narrow Down to Specific Incident

# 500ms window around a latency spike
ap-query trace profile.jfr --from 4m30s --to 4m30.5s -m writeBytes
Useful for:
  • Pinpointing exact cause of outliers
  • Sub-second incident analysis

Combining with Other Filters

Time + Thread

ap-query hot profile.jfr --from 10s --to 20s -t "http-nio-8080"
Analyze specific thread group during a time window.

Time + Event Type

ap-query hot profile.jfr --from 1m --to 2m --event alloc
Focus on allocation hotspots during a window.

Time + Method Filter

ap-query filter profile.jfr --from 5s --to 15s -m HashMap | ap-query hot -
Filter stacks through a method, then re-analyze the filtered window.

Timeline with Time Ranges

Apply a window before generating timeline:
# Timeline of a 1-minute sub-window
ap-query timeline profile.jfr --from 2m --to 3m --resolution 5s
Output:
2m0s-2m5s       [██████████░░░░░░░░░░░░] 456 samples   Service.process
2m5s-2m10s      [████████████████░░░░░░░░] 789 samples   HashMap.resize
2m10s-2m15s     [██████████████████████░░] 1,234 samples String.concat
Time labels adjust to the window: 2m0s instead of 0.0s when --from 2m is used.

Window-Based Diff Analysis

Compare two time windows in a single JFR file:
ap-query diff profile.jfr \
  --from 55s --to 1m05s \
  --vs-from 2m45s --vs-to 3m10s
Output:
REGRESSION
  HashMap.resize      5.2% -> 18.7%  (+13.5%)
  String.split        2.1% ->  8.9%  (+6.8%)

IMPROVEMENT
  Thread.sleep       45.3% -> 12.1%  (-33.2%)
Useful for:
  • Before/after code change in one session
  • Comparing load levels
  • Detecting regressions during long runs
Use diff with time windows to avoid recording two separate profiles.

Automatic Window Clamping

If --from or --to exceed recording duration, ap-query clamps them:
ap-query hot 10s-recording.jfr --from 5s --to 20s
# Warning: --to 20s is beyond recording duration (10s); clamped to 10s
No error is raised — analysis continues with available data.

Duration Parsing Errors

Invalid Format

ap-query hot profile.jfr --from 5seconds
# error: invalid duration "5seconds": use Go syntax (5s, 1m30s, etc.)

Negative Durations

ap-query hot profile.jfr --from -5s
# error: --from must be non-negative

Window Inversion

No error, but empty result if --from > --to:
ap-query hot profile.jfr --from 10s --to 5s
# Warning: --from 10s > --to 5s; result will be empty

Performance Considerations

Large Time Windows

Filtering happens during parse — memory usage is proportional to filtered sample count, not total recording size.
# Efficient: parses only 10s window from 1-hour recording
ap-query hot 1h-profile.jfr --from 30m --to 30m10s

Multiple Windows

Re-parsing the file for each window:
# Three separate parses
ap-query hot profile.jfr --from 0s --to 10s
ap-query hot profile.jfr --from 10s --to 20s
ap-query hot profile.jfr --from 20s --to 30s
Consider using timeline + scripting for bulk window analysis (see Starlark Scripting).

Common Patterns

Exclude Warm-Up, Compare Steady State

ap-query diff profile.jfr \
  --from 30s --to 1m \
  --vs-from 4m --vs-to 4m30s

Analyze Per-Minute Buckets

for i in {0..4}; do
  start=$((i * 60))
  end=$(((i + 1) * 60))
  echo "=== Minute $i ==="
  ap-query hot profile.jfr --from ${start}s --to ${end}s --top 5
done

Find When a Method Became Hot

ap-query timeline profile.jfr -m HashMap.resize --pct --resolution 10s
Shows the method’s percentage in each 10-second bucket.

Limitations

Format Support

  • JFR: Full support
  • pprof: No timestamps → warning printed, flags ignored
  • Collapsed text: No timestamps → warning printed, flags ignored

Stdin

Time-range flags are ignored when reading from stdin:
ap-query hot - --from 5s --to 10s < profile.jfr
# Warning: --from/--to ignored for stdin (parse happens before filtering)
Use file path instead:
ap-query hot profile.jfr --from 5s --to 10s

Build docs developers (and LLMs) love