Configuration

May 28, 2026 · View on GitHub

This guide covers all configuration options available in Project Argus.

Agent Configuration

The Argus agent is configured via Java system properties.

Available Properties

Core Settings

PropertyDefaultDescription
argus.server.enabledfalseEnable built-in dashboard server
argus.server.port9202WebSocket server port
argus.buffer.size65536Ring buffer size for event collection

GC & Memory Settings

PropertyDefaultDescription
argus.gc.enabledtrueEnable GC monitoring
argus.allocation.enabledfalseEnable allocation rate tracking (high overhead)
argus.allocation.threshold1048576Minimum allocation size to track (1MB)
argus.metaspace.enabledtrueEnable metaspace monitoring

CPU & Performance Settings

PropertyDefaultDescription
argus.cpu.enabledtrueEnable CPU monitoring
argus.cpu.interval1000CPU sampling interval (ms)
argus.profiling.enabledfalseEnable method profiling (high overhead)
argus.profiling.interval20Method profiling sampling interval (ms)
argus.contention.enabledfalseEnable lock contention tracking
argus.contention.threshold50Minimum contention duration to track (ms)

Analysis Settings

PropertyDefaultDescription
argus.correlation.enabledtrueEnable correlation analysis

Metrics Export Settings

PropertyDefaultDescription
argus.metrics.prometheus.enabledtrueEnable /prometheus endpoint
argus.otlp.enabledfalseEnable OTLP metrics push export
argus.otlp.endpointhttp://localhost:4318/v1/metricsOTLP collector endpoint
argus.otlp.interval15000OTLP push interval (ms)
argus.otlp.headers(empty)Auth headers (key=val,key=val)
argus.otlp.service.nameargusOTLP resource service name

Setting Properties

java -javaagent:argus-agent.jar \
     -Dargus.server.port=9090 \
     -Dargus.buffer.size=131072 \

     -jar your-application.jar

Buffer Size Tuning

The ring buffer size affects memory usage and event handling capacity.

Guidelines

Application TypeRecommended SizeMemory Usage
Development/Testing16384~1 MB
Standard Production65536 (default)~4 MB
High-throughput131072~8 MB
Extreme throughput262144~16 MB

Considerations

  • Buffer size must be a power of 2
  • Larger buffers reduce the chance of event loss under high load
  • Smaller buffers use less memory
# High-throughput configuration
java -javaagent:argus-agent.jar \
     -Dargus.buffer.size=262144 \

     -jar high-traffic-app.jar

GC Monitoring Configuration

GC monitoring captures garbage collection events and heap usage.

# Enable/disable GC monitoring
java -javaagent:argus-agent.jar \
     -Dargus.gc.enabled=true \

     -jar your-application.jar

GC Events Captured

EventDescription
jdk.GarbageCollectionGC pause duration, cause, collector name
jdk.GCHeapSummaryHeap used/committed before and after GC

GC Metrics Available

  • Total GC events count
  • Total/Average/Max pause time
  • GC cause distribution
  • Recent GC history (last 20 events)
  • Current heap usage

CPU Monitoring Configuration

CPU monitoring tracks JVM and system CPU utilization.

# Configure CPU monitoring
java -javaagent:argus-agent.jar \
     -Dargus.cpu.enabled=true \
     -Dargus.cpu.interval=1000 \

     -jar your-application.jar

CPU Metrics Available

  • JVM CPU (user + system)
  • System CPU
  • Historical data (60-second rolling window)
  • Peak CPU values

Adjusting CPU Sampling Interval

# Sample every 500ms for more granular data
-Dargus.cpu.interval=500

# Sample every 2 seconds for lower overhead
-Dargus.cpu.interval=2000

Allocation Tracking Configuration

Allocation tracking monitors object allocation rate and identifies top allocating classes.

# Configure allocation tracking
java -javaagent:argus-agent.jar \
     -Dargus.allocation.enabled=true \
     -Dargus.allocation.threshold=1024 \

     -jar your-application.jar

