linux/arm64 decides whether an architecture keeps getting release images. Knowing
which versions are still live decides how long a migration baseline is supported. Neither
question needs a customer, an amount, or a domain, which is why none is collected.
The exact event
This is the complete JSON body, field for field:
The wire format also declares optional
features and counters maps. No Omniflow
process ever populates them, so they are omitted from every request. There is no module
inventory and no usage counter in what is sent today; if that changes, this page and the
public schema change in the same release.
Never collected
- Customer identifiers, Telegram IDs, usernames, or email addresses
- IP addresses, hostnames, domains, or URLs
- Payment amounts, currencies, wallet balances, revenue, or provider payloads
- VPN traffic, access links, subscription URLs, nodes, or device identifiers
- Tokens, secrets, message contents, plan names, ticket text, or any other free-form data
- Row counts of any kind — a number small enough to identify an installation is an identifier
Timing and failure behaviour
One heartbeat goes out immediately when the API starts, then one every 24 hours. The HTTP client has a 5-second timeout and the sender discards the result: a non-2xx answer, a DNS failure, and an unreachable collector are all treated identically, which is to say ignored. Telemetry can never block start-up, a request, a job, or shutdown, and async.Once guard means it starts at most once per process.
If the API cannot read or create the installation row — no APP_DATABASE_URL, or the
database is unreachable at start — it uses a random UUID for that process lifetime and
logs telemetry installation ID is ephemeral.
Switching it off
APP_TELEMETRY_ENABLED=nope means
enabled, not disabled — spell it false.
Configuration
Forks that want their own numbers set
APP_TELEMETRY_ENDPOINT to an HTTPS collector they
control. The endpoint is validated at start-up rather than at send time, so a typo is a
refusal to boot rather than a year of silently lost events.
Running a collector
APP_TELEMETRY_COLLECTOR_ENABLED=true mounts POST /v1/telemetry/events on this
installation and opens a second database pool for writes. The route does not exist on an
ordinary installation, which is why nothing needs to be firewalled off on one.
Every submission is validated before it is stored, and an event that fails any check is
rejected whole:
- the body is capped at 64 KiB and unknown JSON fields are refused outright
schemamust be1, andinstallation_idmust be exactly 36 charactersnamemust beinstallation.heartbeatorfeature.usageversion≤ 32,service≤ 16,os≤ 32,architecture≤ 32 characters- at most 64 features and 64 counters, each key ≤ 64 characters of
[a-z0-9._] occurred_atmust be non-zero, no more than 7 days old, and no more than 1 hour in the future
The strictness is deliberate: a collector accepts submissions from installations it does
not control, so an unbounded map or a free-form string would be an injection surface
rather than a data point.
feature.usage is accepted by the validator and emitted by
nothing, so a collector will only ever see heartbeats from Omniflow itself.
A collector deletes its own rows older than 180 days on a daily loop, independently of
the worker’s retention sweep. Maintainers use aggregate installation and platform trends
for compatibility and roadmap decisions. Raw events are not sold or shared for
advertising.
Related
Installation settings
Why the panel’s telemetry card and the running configuration can disagree.
Security
The wider privacy posture: redaction, secrets, and what never leaves.