digidem / digidem/comapeo-core-react-native

feat(ios): report app peak memory from MetricKit

Open
#254 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
1
Forks
0
Avg merge
8h 24m
Merged PRs (30d)
9

Description

On Android we now report the backend process's memory footprint as Sentry gauges (#249), including rss_peak_bytes — the peak the low-memory killer scores the process on. iOS deliberately emits only the JS-heap gauges: the process-level pair is gated off because Node runs inside the app process there, so any process number would describe the whole app, UI included.

But the whole-app number is still worth having on iOS — the OS kills the app on memory just as Android does — it just has to come from a different source, for two reasons:

  1. Node cannot see the right number on iOS. The iOS kill decision ("jetsam") is made on memory footprint — dirty memory plus compressed memory, the figure Xcode's memory gauge shows — not on resident set size. What Node's process.memoryUsage.rss() reports on iOS is resident size, which falls as the OS compresses pages while the footprint that determines the kill keeps counting them. Under memory pressure, exactly when the number matters, RSS is misleading. Node has no API for footprint.

  2. It must not share a metric name with the Android backend gauges. comapeo.backend.rss_bytes means "the backend process" on Android. An iOS value under the same name would mean "the whole app", and any cross-platform query would silently mix the two.

Proposal

MetricKit — the iOS framework we already consume for exit reasons in AppExitMetricsCollector — delivers MXMemoryMetric in the same daily payloads, with peakMemoryUsage measured by the OS as actual footprint (the jetsam-relevant quantity), plus averageSuspendedMemory (memory held while backgrounded, which speaks to background survival). No in-process sampling needed.

Wire these through the existing collector as app-level distributions, e.g.:

  • comapeo.app.peak_memory_bytes — from peakMemoryUsage
  • comapeo.app.suspended_memory_bytes — from averageSuspendedMemory

They pick up platform / device_class / os_major from the centralised injection added in #250, and pair naturally with the iOS exit reasons delivered in the same payloads — the way comapeo.backend.rss_peak_bytes pairs with comapeo.app.exit.rss_bytes on Android: one says what the app grew to, the other what it died holding.

Implementation notes:

  • The iOS bridge currently exposes only countMetric; a distributionMetric equivalent (same device-attribute injection and scrub) is needed. SentryMetricEmit.kt on Android is the shape to mirror.
  • MetricKit payloads are daily aggregates for the previous day, so these are slower-moving than the Android gauges — fine for fleet percentiles, not for boot-time analysis.
  • Caveat to document: the metric describes the whole app, so backend regressions show up diluted by UI memory; the JS-heap gauges remain the backend-specific signal on iOS.
  • Consent tier: propose diagnostic, matching the other memory gauges (daily aggregate, names nothing the user did) — needs the same second-opinion review the #249 tier decision got in docs/BENCHMARKING.md.

Depends on #250 (device-attribute injection in the native bridges).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with AppExitMetricsCollector and the iOS bridge's existing countMetric implementation; compare the requested distributionMetric shape with SentryMetricEmit.kt on Android. Review device-attribute injection from #250 and the consent discussion in docs/BENCHMARKING.md. Done means the two MetricKit memory distributions are emitted with the central attributes and the whole-app caveat is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, kotlin
Domain
documentation, mobile-dev, observability
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.