Allocation Metrics Available

  • Total allocation count
  • Total bytes allocated
  • Allocation rate (MB/sec)
  • Peak allocation rate
  • Top 10 allocating classes

Tuning Allocation Threshold

# Track all allocations >= 512 bytes
-Dargus.allocation.threshold=512

# Track only large allocations >= 8KB
-Dargus.allocation.threshold=8192

Metaspace Monitoring Configuration

Metaspace monitoring tracks class metadata memory usage.

# Enable/disable metaspace monitoring
java -javaagent:argus-agent.jar \
     -Dargus.metaspace.enabled=true \

     -jar your-application.jar

Metaspace Metrics Available

  • Current used/committed memory
  • Peak usage
  • Growth rate (MB/min)
  • Class count

Method Profiling Configuration

Method profiling identifies CPU-intensive methods using execution sampling.

Warning: Method profiling has higher overhead. Use with caution in production.

# Enable method profiling
java -javaagent:argus-agent.jar \
     -Dargus.profiling.enabled=true \
     -Dargus.profiling.interval=20 \

     -jar your-application.jar

Method Profiling Metrics Available

  • Total sample count
  • Top 20 hot methods
  • Method sample percentage

Adjusting Profiling Interval

# More frequent sampling (higher accuracy, higher overhead)
-Dargus.profiling.interval=10

# Less frequent sampling (lower accuracy, lower overhead)
-Dargus.profiling.interval=50

Lock Contention Configuration

Lock contention tracking monitors thread synchronization bottlenecks.

# Configure contention tracking
java -javaagent:argus-agent.jar \
     -Dargus.contention.enabled=true \
     -Dargus.contention.threshold=10 \

     -jar your-application.jar

Contention Metrics Available

  • Total contention events
  • Total contention time
  • Top 10 contention hotspots
  • Per-thread contention time

Tuning Contention Threshold

# Track contention >= 5ms
-Dargus.contention.threshold=5

# Track only severe contention >= 50ms
-Dargus.contention.threshold=50

Correlation Analysis Configuration

Correlation analysis detects relationships between different metrics.

# Enable/disable correlation analysis
java -javaagent:argus-agent.jar \
     -Dargus.correlation.enabled=true \

     -jar your-application.jar

Correlation Features

  • GC ↔ CPU Correlation: Detects CPU spikes within 1 second of GC events
  • GC ↔ Pinning Correlation: Identifies pinning increases during GC
  • Automatic Recommendations: Provides actionable insights:
    • GC overhead warnings (> 10%)
    • Memory leak detection (sustained heap growth)
    • Lock contention hotspot alerts
    • High allocation rate warnings
    • Metaspace growth warnings

JFR Event Configuration

Argus captures the following JFR events by default:

Virtual Thread Events

EventDescriptionOverhead
jdk.VirtualThreadStartThread creationLow
jdk.VirtualThreadEndThread terminationLow
jdk.VirtualThreadPinnedThread pinning (with stack trace)Medium
jdk.VirtualThreadSubmitFailedSubmit failuresLow

GC & Memory Events

EventDescriptionOverhead
jdk.GarbageCollectionGC pause eventsLow
jdk.GCHeapSummaryHeap usage snapshotsLow
jdk.ObjectAllocationInNewTLABObject allocation in TLABMedium
jdk.MetaspaceSummaryMetaspace usageLow

CPU & Performance Events

EventDescriptionOverhead
jdk.CPULoadCPU utilization (periodic)Low
jdk.ExecutionSampleMethod execution samplingMedium-High
jdk.JavaMonitorEnterLock acquisition contentionLow
jdk.JavaMonitorWaitLock wait contentionLow

JFR Settings

The agent configures JFR with:

  • Max Age: 10 seconds (sliding window)
  • Max Size: 10 MB

Server Configuration

Port Configuration

# Start server on custom port
java -Dargus.server.port=9090 -jar argus-server.jar

Production Deployment

