Guide
Profile with watch
Use a repeatable workload and captured telemetry to find where a program spends time, then measure the same workload after a change.
RepoQL’s watch tool stores application telemetry in queryable tables and samples process resource use. A useful profile starts by confirming what was captured. Timing numbers only describe the operations the application actually instrumented.
Choose a workload you can repeat
Write down the input, configuration, application version, and the behaviour you want to improve. Decide whether you are measuring startup, a cold cache, or steady-state work. Changing those conditions between runs can produce a convincing improvement that has little to do with the code change.
Ask your agent to launch the application with watch, passing its actual executable and argument array. Enable the application’s OpenTelemetry support if it is behind a setting. Keep the returned run identifier with your notes.
Check capture before interpreting the profile
Terminal
rql query "SELECT * FROM watch.summary()"
Confirm that the intended process ran and that the expected signals arrived. Payload counts show capture activity; decoded spans, logs, and metrics show what is available to query. If there are no spans, first check instrumentation and exporter configuration. Process resource metrics do not imply method-level tracing exists.
Find expensive operations and failures
Terminal
rql query "SELECT * FROM watch.span_stats()"
Terminal
rql query "SELECT * FROM watch.errors()"
Compare total time, frequency, and the slowest individual operations. A cheap operation called frequently can account for more work than a rare slow call. Nested and overlapping spans must not be added as though each contributes independent wall-clock time.
Follow a timing result into a trace to understand its context. Check failures and outliers as well as averages: an apparent speed-up can come from a path that stopped doing its work.
Connect the observation to the implementation
Use the span name and attributes to locate the instrumentation in source. A span name is chosen by the application; it need not be a method name. Read the instrumented operation and the work it encloses before attributing its duration to a particular function.
If memory is the issue, distinguish process resident memory from the managed heap. If latency is the issue, distinguish waiting from execution. The measurements available in the run determine which explanation you can support.
Compare a change under the same conditions
Run the same workload again and compare the relevant run identifiers. Check that each run completed the same amount of successful work. Repeat the comparison when cache state, machine load, or normal variation could explain the difference.
Save the queries, run identifiers, and evidence needed to reproduce the conclusion. Watch storage is temporary: completed and stale inactive runs become eligible for cleanup after six hours.
Query reference
The installed schema lists its own operations, examples, and return columns. Use those examples to drill into one run or trace; replace the supplied identifier with the one from your capture.
Terminal
rql query 'SELECT object, "what it answers", "example call", "returns"
FROM watch.surface ORDER BY object'
Terminal
rql query "SELECT * FROM watch.available_metrics()"
All runs use the watch schema. Summary and other run-aware functions accept a run identifier; do not combine unrelated runs when measuring one process.
Further reference
In the installed manual: help:///tools/watch/watch.md, help:///patterns/profiling.md.