Each self-hosted Kodus instance sends one anonymous heartbeat per day toDocumentation Index
Fetch the complete documentation index at: https://docs.kodus.io/llms.txt
Use this file to discover all available pages before exploring further.
https://telemetry.kodus.io. The payload contains aggregated counters and
runtime metadata only — never code, identities, or anything that could trace
back to you or your users.
This page documents exactly what is sent, why, where it goes, and how to
turn it off.
What we send
A singlePOST /v1/heartbeat once per UTC day, ~700 bytes. Example payload
(redacted UUID for clarity):
400.
What we never send
By design, the schema cannot carry:- User emails, names, OAuth tokens, API keys
- Repository names, branch names, PR titles, commit messages, code content
- Customer-identifying strings (org slugs, workspace names, custom domains)
- IP addresses (the receiver hashes the source IP with a daily-rotating salt for abuse detection only and never persists the raw IP)
- Any free-form text field
Why we collect this
Anonymous heartbeats let us answer questions we otherwise cannot answer for self-hosted users:- Which versions of Kodus are still in use, and how fast new releases get adopted
- How operators deploy (Docker / Kubernetes / bare metal), so we prioritise the platforms people actually run
- Whether features like Kody Rules are reaching self-hosted users at all
- Volume signals (PRs reviewed per fleet, repos connected) so we can size capacity decisions
Inspect what your instance would send
Before any heartbeat leaves your instance, you can dump the exact payload that the daily cron would build:jq to
explore:
Disable telemetry
SetKODUS_TELEMETRY_DISABLED=true in your environment. The cron skips
silently — no heartbeat is sent, ever, until you flip it back.
1, true, yes, on. Any
other value (including empty) keeps telemetry enabled.
Where the data lives
- Receiver: a small Node.js service (Fastify) deployed at
telemetry.kodus.io. Source code is public: kodustech/kodus-beacon. - Storage: Neon Postgres, US region, encrypted at rest, TLS-only.
Two tables —
telemetry_instances(one row per instance, last seen- version) and
telemetry_heartbeats(one row per instance per UTC day, payload stored as JSONB).
- version) and
- Retention: individual heartbeat rows are kept for 12 months. After that we aggregate the counters into historical statistics (e.g. “X active instances in January 2026”) and drop the per-day rows. The instance row stays — it carries no time-series, only the most recent version + last-seen timestamp.
- Access: product engineering team only, via individual Neon credentials with audit logging. The data is never shared with third parties and never used to train any AI model.
Source code you can audit
Both ends are open and small enough to read end-to-end:- Client (what runs on your instance): the cron, collector, and HTTP
transport live under
libs/telemetry/andapps/worker/src/cron/self-hosted-beacon.cron.ts. - Server (what runs at
telemetry.kodus.io): the entire receiver is ~80 lines of Fastify route + a Postgres upsert. See kodustech/kodus-beacon.