For production environments, consider:

  1. Bind to localhost only (for security):

    # Use a reverse proxy (nginx, etc.) for external access
    
  2. Enable TLS via reverse proxy:

    # nginx configuration example
    server {
        listen 443 ssl;
        server_name argus.example.com;
    
        ssl_certificate /path/to/cert.pem;
        ssl_certificate_key /path/to/key.pem;
    
        location /events {
            proxy_pass http://localhost:9202;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    
        location /health {
            proxy_pass http://localhost:9202;
        }
    }
    

Environment Variables

You can also use environment variables (converted to system properties):

export ARGUS_SERVER_PORT=9090
export ARGUS_BUFFER_SIZE=131072

java -javaagent:argus-agent.jar \
     -Dargus.server.port=${ARGUS_SERVER_PORT} \
     -Dargus.buffer.size=${ARGUS_BUFFER_SIZE} \

     -jar your-application.jar

Docker Configuration

Dockerfile Example

FROM eclipse-temurin:21-jre

COPY argus-agent.jar /opt/argus/
COPY your-application.jar /app/

ENV ARGUS_PORT=9202
ENV ARGUS_BUFFER_SIZE=65536

EXPOSE ${ARGUS_PORT}

ENTRYPOINT ["java", \
    "-javaagent:/opt/argus/argus-agent.jar", \
    "-Dargus.server.port=${ARGUS_PORT}", \
    "-Dargus.buffer.size=${ARGUS_BUFFER_SIZE}", \
    "-jar", "/app/your-application.jar"]

Docker Compose Example

version: '3.8'

services:
  app:
    build: .
    ports:
      - "9202:9202"
    environment:
      - ARGUS_PORT=9202
      - ARGUS_BUFFER_SIZE=131072

Kubernetes Configuration

Deployment Example

apiVersion: apps/v1
kind: Deployment
metadata:
  name: your-app
spec:
  template:
    spec:
      containers:
        - name: app
          image: your-app:latest
          env:
            - name: JAVA_TOOL_OPTIONS
              value: "-javaagent:/opt/argus/argus-agent.jar"
            - name: ARGUS_SERVER_PORT
              value: "9202"
            - name: ARGUS_BUFFER_SIZE
              value: "65536"
          ports:
            - containerPort: 9202
              name: argus
          livenessProbe:
            httpGet:
              path: /health
              port: argus
            initialDelaySeconds: 10
            periodSeconds: 5

Performance Tuning

Low Latency Configuration

java -javaagent:argus-agent.jar \
     -Dargus.buffer.size=32768 \
     -XX:+UseZGC \
     -XX:+ZGenerational \

     -jar latency-sensitive-app.jar

High Throughput Configuration

java -javaagent:argus-agent.jar \
     -Dargus.buffer.size=262144 \
     -XX:+UseParallelGC \

     -jar high-throughput-app.jar

Prometheus Endpoint

Prometheus metrics are exposed at /prometheus by default.

# Scrape metrics
curl http://localhost:9202/prometheus

Prometheus scrape config

scrape_configs:
  - job_name: 'argus'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:9202']
    metrics_path: '/prometheus'

OTLP Export Configuration

OTLP export pushes metrics to an OpenTelemetry collector in OTLP JSON format. No OpenTelemetry SDK is required — Argus hand-codes the OTLP protocol.

java -javaagent:argus-agent.jar \
     -Dargus.otlp.enabled=true \
     -Dargus.otlp.endpoint=http://localhost:4318/v1/metrics \
     -Dargus.otlp.interval=15000 \
     -jar your-application.jar

With Authentication

java -javaagent:argus-agent.jar \
     -Dargus.otlp.enabled=true \
     -Dargus.otlp.endpoint=https://otel.example.com/v1/metrics \
     -Dargus.otlp.headers=Authorization=Bearer\ mytoken \
     -Dargus.otlp.service.name=my-service \
     -jar your-application.jar

Metrics Exported

All 30+ metrics available via Prometheus are also exported via OTLP:

TypeExamples
Gaugeargus_virtual_threads_active, argus_cpu_jvm_percent, argus_heap_used_bytes
Sum (monotonic)argus_virtual_threads_started_total, argus_gc_pause_time_seconds_total
Histogramargus_gc_pause_seconds (_bucket/_sum/_count) — GC pause-time distribution
Per-collector counterargus_gc_pause_breakdown_seconds_total{gc_name,gc_cause}, argus_gc_events_breakdown_total{gc_name,gc_cause}

OpenMetrics exposition

The /prometheus endpoint negotiates format by Accept header:

  • Default (Accept: text/plain or absent) → Prometheus 0.0.4 text exposition.
  • Accept: application/openmetrics-text → OpenMetrics 1.0.0 (terminated with # EOF), with trace-id exemplars on the GC pause histogram when a trace context is active (exemplars are populated once tracing correlation is wired; the plumbing ships now and is a no-op until then).

The OpenMetrics output passes promtool check metrics.

CLI Configuration

The Argus CLI provides unified JVM diagnostics with auto source detection.

First-time Setup

argus init

This creates ~/.argus/config.properties with your preferred language and defaults.

Recent additions (v1.1.0+)

These flags were added in the current development cycle. Each appears in the relevant per-command section below as well.

CommandFlagDescription
argus profile--capabilitiesLists supported profiling events for the host platform
argus profile--event=<name>Selects the profiling event (cpu, alloc, lock, wall, etc.)
argus profile--duration=NsSets the profiling window in seconds
argus profile--save=<path>Saves a profile snapshot to a JSON file for later diffing
argus profile--diff=<path>Diffs the current run against a saved snapshot
argus profile-gate--threshold=XFails if any method's CPU share grows by more than X percentage points
argus profile-gate--threshold-samples=NIgnores changes with fewer than N sample delta
argus profile-gate--max-regressions=KFails if more than K methods regress (any amount)
argus profile-gate--format=jsonEmits machine-readable JSON
argus profile-gate--annotate=githubEmits ::error:: / ::warning:: GitHub Actions annotations
argus flame--duration=NsSets the one-shot flame graph capture window
argus flame--output=<path>Saves the flame graph HTML to the given path instead of a temp file
argus nmt--save <path>Saves an NMT baseline snapshot to a file
argus nmt--diff <path>Compares current NMT state against a saved baseline
argus gclog--top=NShows the top N causes in the aggregated pause-summary table (default: 8)
argus gclog--allShows all causes in the pause-summary table without truncation
argus gcwhy--duration=NsSets the live JFR capture window when a PID is given
argus gcscore(PID form)argus gcscore <PID> now accepts a live PID in addition to a log file
argus gcscore--duration=NsLive JFR capture window (PID form only)
argus doctor--profileAdds a live profile capture to the health report
argus doctor--profile=<file>Adds profile findings from a saved snapshot file
argus doctor--profile-duration=NSets the live capture duration for --profile (seconds)
argus suggest--profileAdds profile-driven flag recommendations to the output
argus suggest--profile=<file>Uses a saved snapshot instead of a live capture
argus suggest--advancedIncludes advanced ZGC flags (e.g. ZAllocationSpikeTolerance)
argus zgc<PID>One-shot ZGC health verdict via 30s live JFR capture
argus zgc--duration=NOverride the JFR capture window (5–120 seconds)
argus zgc--save=PATHCapture once and persist a baseline snapshot to PATH
argus zgc--diff=PATHCapture once and compare against baseline at PATH; renders diff table instead of normal verdict
argus zgc--watch[=N]Loop: unlimited (--watch) or N iterations (--watch=N); 1-line summary per iteration, full table every 5th
argus zgc--interval=NJFR capture duration and watch loop period in seconds (default: 30, range: 10–300)

ZGC logging setup

To enable argus gclog allocation stall detection and ZGC cycle visibility, start the target JVM with the canonical unified GC log configuration:

java -XX:+UseZGC \
     -Xlog:gc*:file=gc.log:time,uptime,level,tags \
     -jar your-app.jar

This produces Allocation Stall (thread) Xms lines that argus gclog parses into the Allocation Stalls (ZGC) section. Without gc* (i.e. with just gc), stall lines are not emitted.

For Generational ZGC on JDK 21–23:

java -XX:+UseZGC -XX:+ZGenerational \
     -Xlog:gc*:file=gc.log:time,uptime,level,tags \
     -jar your-app.jar

ZGC tuning flags

FlagPurpose
-XX:SoftMaxHeapSize=<N>gSoft heap ceiling; ZGC keeps committed heap below this under normal load
-XX:ZAllocationSpikeTolerance=5.0Tolerance for short-lived allocation spikes before proactive GC (default: 2.0)
-XX:+ZUncommitReturn idle heap pages to the OS
-XX:ZUncommitDelay=300Wait N seconds before uncommitting idle memory (default: 300)
-XX:ConcGCThreads=NNumber of concurrent GC threads; raise when cycles overlap or stalls occur
-XX:+ZGenerationalEnable Generational ZGC (JDK 21–23; default in JDK 24+)

Examples:

# List supported profiling events on this machine
argus profile --capabilities

# Profile for 30 s, save snapshot, then gate against it in CI
argus profile 12345 --duration=30 --save=before.json
argus profile 12345 --duration=30 --save=after.json
argus profile-gate before.json after.json --threshold=5 --annotate=github

# One-shot flame graph saved to a specific file
argus flame 12345 --duration=20 --output=./flame.html

# Capture NMT baseline, then diff after a load test
argus nmt 12345 --save baseline.json
argus nmt 12345 --diff baseline.json

# Show all GC causes instead of the default top 8
argus gclog /var/log/gc.log --all

# Diagnose a live JVM and include a CPU profile in the report
argus doctor 12345 --profile --profile-duration=10

# GC score from a live JVM (30 s JFR window)
argus gcscore 12345 --duration=30

CLI Commands

argus ps                       # List running JVM processes
argus histo <pid>              # Heap object histogram
argus histo <pid> --top 50     # Top 50 entries
argus threads <pid>            # Thread dump summary
argus gc <pid>                 # GC statistics
argus gcutil <pid>             # GC generation utilization (jstat-style)
argus heap <pid>               # Heap memory usage
argus sysprops <pid>           # System properties (--filter supported)
argus vmflag <pid>             # VM flags (--filter, --set supported)
argus nmt <pid>                # Native memory tracking
argus classloader <pid>        # Class loader hierarchy
argus jfr <pid> start          # Start Flight Recorder
argus jfr <pid> check          # Check recording status
argus info <pid>               # JVM information
argus top                      # Real-time monitoring (requires agent)

Global Options

OptionDefaultDescription
--source=auto|agent|jdkautoData source selection
--no-color(off)Disable ANSI colors
--lang=en|ko|ja|zhenOutput language
--format=table|jsontableOutput format
--host HOSTlocalhostAgent host (for top and agent source)
--port PORT9202Agent port
--help, -hPrint usage and exit
--version, -vPrint version and exit

Source Auto-detection

When --source=auto (default), the CLI:

  1. Tries connecting to the Argus agent via HTTP
  2. Falls back to JDK tools (jcmd) if agent is unavailable

Use --source=agent or --source=jdk to force a specific source.

JSON Output

All commands support --format=json for pipeline integration:

argus gc 12345 --format=json | jq '.heapUsed'
argus histo 12345 --format=json --top 10 > heap-snapshot.json

Per-command flag reference

argus profile

FlagDefaultDescription
--capabilitiesPrint supported events for the host and exit
--event=<name>cpuProfiling event (cpu, alloc, lock, wall, or a JFR event name)
--duration=N10Capture duration in seconds
--save=<path>Persist snapshot as JSON for diffing
--diff=<path>Compare this run against a saved snapshot
--diff=BEFORE:AFTEROffline diff of two snapshot files (no PID required)
--top=N20Number of methods to display
--format=jsonMachine-readable output

argus profile-gate

Compares two profile snapshots and exits non-zero on regression. Designed for CI pipelines.

FlagDefaultDescription
--threshold=PCT10Fail if any method's share grows by ≥ PCT percentage points
--threshold-samples=N0Ignore changes with sample delta < N
--top=N20Show top N regressions in the report
--format=jsonMachine-readable JSON output
--annotate=githubEmit ::error:: / ::warning:: GitHub Actions annotations
--max-regressions=K(unlimited)Fail if more than K methods regress (any amount)
--baseline-onlyPrint report but always exit 0

Exit codes: 0 = pass, 1 = regression detected, 2 = usage / IO error.

argus profile-gate before.json after.json --threshold=5 --format=json

argus flame

One-shot flame graph. Profiles a JVM and opens the result in the browser.

FlagDefaultDescription
--duration=N10Capture duration in seconds
--type=EVENTcpuProfiling event (aliases --event)
--output=PATH(temp file)Output file path
--output-format=FMTflamegraphOutput format: flamegraph, tree, jfr, collapsed, text
--no-openDo not open browser after profiling

argus nmt

FlagDefaultDescription
--save <path>Save current NMT state as a baseline JSON file
--diff <path>Compare current state against a baseline file
--watch[=N]2Live delta view, refreshing every N seconds
--format=jsonMachine-readable output

Requires the target JVM to start with -XX:NativeMemoryTracking=summary.

argus gclog

FlagDefaultDescription
--top=N8Show top N causes in the pause-summary table
--allShow all causes without truncation
--phasesInclude GC sub-phase breakdown
--tenuringTenuring age-table analysis (requires -Xlog:gc+age=debug)
--follow, -fTail the log file and refresh every 2 s
--suggest-flagsPrint only the recommended JVM flags
--export=PATHExport analysis as a self-contained HTML file
--format=jsonMachine-readable output

argus gcwhy

FlagDefaultDescription
--duration=N30Live JFR capture window in seconds (PID form only)
--last=WINDOW5mAnalyse only pauses in the last window (e.g. 30s, 5m, 2h)
--format=jsonMachine-readable output

Accepts either a GC log file path or a live PID as its first argument.

argus gcscore

FlagDefaultDescription
--duration=N30Live JFR capture window in seconds (PID form only)
--format=jsonMachine-readable output

Accepts either a GC log file path or a live PID as its first argument.

argus doctor

FlagDefaultDescription
--profileCapture a live CPU profile and include findings in the report
--profile=<file>Load a saved snapshot and include profile findings
--profile-duration=N5Live capture duration for --profile (seconds)
--pause-threshold-ms=N200Flag STW pauses exceeding this value as a finding
--format=jsonMachine-readable output
--export=PATHExport report as a self-contained HTML file

Exit codes: 0 = healthy, 1 = warnings, 2 = critical issues.

argus suggest

FlagDefaultDescription
--profileRun a live CPU profile and add profile-driven recommendations
--profile=<file>Load a saved snapshot for profile-driven recommendations
--profile=<workload>Optimise for a named workload: web, batch, microservice, streaming
--profile-duration=N5Live capture duration when --profile is used without a file
--format=jsonMachine-readable output

argus zgc

FlagDefaultDescription
--duration=N30JFR capture window in seconds (clamped to 5–120)
--save=PATHCapture once, render normally, and persist baseline to PATH
--diff=PATHCapture once, compare against baseline at PATH, render diff table (suppresses normal verdict)
--watch[=N]Loop indefinitely (--watch) or for N iterations (--watch=N); 1-line summary per iteration, full table every 5th
--interval=N30JFR capture duration and watch loop period in seconds (clamped to 10–300)

Config File

Stored at ~/.argus/config.properties:

lang=en
default.source=auto
color=true
format=table
default.port=9202

Environment Variables

VariableDescription
ARGUS_DEBUGSet to any non-empty value to print full stack traces on error (equivalent to -Dargus.debug=true)
LC_ALLAuto-detected for output language. Overrides LANG when both are set. Example: LC_ALL=ko_KR.UTF-8 selects Korean output
LANGFallback locale for output language when LC_ALL is unset. The CLI extracts the two-letter ISO 639-1 code (e.g. ko from ko_KR.UTF-8)

ARGUS_DEBUG is checked in ArgusCli and in commands that perform live JFR captures (e.g. gcwhy, gcscore) to decide whether to print stack traces.

Next Steps