Skip to content

Telemetry

OpenJarvis ships anonymous usage telemetry by default so the team can see where the product breaks, what features people actually use, and how to make it better. This page documents exactly what is and isn't collected, where the data goes, and how to opt out.

TL;DR

  • On by default, anonymous, no chat content.
  • Anonymous — one random UUID per install, no email, no name, no IP.
  • No chat content, ever. Only counts, timings, and feature names.
  • Self-hosted backend on the OpenJarvis team's PostHog instance — data is not sold or shared with third parties.
  • 365-day retention, after which events are deleted automatically.

What we collect

Lifecycle events

Event Source Why we send it
install_started install.sh Top of install funnel
install_stage_completed install.sh Per-stage timing — where do people drop off?
install_completed install.sh Did the install succeed?
install_failed install.sh Which stage failed, and on what OS
app_opened Backend + frontend DAU / WAU / MAU
setup_completed Frontend First-run wizard finished
first_chat_sent Backend First-ever message — activation
uninstall_started uninstall.sh (if user runs it) Churn signal

Usage events

Event Why we send it
chat_session_ended Aggregated per-session: turn count, tokens, latency, tool count
tool_first_used Which built-in tools are actually adopted
model_changed How often users switch models
feature_used Which features get traffic, which don't
connector_auth_completed Which connectors people set up
error_shown_to_user User-visible error class (not stack trace)
feedback_submitted Was a rating given? Was a comment included?
settings_changed Which settings get toggled
usage_daily_summary Once-per-day aggregated counts

The canonical, authoritative list with every property name and its type validator lives in src/openjarvis/analytics/events.py. That file is the only place new events can be added — PR review is the gate.

What we never collect

Hard guardrails, enforced by code:

  • Chat content — prompts, model outputs, system messages, tool args.
  • File paths — anything matching ~/, $HOME, /Users/<name>, /home/<name>, file://.
  • Emails, names, phone numbers, addresses.
  • IP addresses (IPv4 + IPv6). PostHog's IP geo lookup is disabled server-side too.
  • MAC addresses, hardware serials, drive UUIDs.
  • Stack traces — only error class enums.
  • API keys, OAuth tokens, JWTs, bearer tokens, password assignments — matched and dropped at value level.
  • Hostnames that look personal (e.g. alice-macbook.local).
  • Lists, dicts, sets — composite values are never sent so PII can't smuggle through inside containers.

Two independent filters run before every event leaves the machine:

  1. src/openjarvis/analytics/redaction.py — value-level pattern matching (20+ regexes for PII).
  2. src/openjarvis/analytics/events.py — structural allowlist (event name + property name + type validator).

Any failure at either layer → the event or property is silently dropped. Tests covering the patterns: tests/analytics/test_redaction.py.

Where the data goes

  • Today (alpha): PostHog Cloud (US region) free tier. Disclosed here for transparency.
  • Production target: A self-hosted PostHog instance at analytics.openjarvis.ai, Hetzner US-East. Single-tenant, operated by the OpenJarvis team.
  • Never sold, shared with advertisers, or used for anything other than improving OpenJarvis.

Retention

  • Default retention: 365 days, then events are deleted by PostHog automatically.
  • jarvis analytics reset-id lets you orphan all of your past events by generating a fresh anonymous ID for future events.

How identity works

A single UUID v4 is generated on first install and stored at ~/.openjarvis/anon_id. The install script, backend, and frontend all read the same file so events across the full lifecycle tie to one person — without us ever knowing who that person is.

Delete the file (rm ~/.openjarvis/anon_id) and a fresh UUID will be generated next time the app runs. The previous UUID and its events are then orphaned.

For researchers and contributors

  • Adding an event: edit src/openjarvis/analytics/events.py, declare the spec, then update this page. PR review enforces both.
  • Adding a PII pattern: edit src/openjarvis/analytics/redaction.py and add a test case in tests/analytics/test_redaction.py.
  • Inspecting what your install sends: run with OPENJARVIS_LOG_LEVEL=DEBUG and grep for Analytics. You'll see every event name and (redacted) property dict before it ships.
  • Local telemetry (FLOPs, energy, latency stored in ~/.openjarvis/telemetry.db) is a separate subsystem documented in src/openjarvis/telemetry/. It never leaves the machine and is controlled by [telemetry] (not [analytics]) in config.toml.
  • The leaderboard / contest opt-in (OptInModal.tsx) is a separate, voluntary feature that publicly shares your energy and savings on the OpenJarvis leaderboard. It is not the same as analytics and requires explicit opt-in with a display name and email.