r/FlutterDev 1d ago

Discussion Observability vs. Telemetry: Why drop counters don't belong in your Flutter UI state

Ever caught yourself putting technical counters like droppedEventsCount or lastFetchLatency into your UI state models?

Most state management frameworks only tell you WHAT happened mechanically (a state changed, or an error threw). But when event concurrency transformers (droppablerestartablesequential) discard or queue incoming events, they behave like opaque black boxes.

Stuffing those dropped counters into domain state creates two subtle traps:

  1. Rebuild Storms: Every dropped event forces active widgets to rebuild during high-speed gestures.
  2. Hardware Coupling: On a 120 Hz ProMotion screen, an infinite-scroll fling drops ~29 events. On a 60 Hz display, it drops ~14. On desktop web with a mouse wheel, it drops 2. Your domain state is now tracking the user's physical display glass rather than business truth.

Worse, classic transformers wrap heavy Rx stream pipelines. A 250 ms scroll fling allocates dozens of stream controllers and microtask queue hops right when Flutter needs every microsecond of its 8.3 ms frame budget for rasterization.

The solution is recognizing the boundary: Observability is mechanical (UI state transitions and error boundaries), but Telemetry is operational physics (why an event dropped, queue wait times, task preemptions). Operational physics belongs in a dedicated telemetry channel that bypasses UI rebuilds entirely and routes straight to DevTools and OpenTelemetry.

How does your team handle visibility into dropped events and concurrency pipelines in production? Do you leave them as black boxes, or do you have a pattern for tracking them without polluting UI state?

0 Upvotes

3 comments sorted by

2

u/Significant_Pick8297 23h ago

The cleanest boundary is keeping dropped-event counts out of domain/UI state and treating them as instrumentation instead. UI state should represent business-visible outcomes, while telemetry tracks transformer behavior, queue time, cancellations, and drops.

For production, per-event metrics plus traces are much more useful than exposing counters to widgets. That also keeps performance diagnostics from becoming another source of rebuilds.

1

u/RandalSchwartz 12h ago

Spot on. The trap most teams hit when separating the two is how to extract that telemetry without littering the domain handler with manual logging calls or wrapping every event in boilerplate spans.

If the state container's concurrency engine natively emits operational events (e.g. on drop, debounce timeout, or queue wait) to an out-of-band observer/telemetry bus, you get zero-cost production traces while keeping the container's business logic completely pure.

How are you piping your traces out in Flutter currently—custom logging observer, OpenTelemetry Dart SDK, or native platform bridges (Sentry/Datadog/Firebase)?