OpenTelemetry under the hood · web + mobile SDKs

Your user saw 8 seconds.
Your dashboard saw 200ms.

Server metrics stop at the load balancer. Last9 RUM captures the rest — device, network, render — and links each frontend span to the backend trace behind it. One trace, from tap to database.

5 SDKs + alerting
Web, Android, iOS, React Native, Flutter — alert on errors, p95, crashes, ANRs
One trace
traceparent injected on every request — frontend span links to the backend trace
DNS → TTFB
every network call broken into connection-phase child spans, no config
0–100% sampling
per-session sampling rate, set in SDK config

The problem

Dashboards green.
Users gone.

The "app is slow" ticket lands, your p99 looks fine, and the investigation starts from zero. The slowest part of every request happens outside your infrastructure — on a device and a network you can't see.

The gap between p99 and a person

Backend latency excludes DNS, TLS, CDN, device CPU, and the user's network. A 200ms API response can still be an 8-second page for someone on a slow connection.

Two SDKs, two vendors, zero correlation

Frontend monitoring in one tool, backend traces in another. Connecting a JS error to the API call behind it means matching timestamps by hand.

Screen recording is a data problem

Session-replay tools capture rendered DOM — including fields your compliance team says must never leave the device. Masking is a patch on capture; not capturing is the fix.

Per-session pricing punishes traffic

When RUM is billed per session, a marketing campaign becomes an observability bill spike — so teams sample away the very users they wanted to watch.

Last9 RUM is spans and logs over OTLP — telemetry, not screen capture. It's priced like the rest of your telemetry and correlated with the rest of your telemetry.

How it works

One SDK per platform. One trace end to end.

Each SDK auto-instruments sessions, views, network requests, errors, and vitals — then injects a traceparent header on every outgoing HTTP request, so your backend trace continues the frontend span. The slow screen and the query behind it are the same trace.

  1. Web · Android · iOS · React Native · Flutter sessions, views, network, errors, vitals — per real user
  2. Last9 — correlation: session · view · frontend span · backend trace

    Every span and log carries a rolling session ID, and every network call carries traceparent into your backend. A crash resolves to the session, the screen, and the API call that preceded it — not a timestamp hunt.

  3. Discover → Applications performance · errors · sessions · alerts on RUM metrics

Platform coverage

What each SDK captures.

All SDKs instrument the same core signals — sessions, views, network, errors. Mobile SDKs also measure cold start, warm start, screen load, and time-to-full-display, and break every network call into DNS, TCP, TLS, and TTFB child spans automatically.

  • Web

    JavaScript

    Core Web Vitals — LCP, FCP, CLS, INP, TTFB. JS errors and promise rejections, fetch/XHR requests, SPA route changes, sessions. Works with React, Angular, Vue, Next.js.

    Setup guide →
  • Android

    Kotlin

    OkHttp interceptor, activity-lifecycle view tracking, crashes, ANR detection, periodic CPU and memory samples.

    Setup guide →
  • iOS

    Swift

    URLProtocol network capture, UIKit and SwiftUI view tracking, crash capture, WebView session correlation.

    Setup guide →
  • React Native

    TypeScript

    Bridges the native Android and iOS SDKs — fetch/XHR, React Navigation view tracking, JS and native errors, ANR detection on Android.

    Setup guide →
  • Flutter

    Dart

    Dart plugin over the native SDKs — HttpClient override, NavigatorObserver view tracking, Flutter framework errors.

    Setup guide →
  • Your platform

    ?

    The SDKs speak OTLP — spans and logs. If your platform isn't listed, tell us what you're building and we'll work out the integration with you.

    Request a platform →

Setup

One init block per app.

A script tag on the web, an init call at app entry on mobile. SDKs ship from Last9's CDN — no proprietary agent, no build-system surgery. Create a client monitoring token, scope it to your app's origin, and data starts flowing.

Read the RUM docs
<script src="https://cdn.last9.io/rum-sdk/builds/stable/v2/l9.umd.js"></script>
<script>
  L9RUM.init({
    baseUrl: "https://<your-last9-otlp-endpoint>",
    headers: { clientToken: "<your-client-token>" },
    resourceAttributes: {
      serviceName: "your-app-name",
      deploymentEnvironment: "production",
      appVersion: "1.0.0",
    },
  });

  // optional — tie sessions to a user on login
  L9RUM.identify({ id, email, name });
</script>
Full Web guide →

After setup you get:

  • Sessions, views, network, errors, and vitals captured automatically
  • Frontend spans linked to backend traces — traceparent on every request
  • Every network call broken into DNS, TCP, TLS, and TTFB
  • Alerts on error rate, p95 latency, crashes, ANRs — same engine as your backend alerts
See the RUM alerting guide →

What you can finally answer

Questions the "app is slow" ticket will ask.

  • Which release moved LCP — and on which pages?
  • Is checkout slow because of our API or the user's network?
  • Which app versions and devices throw this crash?
  • What did the session do in the thirty seconds before the error?
  • Which API endpoints fail most for real users, by geography?
  • Did yesterday's backend deploy slow down the mobile app's screens?

The next "app is slow" ticket deserves an answer.

One init block per app, and every session lands in Discover → Applications — linked to the backend traces you already have.

Start observing for free. No lock-in.

OpenTelemetry · Prometheus

Just update your config. Start seeing data on Last9 in seconds.

Datadog · New Relic · Others

We've got you covered. Bring over your dashboards & alerts in one click.

Built on Open Standards

100+ integrations. OTel native, works with your existing stack.