Instance Health, Footprint and Memory Leaks

A healthy endpoint can hide a growing heap, leaked subscriptions, too many processes or an oversized app. Reaktor needs both fleet health and evidence about each application instance. Every measurement names its runtime, release, activation, collector, unit, observation interval and scope.

Status: existing infrastructure collects JVM/host/container metrics; DevTools vitals and Crashlytics adapters supply selected client signals; the legacy debug Measure integration is pending removal. The catalog below defines the required operating coverage. It does not claim that every row is wired on every platform.

Footprint and instance catalog

FamilyRequired measurementsScope and interpretation
App/build sizeDownload/compressed bytes, installed/unpacked bytes, executable/code, native libraries, resources/assets, dependencies and symbols; build-over-build deltaSeparate APK/AAB, IPA, web chunks, JAR/distribution and container image. Record device/ABI, build mode, compression and whether symbols are shipped
Instance inventoryDesired/ready replicas, process count, start time, uptime, restarts, exit reason, image/artifact IDGroup by application/deployment and process role. Distinguish sidecars, helpers and app workers; reconcile observed count against topology
CPU and schedulingCPU time/utilization, capacity/limits, throttling, runnable threads, event-loop lagState normalization: one core, allocated cores or host total. Include contention and generator/profiler overhead
Threads/tasksOS thread count, Java platform/virtual-thread observations where supported, blocked/waiting/runnable states, executor queue, coroutines/actors and mailbox backlogProcesses, threads, coroutines and actors are different counts. A thread dump may omit logical coroutine ancestry
Managed memoryHeap used/committed/max, post-GC live set, allocation rate, object counts, retained bytes and GC pauses/cyclesUsed is not committed; committed is not resident; allocation volume is not retained volume
Native/process memoryRSS, PSS where supported, physical footprint, swap, mapped/shared/private pages, stacks, direct buffers, native/FFI allocations, metaspace and code cachePreserve platform metric semantics. Never add overlapping measures or compare Android PSS to iOS footprint as if identical
Container/host memoryWorking set, limit, pressure, OOM kills and host headroomContainer accounting includes more than the application heap; heap tuning must leave native/stack/runtime headroom
ResourcesOpen file descriptors/handles and limits, sockets, connection pools, disk/temp/cache bytes, I/O latency/throughputCheck idle return and disposal, not only peak values
User experienceCold/warm startup, frame deadline misses, stalls, crashes, ANRs, background/foreground behavior, network durations/errorsRecord display refresh interval, device tier, thermal/power state and session sampling
Graph lifecycleActive scopes/activations, pending work, retained subscriptions/interceptors, open capabilities, cancellation/drain/close outcomesAfter detach, resource counts should return to an explained steady-state baseline

App size is a build artifact measurement; memory is runtime footprint. Process count is an inventory measurement; coroutine count is a runtime model measurement. Do not collapse them into a single health score that conceals a missing collector.

Platform collection plan

RuntimeBaseline collectionDeeper investigation
JVM server/desktopExisting runtime/host metrics, management APIs, container limits and process inventoryJFR/JMC, thread dumps, heap retention analysis, NMT and native profiler
AndroidNative DevTools frame/memory/startup observations in debug builds; Crashlytics crashes/handled errors/supported ANRs; qualify Firebase Performance, release resource probes and app/process identityAndroid Studio/Perfetto/simpleperf, heap dump/LeakCanary, package/asset analysis
iOSDevTools observations in debug builds; Crashlytics crashes/handled errors; qualify Firebase Performance, startup/frame probes and physical-footprint measurementsInstruments allocations/leaks/time profiler; symbols and device crash diagnostics
BrowserNavigation/resource/error observations through Reaktor's own client evidence and versioned bundlesPerformance recording, allocation/heap snapshots, detached DOM and listener analysis
Worker / Durable ObjectProvider invocation CPU/duration/errors, limits and resource identifiersSupported local/deployed runtime captures; application state/resource-growth evidence. PID/heap fields may be unavailable
Native / FFIHost process and owned allocation/resource countersSupported native profiler, sanitizers and allocator evidence on qualified builds

Android distinguishes process memory measures and memory-pressure behavior in its memory guide. Collectors must retain which measure they actually report.

Crashlytics does not supply a resource timeline or prove a retained-object leak. Qualify existing Android memory and iOS physical-footprint probes by SDK, build and device; use the platform profilers for deeper attribution. Firebase Performance is a separate integration. Missing measurements remain visible in the required-probe manifest rather than becoming zero usage or a green result.

Proving a leak

  1. Pin artifact, device/runtime, flags, workload and initial state. Warm caches separately, then repeat a bounded lifecycle such as open/send/close, graph attach/detach or live update.
  2. Measure the idle baseline, peaks and return after quiescence. Account for cache policy, GC timing and retained pools. Increasing RSS alone is a suspicion, not a leak diagnosis.
  3. Compare equivalent post-GC live sets or retained ownership evidence. Use heap dominators/paths to roots for managed memory, native allocation evidence for native growth, and resource counts for non-memory leaks.
  4. Identify the retained owner: listener, scope, coroutine/job, timer, classloader, native handle, direct buffer or cache. Link it to a graph lifecycle when that attribution is supported.
  5. Reproduce the growth on baseline/candidate in isolated Shadow workspaces. Verify both bounded growth and disposal; retain dumps/profiles plus the assertion and capture interval.

Heap and memory artifacts may contain sensitive data and are expensive to collect. Record capture impact and access policy. Oracle's leak troubleshooting guide distinguishes Java-heap and native investigations; the profiling page turns this into a JVM workflow.

Budgets and workbench behavior

A required-measurement manifest names target/revision, metric, unit, collector and acceptance rule. Use absolute limits and baseline-relative deltas where appropriate; product/device owners choose limits from evidence. Outcomes are passed, exceeded, no collector and measurement failed. A skipped probe cannot produce green.

Show count and coverage: for example, ready replicas versus desired, observed processes versus expected, and sessions measured versus eligible. Join peaks and restarts to deploys and user journeys. Keep original artifacts reachable from findings and preserve identity and attribution limits.