---
title: "6 things mobile engineering teams wish they knew earlier"
metaTitle: "6 things mobile engineering teams wish they knew earlier"
slug: "6-mobile-engineering-lessons"
metaDescription: "Learn what makes mobile observability uniquely hard, reported by engineers who’ve lived through it at places like Favor Delivery, Hatch, and Zuper."
cover:
  url: "/assets/posts/no-one-talks-about-mobile-observability/feature-talk_about_mobile_observability_blog_image-desktop@2x.webp"
  alt: "6 things mobile engineering teams wish they knew earlier"
socialThumbnail:
  url: "/assets/posts/no-one-talks-about-mobile-observability/feature-talk_about_mobile_observability_blog_image-desktop@1x.webp"
  alt: "6 things mobile engineering teams wish they knew earlier"
author:
  - "collin"
tags:
  - "mobile observability"
publishedDate: "2026-08-25T12:00:00.000Z"
modifiedDate: "2026-08-25T12:00:00.000Z"

---

We spend a lot of time talking with teams that are building out a dedicated mobile engineering function for the first time. In those conversations, it’s become clear how nascent mobile observability is for many organizations. Until you’re in the trenches of trying to deeply understand the way users experience your app on mobile, you just don’t get how different it is from traditional, backend observability.

I’ve witnessed many “a ha” moments surface in those conversations, where mobile engineers flag things they wished they’d known sooner. Here’s a common story:

_“A one star review says checkout is broken, yet the crash reporter says everything is fine. Backend dashboards say the API is healthy. Somewhere between those three is the truth, yet none of our tools can show it.”_

That gap is actually the predictable result of how mobile observability tooling has evolved: built for servers first, adapted for mobile later. The problems show up everywhere once you know to look for them.

So here’s my attempt at packaging all of those hard-earned lessons into a post that might benefit others who are starting out on the mobile observability journey.

First, let’s talk about the dark side of sampling.

## Lesson #1: Sampling means the data you need usually doesn't exist

Traditional observability relies on sampling. You capture 1% or 10% of events, aggregate them server-side, and then surface summaries in a dashboard. That works fine-ish for spotting broad trends. Most teams don't even see the flaws with this approach until the day they need one specific session and it isn't there.

When a specific user reports a specific failure, you need that user's session, not a statistical picture of what might have happened across a subset of users. With sampled telemetry, the odds that the session you need was actually captured match your sample rate. Roll the dice enough times and you learn the house rule of mobile debugging:

_You never get lucky when you actually need it._

