Traces · timed spans
One row per operation. Every metric that matters.
Count, averages, the full percentile spread, total cost, how often it fires, and how fast — all sortable, all searchable. Operations fired suspiciously often get a HOT flag so redundant work stops hiding in the noise.
avg inter-call interval (intvl) + count is how duplicate work surfaces — a tight interval at a high count means the same op is firing back-to-back.
Drill into any key
Distribution, exemplars, and the span tree.
Where calls actually land — not just the average.
Real calls with timing + attributes.
Nested spans on a shared monotonic clock.
Beyond traces
Frames, rebuilds, and startup.
Frames & jank
14 jank · 4.2%Frame-time timeline with build/raster/total percentiles and the worst recent frames + their cause. Reset the counters to measure a specific interval.
Widget rebuilds
Per-label counts from instrumented subtrees. Excessive rebuilders flagged.
A single headline metric from init to first frame, broken down by phase — and an honest "not measured" state when it wasn't captured.
Real code
Trace a span. Count a rebuild.
// Wrap any operation — sync or async.
final messages = await Radar.trace(
'api.fetchMessages',
category: 'network',
() => api.fetchMessages(roomId),
);
// Nested spans share a monotonic clock —
// they roll up into a parent/child tree.
// Wrap a subtree to count its rebuilds.
RadarRebuildScope(
label: 'ChatBubble',
child: ChatBubble(message: m),
)
// Excessive rebuilders are flagged automatically
// in the Rebuilds view.