Self-hosted product analytics

See the signal in every event.

TrueSight collects every tap, screen and server event into one pipeline you run, then turns it into analytics, journeys, experiments and alerts. Your agents can drive all of it from the terminal.

Open source · self-hosted · hosted beta coming soon

Good morning, Alex

Acme App · Production · live data

7D30D90D

Daily active users

63.2K▲ 8%

New users · 30d

124.6K▲ 10%

Last 30 daysPrevious 30 days
050K100K150K200K250KAug 29Sep 1Sep 4Sep 7Sep 10Sep 13Sep 16Sep 19Sep 22Sep 25
Illustrative data
01Collect

One stream in. Everything else reads from it.

Web, iOS, Android and your backend send to one ingestion API. Each event is stored once for analysis and evaluated once against your live journeys, on infrastructure you run.

Webbrowser SDKiOSKotlin MPAndroidKotlin MPServerPython SDKIngestion APIvalidate · batchfan-outqueue per consumerClickHouse writerbatched, deduplicatedJourney engineevaluates every eventagainst live journeysClickHouseyour event storePush · Email · In-appsent on your rulesDashboardCLIAgents

At-least-once, end to end

A queued event is cleared only after it has been processed, so a restart re-delivers instead of dropping.

Batched writes, deduplicated

Events land in bulk and collapse on their id, so a retried batch never double-counts.

Every tenant isolated by project

Each project has its own keys and its own slice of every table, from ingest to query.

02Analyse

Every question, one store.

Trends, funnels, retention, flows, segments and a live stream, all over the same events. Explore them in the dashboard, or ask an agent to.

01Trends

Any event, any property, split and compared over time.

completed_purchase by platformLast 24 weeks
iOSAndroidWeb
Week of Aug 16iOS2,546Android1,610Web780
Illustrative data

02Funnels

See the step where people give up, and who they are.

Purchase funnelWithin 1 day
100%
opened_app
78%
viewed_product
42%
added_to_cart
35%
completed_purchase
Biggest drop-off
viewed_product → added_to_cart
▼ 46% of users
Illustrative data

03Retention

Weekly cohorts that show whether users come back.

Weekly retentionAny event
W0W1W2W3W4W5W6W7Aug 3100%64%51%43%41%31%28%23%Aug 10100%64%56%48%42%34%32%Aug 17100%66%55%49%39%33%Aug 24100%66%54%47%42%Aug 31100%67%54%51%Sep 7100%63%56%Sep 14100%65%Sep 21100%
Illustrative data

04Flows

The paths people actually take, from any starting event.

Paths after $session_start2 steps
$session_start100%searched50%offers23%my_orders16%exited11%added_to_cart36%applied_coupon14%
Illustrative data

05Segments

Behaviour and profile rules, sized live and summarised in plain English.

Frequent buyers on ProSegment
didcompleted_purchase≥ 3 timesin the last 30 days
And
profileplanispro
Members
~12.4K
26% of active users
Summary

Pro-plan users who made at least three purchases in the last 30 days.

Illustrative data

06Live events

Every event as it lands, with its properties, seconds after it happens.

Live eventsStreaming
EventPropertiesTime
completed_purchaseitems: 2country: Germanynow
added_to_cartsku: TS-104platform: ios2s
$screenscreen: search3s
applied_couponcode: WELCOME205s
completed_paymentamount: 49.00method: card8s
$session_startplatform: android9s
searchedquery: running shoes12s
Illustrative data
03Engage

Journeys that wait for the right moment.

Build lifecycle flows on a canvas. Every user moves at their own pace, quiet hours are on by default, and each open and click is credited to the step that sent it.

journeys / abandoned-cartLive · illustrative
yesnoTRIGGEREnters segment · Lapsed buyers18,240 enteredDELAYWait until their usual active timeusual_active_timeBRANCHOpened app in 24h?PUSHYour cart is still waitingQuiet hours · until 07:00EMAILSomething you left behindGOALCompleted purchase4,112 convertedwaiting · 2h 14mnosentheldopenedConverted
  • A visual builder

    Start a journey on an event, when someone enters a segment, or from a CSV upload.

  • Delays that respect each user

    Wait a duration, until a time of day, or until each user's own usual time.

  • Quiet hours by default

    Nothing lands 22:00–07:00; transactional sends can bypass it, one step at a time.

  • Per-user merge tags

    Upload a CSV and every column becomes a tag, rendered for that recipient only.

  • Opens and clicks, per step

    Push taps and email clicks are attributed back to the exact step that sent them.

Reach

Campaigns, templates and links, next to the data.

Push and email campaigns go to the segments you already built, personalised per user, and every link knows which app store to send people to.

Your cart is still waiting

now

2 items, saved for you

Back in stock: the one you viewed

2m

Grab it before it goes again

Your Pro trial ends tomorrow

1h

Tap to review your plan

Sent
48,210
Opened
31.4%
Clicked
12.8%

Illustrative numbers

Campaigns

One-off or scheduled sends to a segment or a list, with sent, opened and clicked for every recipient.

Subject

Hi Alex, 20% off your next order

Use WELCOME20 at checkout this week.

Email templates

Merge tags render from each user's profile at send time.

user_idcoupon_codeplan
10421WELCOME20free
22917SAVE15pro
33108WELCOME20free
WELCOME20 works on your next order

CSV merge tags

Every column becomes a tag for that send only; profiles stay untouched.

ts.link/spring-saleApp StoreGoogle PlayWeb

Deferred deep link: the install opens on the right screen.

Smart links

One link for every platform, and installs land on the screen you meant.

Upload once · WebP / AVIF on the way in

Asset library

Images live with the project, ready for every template and push.