“In many cases the information was like getting a couple of grains of sand to explain the whole sea,” [explained Favor Delivery’s Senior Staff Software Engineer Igor Korobka](https://bitdrift.io/case-study/favor).

Sampled data produces sampled answers. For monitoring, that's a trade off. For debugging, it's a dead end.

## Lesson #2: The de facto observability cost model forces you to choose blindness upfront

If sampling doesn’t work great, then why is everyone doing it? The short answer: because the dominant pricing model charges for ingest.

Every log shipped off the device costs money, so teams are pushed into an impossible trade off. You have to decide today which telemetry you'll need tomorrow, for a bug that hasn't happened yet. On top of that, if you collect everything, your bill is outrageous, plus you're burning your users' data plans. (We’ve heard many, many complaints about this, and our founders lived it firsthand at Lyft.)

Collect conservatively and you trade money for blindspots. Most teams land somewhere in the middle, which means every incident starts with the same discovery: _the one field that would explain everything is the one nobody thought to send._

The sampling model demands too much guessing upfront.

## Lesson #3: Crashes are the tip of the iceberg

Most mobile observability stacks are built around crash reporting, and crash reporting answers exactly one question: did the app crash?

Most bad user experiences never trip it, which is another eye-opening realization for many teams. Here are some common anecdotes:

- The OS kills your app for memory pressure, and it doesn't look like a crash in your logs. In fact, it looks like nothing.
- The device runs hot and throttles the CPU, so your “optimized” code runs slow.
- A request completes just as the app is backgrounded and triggers a race condition that only exists in real world usage.
- A checkout flow silently stalls on a congested cellular network that behaves nothing like the office Wi-Fi.

None of these show up as a clean stack trace. All of them show up in your reviews, and worse, your revenue.

If your observability starts and ends with crashes, you're monitoring the smallest category of failure your users experience.

## Lesson #4: In mobile, everything you want to know waits on an app release

On the backend, if you need a new log line, you add it and deploy. Minutes later, you have data.

On mobile, that same change enters the release pipeline:

1. code review
2. release train
3. app store review
4. then the slow crawl of user adoption

Realistically you're looking at days to weeks before the instrumentation is even present on enough devices to matter, and that assumes users update at all.

This catches new mobile teams off guard fast, and destroys the iteration loop that makes debugging work everywhere else. Investigation is a cycle of asking a question, getting an answer, and asking a better question. When each new question costs a release cycle, engineers stop asking. They guess, they close the ticket as “cannot reproduce,” and the bug ships again.

## Lesson #5: Logs tell you what failed, never what state the app was in

Mobile apps exist in a world of lifecycle transitions, feature flag states, varying screen sizes, and background suspensions. Two users on the exact same app version can have completely different experiences, and your logs won't tell you why.

* Was the app mid-transition to the background?
* Which feature flag variants was the user exposed to?
* Was the exposure even logged?
* What did they actually see on screen in the thirty seconds before the failure?

For the Hatch Sleep app, issues show up as a routine that doesn’t start, audio that cuts out, a device that doesn't respond as expected, or a delay that breaks the flow of a bedtime ritual.

Without lifecycle events, flag exposure, and session replay captured alongside your telemetry, “can’t reproduce” is the honest truth. The logs show that something failed, but they rarely explain the state the app was in when it happened.

“If we couldn't reproduce it, we didn't really have anything to go off of,” [said Lotus Quach](https://bitdrift.io/case-study/hatch), Hatch’s Staff QA Analyst.

## Lesson #6: Investigations are scattered across 5 tools

Even when the data exists, answering one question means opening several tools:

* the analytics dashboard for the funnel
* the crash reporter for stability
* the logging tool for events
* the tracing tool for the backend
* and a spreadsheet to reconcile the four different stories they tell

Session IDs don't match across tools, and time windows don't line up. Two hours later you have 17 tabs and a theory.

Zuper Engineering Manager Ranjith Kumar [described their workflow](https://bitdrift.io/case-study/zuper): “The first signal that something went wrong was usually a Slack error notification. From there, we'd have to jump between Sentry and Mixpanel to reconstruct the story. But we never had the full picture of what the user was doing, whether the device was under memory pressure, or what the OS constraints were.”

That lack of context meant Zuper's engineers often spent hours tracing the root cause of production issues, or worse, reacting only after customers experienced them.

The newest version of this problem, and the one we’re hearing about a lot from teams building with agents, is that fragmentation locks out AI agents. Agents are ready to run investigation loops on your behalf by authenticating, pulling the funnel, comparing time windows, and correlating errors. But they can't reason across five disconnected tools with sampled data any better than you can. An agent querying approximations produces approximate answers, just faster. If observability is going to be agentic, the data layer underneath has to be complete and programmable first.

## Applying those lessons to figure out what good looks like

None of these lessons are the result of physics laws. They're consequences of one architectural decision: collect a little data all the time, and decide what to keep before you know what you need.

The problems disappear when you invert the approach; our founders learned this when standing up mobile observability at Lyft and X/Twitter. That’s why we built bitdrift the way we did. The [Capture SDK](https://bitdrift.io/feature/performance-centric) logs everything locally to an on device [ring buffer](https://bitdrift.io/feature/ring-buffer). It tracks every log, every network request, and every lifecycle transition with full context and zero sampling. A real-time control plane lets you [or your agents](https://bitdrift.ai/) decide what to pull from exactly the devices you care about, the moment a blindspot becomes a problem. There's no redeploy, no guessing, and no ingest bill for data you never look at. Just backend grade observability for the most complex platform on earth.

What other lessons have you learned that we missed? [We’d love to hear from you](https://bitdrift.io/contact-us).

Interested in seeing what mobile-first observability looks like in practice?

* [Check out the bitdrift sandbox](https://bitdrift.io/sandbox) to explore the product yourself.
* [Start a free trial](https://bitdrift.io/signup) to dive right in.

---

## Frequently asked questions

### What are the biggest problems with mobile observability today?

The biggest problems reported by teams building out mobile observability are sampling, ingest based pricing that forces them to pre-decide what telemetry to collect, crash-centric tooling that misses OOM kills and degraded experiences, release cycle lag, missing app state, and investigations that are fragmented across disconnected tools.

### Why is sampling a problem for mobile debugging?

Sampling captures a small percentage of events to control costs. This works for trend monitoring but fails for debugging. Teams tell us the same story on repeat: when investigating a specific user's issue, they need that user's actual session data. With a standard sample rate, the relevant session most likely was never captured.

### Why do mobile bugs so often get closed as “can’t reproduce”?

The context that would explain the bug is rarely captured alongside the failure. This is one of the most common frustrations we hear from mobile engineering teams: logs show that something failed but not the state the app was in, leaving engineers unable to recreate the exact conditions that triggered the issue.

### Why doesn't crash reporting catch most mobile issues?

Many of the worst mobile experiences never register as crashes. OS level out-of-memory kills, ANRs, thermal throttling, and failed network requests all degrade the user experience without producing a stack trace. This gap is often the first thing teams discover once they start looking past crash rate as their main health metric.

### How does bitdrift address these problems?

bitdrift was built after our founding team learned these lessons firsthand at Lyft and X/Twitter. The Capture SDK logs everything locally on the device, unsampled, with full context. A real-time control plane retrieves exactly the data teams need when they need it without an app release. Pricing is based on monthly active applications rather than data ingestion, eliminating the per-byte penalty. And with the bitdrift Public API and bd skills, that full fidelity data is completely programmable and accessible to AI agents.
