Telemetry

Elide ships a small, anonymous telemetry subsystem. It exists to answer operational questions -- which platforms run Elide, how often it crashes, how long runs take -- without collecting source code, file contents, arguments, or personally identifying information. This page documents exactly what is collected, how it travels, and every supported way to switch it off.

The subsystem lives in the elidetelemetry crate (crates/telemetry/). It is designed to never affect your program: every emission path is wrapped in catch_unwind, so a telemetry failure can never crash the binary, and a send that cannot complete is dropped rather than retried.

What is collected

Telemetry is event-based. There are exactly four event types, defined by the Event enum in crates/telemetry/src/model.rs:
EventWhen it firesPayload
Program bootAt startup, before command dispatchNo fields
Program exitBefore normal exitRun duration (ms), subcommand id, exit code, exit reason
Program crashOn a Rust panic or unhandled JVM exceptionCrash origin (rust/kotlin), exception/panic type name, error message, stack trace, active subcommand id
Dependency installAfter a dependency install completesEcosystem id (Maven/NPM), package count, bytes transferred, cached-package count, cache status, duration (ms)
The exit code, exit reason, and subcommand fields are omitted from the wire payload when they are zero or absent (ProgramExitEvent serde rules in model.rs). Boot and exit fire on every run so that runs and durations can be counted; the crash event fires only on failure.

Crash payloads

The crash event carries the exception type, message, and stack trace so that failures can be triaged. Both are bounded before transmission, in packages/entry/bin/bridge.rs (event_crash):

  • Error message -- truncated to 512 bytes (truncate_utf8(message, 512)).
  • Stack trace -- truncated to 4096 bytes (truncate_utf8(backtrace, 4096)).

No file paths beyond what appears in a stack trace, no command-line arguments, and no source code are included.

Per-run metadata

Every batch carries a small block of build/platform metadata (EventMetadata in model.rs), all of it baked in at compile time:

  • Elide release number and version.
  • Target platform (one of linux-amd64, linux-arm64, darwin-amd64, darwin-arm64, windows-amd64, or unknown).
  • Whether the build is a release build.
  • Whether debug symbols are present.
  • A feature bitmask.

Events are correlated within a single execution by a per-run identifier and a monotonic ordinal; timestamps are encoded relative to a fixed 2026 epoch to keep payloads small. No stable cross-run device or user identifier is part of the event model.

How it is transported

Telemetry has two transports. They are tried in order:

1. Sidecar (preferred, Linux only). A single background process per (user, Elide version) aggregates events from concurrent Elide invocations over local IPC, batches them, and uploads over HTTP/3. The sidecar is gated on Linux in crates/sidecar/src/policy.rs (is_sidecar_supported); macOS and Windows do not use it. See the sidecar source for batching and idle-shutdown behavior.

2. UDP fallback. When the sidecar is unavailable -- or declines an event -- buffered events are flushed as fire-and-forget UDP datagrams to Elide's relay (crates/telemetry/src/udp.rs). Datagrams are encrypted with AES-128-GCM-SIV using a per-build ephemeral X25519 key exchange, and compressed with zstd before encryption. The relay hostname is receiver.elide.events; datagrams go to UDP port 9514. Because UDP is connectionless, the firewall-visible DNS lookup for that hostname is the only network signal a tool like Little Snitch will correlate.

The HTTP transport endpoint and API key are compiled in at build time from the ELIDE_TELEMETRY_ENDPOINT and ELIDE_TELEMETRY_API_KEY build variables (crates/base/build.rs); they are not configurable at runtime.

UDP events are flushed when a terminal event (program exit) is recorded, so a short-lived command still delivers its boot and exit events on the way out.

How to disable it

Any one of the following disables telemetry. They are checked in crates/telemetry/src/lib.rs.

DO_NOT_TRACK environment variable

Elide honors the cross-vendor DO_NOT_TRACK convention. If the variable is set to any value, telemetry is disabled for the run (check_do_not_track, called from init_telemetry):

bash
export DO_NOT_TRACK=1
 elide ./script.ts

--no-telemetry flag

A global flag, available on every command, disables telemetry for that invocation (crates/cli/src/lib.rs):

bash
 elide --no-telemetry ./script.ts

--no-sidecar flag

A global flag that disables the background sidecar process (crates/cli/src/lib.rs). This does not disable telemetry on its own -- it forces the UDP fallback transport on Linux:

bash
 elide --no-sidecar ./script.ts

To both skip the sidecar and stop telemetry entirely, combine --no-sidecar with --no-telemetry, or set DO_NOT_TRACK.

When telemetry is disabled, the sidecar is not started either: the sidecar's only single-tenant purpose is telemetry aggregation, so should_use_sidecar returns false once telemetry is off (crates/sidecar/src/policy.rs).

EAP builds

Unlicensed Early Access ("EAP") builds always emit telemetry. On these builds force_enable_telemetry is called at startup, after which --no-telemetry and DO_NOT_TRACK become no-ops (packages/entry/bin/main.rs, crates/telemetry/src/lib.rs). Licensed builds respect every opt-out above. The --no-telemetry flag help text reflects this: *"Disallow telemetry; has no effect if unlicensed."*

Sources

  • crates/telemetry/src/model.rs -- Event, EventMetadata, event payloads
  • crates/telemetry/src/lib.rs -- check_do_not_track, disable_telemetry, force_enable_telemetry, is_telemetry_enabled, flush/terminal-event logic
  • crates/telemetry/src/udp.rs -- UDP relay, encryption, compression, RELAY_PORT
  • crates/telemetry/src/emit.rs -- sidecar IPC emission path
  • crates/sidecar/src/policy.rs -- is_sidecar_supported, should_use_sidecar
  • crates/cli/src/lib.rs -- --no-telemetry, --no-sidecar global flags
  • packages/entry/bin/bridge.rs -- event_boot/event_exit/event_crash, crash truncation
  • crates/base/build.rs -- ELIDE_TELEMETRY_ENDPOINT, ELIDE_TELEMETRY_API_KEY