Anonymous report
What leaving the anonymous report on does, what Appflare sends and never sends, where it goes, and the ways to turn it off.
Appflare collects anonymous usage data to decide what to build and fix: the manager
sends an anonymous report once a day, with an event for each job, and the installer
sends one event when it ends. It is on by default and easy to turn off. The manager's first report
goes out with its first scheduled run after setup finishes (or, on a manager updated
from a version without the report, after the update). No banner in the manager
announces it: this page, Settings > Anonymous report in the manager, and the
installer's notice when it starts are where it is disclosed, and nothing waits for an
answer. A development build never sends anything, and a pre-release of the manager (a
version with a pre-release part, such as 0.4.0-rc.1) sends no report, so test
managers stay out of the numbers. Settings > Anonymous report says so on either,
and the Worker's log notes the skipped report once.
What it does for you
Every manager runs in someone's own Cloudflare account, where the maintainers cannot see it. The anonymous report is how they find out what happens there. Leaving it on lets them:
- Keep the versions you run working. They see which versions of the manager are in use, so they know which ones to keep supporting and which upgrade paths to test an update against.
- Fix what breaks, sooner. They learn which install paths, apps and steps fail, and how often, so the most common failures get fixed first and updates break less often.
- Work on what matters. They see which features people use, such as passkeys, automatic updates or notification channels, so time goes where it helps most.
Turning it off changes nothing about how Appflare works for you.
The anonymous report is not the usage Appflare shows you. What each of your apps uses of Cloudflare, and what it costs, stays in your Appflare; the report only counts pausing and resuming an app as jobs, like the others below. See Usage and spend protection.
What is sent
Every event carries the Appflare version, whether it came from the manager or the installer, and the random id described below. Everything else is a count, a yes or no, a version, a duration, or a value from a fixed list, apart from the filtered Cloudflare error message a failed job can carry (below).
Daily report (manager)
Once a day, the manager sends one report with:
- Manager: its database schema version, the Workers plan chosen in Settings > Your account (
free,paidor unset), whether it uses Appflare's catalog or a custom one, how many catalogs were added in Settings > Catalogs (a count only, never their URLs or labels), days since setup, and whether a newer manager release exists. - Users: how many users and admins there are, whether passkeys are in use, and how many users have one.
- Features: whether Cloudflare Access protection is on, whether the sandbox Worker is connected, whether Appflare and apps update automatically, and how many apps use the account setting for automatic updates or override it with on or off, and how many notification channels there are of each kind (Telegram, Slack, Discord, webhook), and how many GitHub access tokens there are (the count only: never a label, a repository or a token).
- Apps: how many are installed, counted by status (installed, failed, installing, updating, uninstalling), by build type (prebuilt, sandbox, self-deploying), and by version age (current, or, when the catalog has a newer version, how long ago the running one was installed: under 7 days, 7 to 30, 30 to 90, over 90 days); how many have a custom domain, Email Routing, or cron triggers; how many install as several Workers; how many come from added catalogs; how many removed apps still keep data; and the catalog slugs of the installed apps, only for apps in Appflare's own catalog.
Jobs (manager)
For each install, update, settings change, rollback, database restore, uninstall, deletion of a removed app's kept data, build for review, pause, resume, manager self-update, and manager rollback, one event when it starts and one when it ends, with:
- the kind of job, the app's catalog slug (
customfor an app from a custom catalog or from a repository), the version it moves from and to (none for a custom catalog's app, an app from a repository, or an app built from source), the build type, where the app comes from (catalog,repositoryorsource), how many Workers the app installs, and what started it (an admin, or the schedule for automatic updates and automatic pauses); a manager rollback carries its kind only, never the versions it moves between. Nothing about a repository is sent: not its address, owner, name, branch or commit; - when it ends: whether it succeeded, how long it took, and for a failure, its
error category (such as
cloudflare_permission,plan_limit,d1_migrationoraccess_conflict), the phase it failed in (such asresources,upload,healthoraccess), and, for a failed Cloudflare API request, the HTTP status and Cloudflare's numeric error code. When the failure is in the Cloudflare categories (cloudflare_permission,cloudflare_rate_limited,cloudflare_unavailable,cloudflare_rejected), it also carries an excerpt of Cloudflare's own error message (cf_message, at most 200 characters, such asincomplete input: SQLITE_ERROR). The excerpt starts after Cloudflare's error code, so it never holds the request's method or path. It ends at the closing bracket when Appflare put Cloudflare's message in brackets, and otherwise at the first semicolon that does not start another of Cloudflare's errors, or at a line break. Before it is sent, anything in quotes, anything shaped like a hostname and every IP address is replaced (Cloudflare's own hostnames, such asdash.cloudflare.com, and its error keys, such asaccess.api.error.conflict, are kept), and so is everything the failure report filter takes out: your account id, other ids, email addresses, anything that looks like a token or password, your workers.dev subdomain, and every hostname, Worker name and other name Appflare recorded. Then every other word of three characters or more with a hyphen, an underscore or a digit in it, such asacme-payroll-api, is replaced ([name]), except error constants in capitals such asSQLITE_ERROR, error codes in brackets, numbers of up to six digits (HTTP statuses, error codes and limits), versions and dates. A name made only of letters, such asIntranet Portal, cannot be told apart from Cloudflare's own words, so it stays in the excerpt unless Appflare recorded it. If Appflare cannot read the names it recorded when it reports, the excerpt is left out.
Setup and use (manager)
- Once, after setup: how many minutes passed between connecting Cloudflare and creating the owner, and whether the manager continues the installer's id.
- At most once a day: that the manager was opened that day, and whether the first person to open it was an admin or a member.
Installer
The installer sends one event per run, when the install ends:
- whether it succeeded, failed or was cancelled, how long it took, the last step it
reached, and an error category (such as
wrangler_login,wrangler_deployorhealth_timeout); - the installer's version, the operating system, CPU architecture and Node.js major version;
- whether it ran interactively, in CI, or with
--yes; whether the Worker name was the default one; whether the login had several accounts; whether a wrangler login was needed; the coding agent it ran under, if any (such asclaude,codexorcursor, from the variables those agents set).
What is never sent
Your Cloudflare account id or name, email addresses, user names, Worker or instance names, domains or URLs, secret or variable names or values, tokens, resource ids, logs, error messages, or anything from a custom catalog, its app names and versions included. The exceptions to logs and error messages are the filtered excerpt of a Cloudflare API error message described above, and a failure report, which only an admin sends, by hand.
How it is sent
Every event is tied to a random id created at install, never to a person. Setup with the installer creates the id and hands it to the manager, so both report under the same id. The manager sends from its Worker, not from your browser: there is no tracking script, no cookie and no page view. The installer sends from your machine, and gives up after 3 seconds so a run is never held up.
Preview in Settings > Anonymous report shows the next daily report, built the same way the scheduled one is.
Where it goes
Events go to PostHog Cloud in the EU region (Frankfurt), at
eu.i.posthog.com, as anonymous events: every event asks PostHog to create no
person profile and to skip its IP-based location lookup.
Two more protections are PostHog project settings, not something the code enforces: the Appflare project is set to discard IP addresses, and events are kept for as long as PostHog's plan retains them (a year on the free plan).
Failure reports
When a job fails, admins see Send a report on the failure message: on the job's page, and on the sandbox and Appflare update cards. Nothing is sent until an admin opens it, reads what the report contains, and clicks Send. A report is never sent automatically, and each failed job can be reported once.
A report contains:
- the kind of job, the app's catalog slug and version (with the same rules as the
job events above, so
customfor an app from a custom catalog or a repository), the Appflare version, and the Workers plan; - the step the job stopped at, its error, the error category and phase, and every Cloudflare error code in the log;
- the job's log (its last 400 lines at most);
- a note, if the admin writes one;
- the same random id as the anonymous report, and whether the anonymous report is on.
Before the report leaves, the error, the step, the log and the note are passed once
more through a filter that takes out anything that looks private: tokens, keys and
passwords, including every value of a NAME=value environment line and of flags
such as --password (shown as [redacted]); email addresses ([email]); your
Cloudflare account id ([account id]); other Cloudflare ids and UUIDs ([id]);
your workers.dev subdomain and your custom hostnames ([domain]); the names of
your Workers ([worker]); and the other names Appflare recorded: the apps'
databases, namespaces, buckets, queues and Access applications, and the names you
gave apps ([name]). What stays readable is what a fix needs: Cloudflare's
error codes and HTTP statuses, step names, versions, and the app's catalog slug.
The dialog's See exactly what is sent shows the report exactly as it will leave,
after that filter.
A failure report goes the same way as the anonymous report: from the manager's Worker
to the Appflare PostHog project in the EU, as an event called job_failure_report. It
is sent even when the anonymous report is turned off, because the admin chose to send it; the dialog says
so. A development build never sends one.
Turning it off
Any one of these stops everything:
- The Send the anonymous report switch in Settings > Anonymous report (admins).
- The installer's flag:
npx create-appflare --no-telemetry. APPFLARE_TELEMETRY=off(0andfalsework too) orDO_NOT_TRACK=1in the installer's environment.- The same variables on the manager's Worker, set in the Cloudflare dashboard under
the Worker's Settings, Variables and Secrets. Either one locks the anonymous
report off: Settings > Anonymous report shows the switch off and disabled, with "Turned off by the
APPFLARE_TELEMETRY variable on this Worker. Remove the variable to change this
here." (naming
DO_NOT_TRACKwhen that is the one set). Updates of the manager keep the variable.
When the installer's report is off by the flag or a variable, it deploys the
manager with APPFLARE_TELEMETRY=off, so the manager's is locked off too.
When it is off, nothing is sent, not even the fact that it is off, apart from a failure report an admin chooses to send. Turning it on again continues with the same random id, and jobs that ran while it was off are not reported.
Wrangler's own metrics
The installer runs wrangler to deploy the manager. Wrangler has usage metrics and
error reports of its own, which go to Cloudflare. The installer turns both off for
every wrangler command it runs, whether Appflare's anonymous report is on or off, unless
you set WRANGLER_SEND_METRICS or WRANGLER_SEND_ERROR_REPORTS yourself.
Security model
Signed artifacts, pinned builds, what the manager does with its access to your Cloudflare account, the browser installer's part, sessions, roles, notification credentials, and the optional Cloudflare Access protection.
FAQ
Free plan limits, health check results, R2 and payment methods, and removing Appflare.