Skip to content

Privacy & Telemetry

The Alchemy CLI and the Cloudflare State Store worker emit OpenTelemetry traces, metrics, and logs to a relay we operate at otel.alchemy.run, which forwards to our Axiom workspace. The data helps us prioritize providers, find bugs, and understand which features people actually use.

This page documents exactly what is collected, what is not, where it goes, and how to opt out. Source of truth is the code: Telemetry/Attributes.ts and Cloudflare/StateStore/Api.ts.

Resource attributes attached to every span/metric/log:

AttributeValue
alchemy.user.idRandom UUID generated on first run, persisted at ~/.alchemy/id. Not your shell user, email, or hostname.
alchemy.session.idRandom UUID per CLI invocation.
alchemy.versionThe version of the alchemy package you’re running.
alchemy.git.root_commitSHA of the first commit in your repo. Acts as a stable repo fingerprint.
alchemy.git.origin_hashSHA-256 of git config remote.origin.url. The raw URL is never sent.
alchemy.git.branch_hashSHA-256 of the current branch name.
alchemy.runtime.name / .versionbun / node / deno and its version.
alchemy.ci / alchemy.ci.providerWhether this looks like a CI run, and which provider (GitHub Actions, GitLab, etc.).
host.arch, os.type, os.version, host.cpus, host.memory_mbCoarse machine info.

Per-operation span attributes:

  • cli.<command> spans carry the command name (deploy, destroy, plan, …) and outcome (success / error).
  • provider.<op> spans carry the resource type (AWS.S3.Bucket, Cloudflare.Workers.Worker, …), op (create / update / delete / read), and outcome.
  • state_store.init spans carry the state-store backend slug (local, inmemory, http, cloudflare-http, or any third-party slug).

When you deploy the Cloudflare State Store it runs as a Worker on your Cloudflare account. The worker emits OTLP traces/metrics/logs to the same otel.alchemy.run relay.

Resource attributes (set on every signal from the worker):

AttributeValue
service.namealchemy-state-store
service.versionThe deployed worker contract version (currently 2).
alchemy.state_store.script_namealchemy-state-store.

Per-request span attributes (one per state-store API call):

AttributeValue
alchemy.state_store.opgetState / setState / deleteState / listStacks / listStages / listResources / getReplacedResources / deleteStack / getVersion
alchemy.state_store.stackThe stack name from your alchemy.run.ts (e.g. MyApp).
alchemy.state_store.stageThe stage name (e.g. prod, dev_alice).
alchemy.state_store.fqnThe fully-qualified resource name within the stack (e.g. bucket/uploads).
durationOp latency.

CLI-side spans that touch the Cloudflare State Store (state_store.bootstrap, state_store.deploy, state_store.init) also carry alchemy.cloudflare.account_hash — a SHA-256 of your Cloudflare account ID. The raw account ID is never sent. We use the hash to count distinct deployments without identifying anyone.

  • Secrets, API tokens, environment variables, .env contents.
  • Resource property values, source code, file contents.
  • Raw filesystem paths, hostnames, or shell user names.
  • Raw git URLs, raw branch names, raw Cloudflare account IDs (only SHA-256 hashes of these).
  • IP addresses (the relay strips them before forwarding).
  • Any tracking cookies, advertising IDs, or third-party identifiers.

otel.alchemy.run is a Cloudflare Worker we operate. It accepts standard OTLP/HTTP at /v1/traces, /v1/logs, and /v1/metrics, attaches an Axiom ingest token server-side, and forwards to our Axiom workspace. Source for the relay lives at stacks/otel/Ingester.ts.

We do not share or sell the data. Aggregated stats may appear in public talks, posts, or dashboards.

Any one of these disables the OTLP exporter entirely. The CLI’s default tracer becomes a no-op, so nothing leaves your machine:

Terminal window
DO_NOT_TRACK=1 alchemy deploy
NO_TRACK=1 alchemy deploy
ALCHEMY_TELEMETRY_DISABLED=1 alchemy deploy

To make the opt-out persistent without setting an env var on every run, create the marker file:

Terminal window
mkdir -p ~/.alchemy
echo "true" > ~/.alchemy/telemetry-disabled

To re-enable, delete the file:

Terminal window
rm ~/.alchemy/telemetry-disabled

Cloudflare State Store — opt out per-deployment

Section titled “Cloudflare State Store — opt out per-deployment”

The state-store worker exports its own OTLP signals — these go through the same relay but flow even if your CLI’s telemetry is disabled (because the worker runs on your CF account, not your machine). Two mechanisms exist:

noTrack option. Passes through to the CLI-side state-store spans, suppressing the alchemy.cloudflare.account_hash attribute:

import * as Cloudflare from "alchemy/Cloudflare";
Cloudflare.state({ noTrack: true });

NO_TRACK env var. When Cloudflare.state() is called without an explicit noTrack, it falls back to NO_TRACK from the environment.

Terminal window
NO_TRACK=1 alchemy deploy

noTrack only suppresses the account-hash attribute on state-store spans. To stop the worker from emitting signals at all, you’d need to remove the OTLP layer in your own fork of Api.ts, or run a custom HTTP state store via makeHttpStateStore.

Email sam@alchemy.run or open an issue at alchemy-run/alchemy-effect.