Find the regression in minutes, not days.

xprem implements the expo-observe protocol: every metric, event and log comes back tied to the exact update that produced it, into your own ClickHouse, so a bad release shows up while the rollout is still small.

ota.acme.internal/overview

Overview

Is the app healthy right now?
AllLive24h
Online now
14,208

Pinged in the last 20 minutes, any route

Devices
1.24M

Installs that reported in

Sessions
8.6M

App runs observed

Events
41.2M

Logs and exceptions

OTA updates
37

Distinct updates running

App versions
6

Store versions in the field

Builds
14

Native builds in the field

Live activity

Devices by city over the selected period. Ripples are check-ins as they land.

listening4,182 cities

Busiest in view

  • New York47.3k
  • Tokyo44.1k
  • Paris41.2k
  • London38.6k
  • Mumbai36.7k
  • Delhi34.5k

Observe.

Monitor crashes, performance and the JS runtime of your apps, so you can tell what each update actually did to them.

CapabilityBuilt innothing to installObserveneeds ClickHouse · SDK 56+
Native crashBuilt inObserve
DownloadsBuilt inObserve
GeolocationBuilt inwith GeoIP DBObservewith GeoIP DB

Metrics

Bundle loadBuilt inObserve
Time to first renderBuilt inObserve
Time to interactiveBuilt inObserve
Cold launchBuilt inObserve
Warm launchBuilt inObserve
Update downloadBuilt inObserve
LogsBuilt inObserve
EventsBuilt inObserve
JS crashBuilt inObserve

Enterprise

Custom device attributesBuilt inObserve
Default needs no extra infrastructure.

Every update carries its own crash and download counts, which is the health figure you watch during a rollout. Point the server at a MaxMind database and check-ins also get a city.

ClickHouse is yours to query.

xprem implements the expo-observe protocol and writes into your own ClickHouse. Point anything that speaks SQL at it and keep the data where it already lives.

ClickHouseGrafanaDatadogPostHog
Two questions it answers.
  • Did this update change how the app performs?Every record carries the update that produced it, so you read a release against the one before it instead of one blended average across every version in the field.
  • Where do I need to debug?Break the same data down by device model, OS, app version, build and region to find the segment that is actually failing. A crash on one Android model does not look like a problem until you stop averaging it away.

Ask it harder questions.

The xprem MCP server exposes the whole Observe dataset to agents, behind the same OAuth sign-in and the same per-app permissions as the dashboard. Plain-language questions come back as tables and charts, cut the way the dashboard cuts them.

Claudexprem mcp · oauth · acme-app

Compare cold launch between 3.4.2 and 3.4.1, split by device model.

xprem · queried Observe

Overall p90 is flat, but the regression hides in one model:

Model3.4.13.4.2Δ p90
Galaxy A541.9s3.1s+63%
Pixel 81.6s1.7s+6%
iPhone 131.4s1.4s±0%
iPhone 15 Pro1.1s1.1s±0%

cold launch · p90 · last 7 days

The regression is isolated to Android mid-range: the Galaxy A54 nearly doubled.

And update download time by region, for the 3.4.2 rollout?

xprem · queried Observe

South America and India wait the longest:

São Paulo4.1s
Mumbai3.6s
Paris1.2s
New York0.9s

update download · p90 · by region · rollout 3.4.2

Ask about your app…

Split by anything

The same cuts the dashboard offers, from plain language: update, device model, OS, app version, build and region.

Release against release

Every record carries the update that produced it, so a release reads against the one before, not a blended average.

Scoped per app

This user reads acme-app's data but can't publish to it. The agent inherits exactly that.

More about the MCP server →

Run it on infrastructure you own.

xprem is one Go process: your Postgres, your bucket, your network. Deploy it on Railway, Docker, Kubernetes or a bare binary, and ship your first update today.