22:00 – 07:00

on by default, per project

held until 07:00

Quiet hours

Deferred, not dropped: sends in the window wait for morning.

04Experiment

Ship the winner, not the hunch.

Feature flags and A/B tests on the same users your analytics already knows. Results update as data lands, and a guardrail breach pauses the variant before it costs you.

Assignmentpricing_banner · illustrative
TreatmentControlNot yet allocated
Allocation · auto-ramp50%
10%→ 25%→ 50%

Ramping only adds users. Nobody already in the test is reshuffled.

Deterministic bucketing: the same user lands in the same variant on every platform.

Resultsday 14 · illustrative
-10%0%+10%+20%day 1day 7day 14↑ Significant · +4.8% purchases
purchases_per_user
Primary
+4.8%↑ Winning
app_crashes
Guardrail
+0.1%Within bounds
refund_requests
Guardrail
−0.3%Within bounds
✓ SRM check · passedGuardrail auto-stop · armed
checkout/views.pyPython SDK · local evaluation
variant = flags.get_variant(    "pricing_banner",    {"user_id": uid},    attributes={"plan": "pro"},    default="control",)# in-memory, no network on the request path
  • Flags with rules and overrides

    Target by any trait, segment or id list; pin a user to a variant while you QA.

  • Layers and holdouts

    Keep competing tests mutually exclusive and hold a slice out of everything.

  • Sequential stats you can peek at

    Check results any day without inflating false positives.

  • Sample-ratio and guardrail alerts

    Broken splits and hurting guardrails go straight to Slack or email.

  • Auto-ramp and auto-pause

    Step allocation up when it's safe; pause a variant that breaches a guardrail.

  • Local or one decide call

    Evaluate in-process on your server, or with a single request from apps and web.

05Watch

Know before the stand-up does.

Put a monitor on any metric. TrueSight learns its weekly rhythm, tells Slack or email when it breaks, and tells you again when it recovers.

Purchasesdaily · anomaly
last 12 weeks · illustrative
wk 1wk 5wk 9today
ActualExpected for that weekday
TrueSight Monitors
#growth-alerts · 10:02 AM
● Firing

Purchases · anomaly

↓ 23% below expected for a Tuesday

10,200 vs ~13,240
Purchases are back in range✓ Recovered

Wednesday · one message, then quiet

Active users
48,210↑ 6.2% WoW
Purchases
11,480↓ 3.1% WoW
Conversion
23.8%↑ 0.9 pts WoW

Growth board · illustrative data

  • Threshold, change or anomaly

    Fixed limits, week-over-week moves, or a baseline learned from the same weekday and hour.

  • Hourly or daily

    Each bucket is checked an hour after it closes, so late events are counted.

  • Slack or email, not a firehose

    One alert when it fires, one when it recovers, with a cooldown in between.

  • A growth board

    Pin the metrics that matter and read week-over-week change at a glance.

06Automate

Analytics your agents can run.

Ask Claude Code for last week’s funnel and it runs truesight, reads the JSON, and hands back the answer. The same CLI builds cohorts and stands up journeys, on infrastructure you own.

Claude CodeCodexCursor
An agent driving TrueSight · illustrative
you ▸Show me last week's signup funnel, then build a cohort of everyone who dropped before upgrading.
truesight ▸funnels results 3f2a… --from -7d
truesight ▸cohorts create --body @drop-before-upgrade.json
{ "funnel": "Signup → Upgrade",
  "biggest_drop": "Invited Teammate",
  "rate": "39%" }
Cohort “Dropped before upgrading” created · 4,310 users
truesight funnels results

Query funnels, retention, cohorts, segments and events, and read structured JSON back. No screen-scraping a dashboard.

truesight journey create

Create, not just read. Agents build segments and funnels, and stand up journeys from a prompt.

--format json

JSON by default; --format table for humans. Pipe into jq, drop into CI, hand it to an agent.

truesight skill install

Installs the /ts skill, so Claude Code, Codex and Cursor know every command with no custom wiring.

Segments also get a plain-English summary, so anyone can tell what a rule set actually means.

SDKs

A few lines to your first event.

One API, init, track, identify, across web, mobile and your backend.

app.tsWeb SDK
1import { init, track, identify } from '@cityflo/truesight-web-sdk'2 3await init({ apiKey, endpoint })4 5track('completed_purchase', { items: 2, total: 49.9 })6identify('user_8f21', { plan: 'pro' })
npm install @cityflo/truesight-web-sdk

Browser apps and WebViews · ESM, CJS & UMD

Or grab the truesight CLI, prebuilt for macOS, Linux and Windows.

Offline-first

Events queue on the device and flush in batches, so a tunnel or a dead zone loses nothing.

Encrypted at rest

The queue is encrypted on web, Android and iOS before anything leaves the device.

Auto-tracked

Sessions, screens and clicks come for free; you add the events that matter to you.

Ownership

Your events never leave your infrastructure. Self-hosted, isolated per project, encrypted on the device and open source, so where the data lives and who reads it stays your decision.

Self-hosted, multi-tenant

Run the whole stack on your own cloud. Every project is isolated, and no event touches a third party.

Encrypted on the device

The SDK queue is encrypted before it leaves the phone or the browser, on every platform.

Retention you control

Your cluster, your rules: how long events live and who can query them is your call.

Built with Rust, ClickHouse and PostgreSQL.

MIT-licensed and opening up soon: pipeline, SDKs and CLI, yours to read, fork and run.

GitHub · coming soon
Hosted beta

Bring your events into sight.

The SDKs and CLI are published; the platform is being prepared for release. Join the waitlist and we’ll email you the moment your spot opens.