telemetry · schema 1 ·
What FearMiner collects
An anonymous report from each rig, on by default and off with one switch. Every field it carries is here, with why it is sent and what is done with it, and so is everything it never carries.
Built from the schema file every release carries (telemetry-schema.json, schema 1); the miner's tests refuse a report with a field outside it. The dated history of this page is at the bottom.
Contents
01 · in short
In short #
- what
- 22 fields in 12 groups, the ones the egress line names at start:
event,install,format,version,system,mining,hardware,hashrate,features,uptime,errors,pool. The hashrate goes as a wide bucket, never the figure. - never
- the wallet, the worker name, a login or a password, the machine's name, the IP address, a serial number, a path, a configuration value, anything of the cockpit. The full list is below.
- when
- once the run is under way, every 15 minutes, and at a clean stop; never more often than every 5 minutes.
- where
- telemetry.fearminer.com, a service of its own, walled off from the cockpit and its relay. The country is kept, never the address.
- kept
- raw points about 3 months; daily counts without any install id, longer.
- off
--no-telemetry, orFEARMINER_NO_TELEMETRY=1: no install id is drawn or kept, nothing is sent, and the miner loses no feature.- see it
fearminer telemetry showprints the beat this machine would send, and sends nothing.
02 · field by field
What is sent, field by field #
Each group, then each of its fields: what is sent, why, and what is done with it. A field without a reason is not sent.
One beat, as it leaves the rig:
{
"schema": 1,
"kind": "beat",
"first": false,
"previous_version": null,
"install": "5f0c3b8e2a9d4c71b6e8f0a1d2c3b4a5",
"interval": 15,
"version": "1.5.1",
"build": "f6f9d649c",
"os": "linux",
"os_release": "debian-13",
"mining_os": null,
"algo": "quantus",
"engine": "1.0.1",
"engine_build": "linux-x86_64-cuda",
"driver": {"nvidia": 575, "cuda": 12},
"gpus": [{"model": "GeForce RTX 4070 Ti", "count": 2}],
"cpu": {"vendor": "amd", "model": "Ryzen 9 9950X", "cores": 16},
"rate": {"bucket": "1G-2G", "unit": "H/s"},
"features": ["doh", "failover", "helper", "service", "tls"],
"uptime": "lt1d",
"errors": {"E116": 3},
"pool_host": "pool.example.com"
}The ingestion checks each report against the schema, adds the country and writes one data point; what is read from the points is counts, such as how many installs run each version, system or algorithm. The last column says what becomes of each field.
The event event #
Which moment the report is: a start, a beat or a stop.
| field | sent | why | what is done with it |
|---|---|---|---|
kind"beat" | start, beat or stop. | A start counts a launch, beats say a rig still runs, a stop says it ended on purpose. Beats that end without a stop mean a crash or a lost network. | Stored with the point: launches, running rigs and clean stops are counted from it. |
firstfalse | true on the start of a new install, when the id was just created; false otherwise. | Tells a new install from a restart. | Stored as 1 or 0: new installs are counted from it. |
previous_versionnull | On a start, the version this install ran last time, when it was another one; null otherwise. | Shows which versions people upgrade from, and which releases they skip. | Stored with the point: the adoption of each release is followed from it. |
The install id install #
A random number that stands for this installation and for nothing else.
| field | sent | why | what is done with it |
|---|---|---|---|
install"5f0c3b8e2a9d4c71b6e8f0a1d2c3b4a5" | 32 hexadecimal characters: 16 random bytes drawn on the first start and kept in telemetry-id in the state directory, readable by your account only. Derived from nothing: not the hardware, not the wallet, not the time, not the cockpit. | Two uses and only two: counting rigs without counting one twice, and following how fast a version is adopted. | The index of the data points, so that distinct installs can be counted; the daily counts carry none. fearminer telemetry rotate-id draws a new one. |
The format format #
How to read the rest of the report.
| field | sent | why | what is done with it |
|---|---|---|---|
schema1 | The schema number: 1. | A report of a newer version can be read by an older reader: an added field breaks nothing, and a reader skips what it does not know. | Checked by the ingestion, which refuses what it cannot read; not stored. |
interval15 | The minutes between two beats: 15 by default, 5 to 1440 (--telemetry-interval). | Tells when the next beat is due. | The ingestion checks the floor again, then stores the number. |
Version and build version #
Which release of the miner runs.
| field | sent | why | what is done with it |
|---|---|---|---|
version"1.5.1" | The miner's release version. | How fast a release is adopted, and how many rigs still run a version that a fix concerns. | Stored with the point; counted per version. |
build"f6f9d649c" | The short commit id of the build. | Tells two builds of one version apart. | Stored with the point. |
The system system #
Where the miner runs.
| field | sent | why | what is done with it |
|---|---|---|---|
os"linux" | linux, windows or macos. | Where the packaging and testing effort should go. | Stored with the point; counted per system. |
os_release"debian-13" | The system's short name and major version only: debian-13, ubuntu-24, windows-11, macos-15; linux-other when unknown. Never a kernel string, never a host name. | Which system versions the supported platforms really have to cover. | Stored with the point. |
mining_osnull | hiveos or mmpos when the miner runs under one; null otherwise. | Whether the HiveOS and mmpOS integration serves anyone. | Stored with the point. |
What is mined mining #
The algorithm, the engine that mines it, and the drivers' major versions.
| field | sent | why | what is done with it |
|---|---|---|---|
algo"quantus" | The algorithm's name, as the catalogue gives it; null when nothing is mined. | Which algorithms the rigs mine, and where kernel work matters most. | Stored with the point; counted per algorithm. |
engine"1.0.1" | The version of the engine that mines; null when there is none. | Follows the engines' own releases, which come without a miner release. | Stored with the point. |
engine_build"linux-x86_64-cuda" | The engine's platform build, such as linux-x86_64-cuda; null when there is none. | Which builds are really used: CPU or CUDA, and on which platform. | Stored with the point. |
driver{"nvidia": 575, "cuda": 12} | The NVIDIA driver's major version and the newest CUDA major it runs, majors only (null when absent); other keys may come later (ROCm, Metal). | Which driver floor can be raised without breaking rigs that exist. | Stored as one label, such as nvidia575 cuda12. |
The hardware hardware #
Models and counts; never a serial number or a card's identifier.
| field | sent | why | what is done with it |
|---|---|---|---|
gpus[{"model": "GeForce RTX 4070 Ti", "count": 2}] | Each GPU model with its count, the name normalized (no vendor prefix, no memory size), sorted, 16 models at most. Never a UUID, a serial number or a PCI bus id. | Which cards the kernels should be tuned for first, and whether a supported model is used at all. | Stored as one label (GeForce RTX 4070 Ti x2) and the total number of cards. |
cpu{"vendor": "amd", "model": "Ryzen 9 9950X", "cores": 16} | The vendor (amd, intel, apple or other), the model's marketing name, and the number of physical cores. | Which CPU families the MSR presets and the memory placement should serve first. | Stored as the vendor, the model and the core count. |
The hashrate, as a bucket hashrate #
A wide bucket, never the figure; the buckets are below.
| field | sent | why | what is done with it |
|---|---|---|---|
rate{"bucket": "1G-2G", "unit": "H/s"} | The rig's total rate on its algorithm, as a bucket of the 1-2-5 series, with the algorithm's unit; null when nothing is mined. | How much FearMiner hashes as a whole, and a slowdown between two versions on the same hardware, without ever giving a farm's exact figure. | Stored as the bucket and the unit. |
Features in use features #
Which settings are in use, as named flags, never their values; the flags are below.
| field | sent | why | what is done with it |
|---|---|---|---|
features["doh", "failover", "helper", "service", "tls"] | The names of the flags in use on this rig, sorted, 48 at most: only the fact that a setting is in use, never its value. | Which features run on real rigs, not only which were shipped: where the next effort should go. | Stored as one label; counted per flag. |
Uptime, as a bucket uptime #
How long this run has lasted, never to the second.
| field | sent | why | what is done with it |
|---|---|---|---|
uptime"lt1d" | lt1h, lt1d, lt1w or ge1w: under an hour, under a day, under a week, a week or more. | How stable the miner really is in production, beside the restarts its supervisor counts. | Stored with the point. |
Error codes errors #
The stable codes the miner printed since the last report that got an answer, with their counts; never a message.
| field | sent | why | what is done with it |
|---|---|---|---|
errors{"E116": 3} | Each stable code the miner printed since the last report that got an answer (E116 and the like), with its count, 64 codes at most; a report that got no answer at all leaves them for the next one. Never a message, a trace, a path or a host. | The bugs nobody reports: someone who sees E116 three times a day changes miner rather than opening a ticket. | The total is stored with the point, and each code gets a point of its own with the version, the system, the algorithm and the country, to rank the codes by count and by share of rigs. |
The pool's host pool #
Which pools the rigs mine on.
| field | sent | why | what is done with it |
|---|---|---|---|
pool_host"pool.example.com" | The host name of the first pool, in lower case, and nothing after it (no port, path, user or query), only when it is a public DNS name: an IP address, a one-label name, a private suffix such as .lan or .local, or an onion sends null. | Which pools the miner must be tested with at each release. | Stored with the point. |
03 · hashrate buckets
The hashrate, as a bucket #
The rig's total rate on its algorithm leaves as a bucket, in the algorithm's own unit, never as the figure. The buckets follow the 1-2-5 series:
00-11-22-55-1010-2020-5050-100100-200200-500500-1k1k-2k…500M-1G1G-2G2G-5G5G-10G…0 is a rig at zero and 0-1 a rig under 1; every other bucket runs from one value of the series to the next, 1, 2, 5, 10, 20, 50, 100 and so on, written with k, M, G, T and P and no decimals. A few rates, and what is sent for each:
| 0 H/s | {"bucket": "0", "unit": "H/s"} |
|---|---|
| 5.4 kH/s | {"bucket": "5k-10k", "unit": "H/s"} |
| 618.4 MH/s | {"bucket": "500M-1G", "unit": "H/s"} |
| 1.29 GH/s | {"bucket": "1G-2G", "unit": "H/s"} |
| 7.74 GH/s | {"bucket": "5G-10G", "unit": "H/s"} |
| nothing mined | null |
Wide enough to tell a rig's size, and a version that got slower on the same hardware; too wide to give a farm's exact figure.
04 · feature flags
The feature flags #
The features field carries the names of the flags below that are in use on the rig, 46 flags in schema 1. A flag says that a setting is in use, never its value: proxy says there is a proxy, never which one.
| flag | meaning |
|---|---|
api-public | The API listens beyond 127.0.0.1 (--api-bind). |
background | The miner runs without a console (--background). |
cert-pin | A pool's certificate is pinned by its fingerprint (--tls-fingerprint); never the pin. |
cockpit | The rig is enrolled in a cockpit: a yes, never which fleet or which rig. |
config-file | A configuration file is read (fearminer.toml); never its contents. |
cpu | CPU threads mine. |
cpu-affinity | The CPU threads are placed by hand (--cpu-affinity); never where. |
doh | DNS over HTTPS resolves the pools, the system resolver as the fallback (--dns doh). |
doh-strict | DNS over HTTPS alone resolves the pools, with no fallback to the system resolver (--dns doh-strict). |
engine-pinned | An engine is held at a version (--engine ALGO=VERSION). |
failover | More than one pool is configured. |
gpu | At least one GPU mines. |
heartbeat | A heartbeat URL is pinged (--heartbeat-url); never the URL. |
helper | The privileged helper is installed where the miner finds it (fearminer-helper, Linux). |
hooks | Programs run on events (--hook); never which. |
hugepages | RandomX's dataset has all the huge pages it needs. |
hugepages-1g | RandomX's dataset is on 1 GiB pages (--1gb-pages). |
igpu | Integrated GPUs mine too (--igpu). |
ipv4-only | The pools are reached over IPv4 only (--ipv4-only). |
ipv6-only | The pools are reached over IPv6 only (--ipv6-only). |
log-file | The log is also written to a file (--log-file); never its path. |
msr | MSR presets are applied for RandomX (--msr). |
no-api | The stats endpoint and the API are off (--no-api). |
no-history | The rig keeps no history of its own (--history off). |
no-nvml | The GPU sensors are not read (--no-nvml). |
no-supervisor | One process, without the supervisor that restarts it (--no-supervisor). |
no-verify | GPU solutions are not re-checked on the CPU before they are submitted (--verify-shares off). |
no-wallet-check | The wallet is sent to the pool unchecked (--ignore-wallet-check). |
no-watchdog | The watchdog's checks are off (--no-watchdog). |
notify-discord | Notifications go to Discord (--notify-discord); never the webhook. |
notify-telegram | Notifications go to Telegram (--notify-telegram); never the token or the chat. |
notify-webhook | Notifications go to a URL of the user's (--notify-url); never the URL. |
oc | Clocks, power limit or fan are set by the miner on at least one card (--cclock, --mclock, --pl, --fan). |
oc-script | A program runs for each card before mining (--oc-script); never which. |
proxy | The pools are reached through a SOCKS5 proxy (--proxy); never its address. |
root | The miner runs as root (--allow-root). |
service | The miner runs as the installed service, of an account or of the machine (fearminer service install). |
service-system | The service is the machine's (fearminer service install --system). |
skip-preflight | The start-up checks are reported and not acted on (--skip-preflight). |
spki-pin | A pool's certificate is pinned by its public key (--tls-spki); never the pin. |
tls | At least one pool is reached over TLS (stratum+ssl). |
tls-insecure | Pool certificates are not verified (--tls-insecure): a TLS port forward or a proxy. |
tofu | Pool certificates are trusted on first use (--tls-tofu). |
tui | The full-screen panel is shown. |
unrestricted-api | The API takes more than the reversible commands (--unrestricted-api). |
watch-config | The configuration file is watched and reloaded when it changes (--watch-config). |
05 · never sent
What is never sent #
In no version and under no option: nothing that identifies a person or an account. The list, word for word as the schema file publishes it:
- wallet
- worker name
- pool login or password
- machine name
- MAC address
- card or disk serial number
- GPU UUIDs or PCI bus ids
- file paths
- configuration contents or values
- IP address (the ingestion reads the country from Cloudflare and never the address)
- anything of the cockpit or relay (rig fingerprint, keys, codes)
The miner's tests hold every report to the schema: a field outside it fails the build, and so does a test configuration's wallet, worker, password, host name or path found anywhere in it.
start | Once per start, when the run is under way: at the first accepted share, a minute after the start at most, or at once when there is nothing to mine. It never delays the first share. Carries first and previous_version. |
|---|---|
beat | Every 15 minutes by default. --telemetry-interval (FEARMINER_TELEMETRY_INTERVAL, or telemetry_interval under [output] in the configuration file) sets 5 to 1440 minutes: under 5 is raised to 5, over a day lowered to a day, and the log says so; the ingestion checks the same floor. The error codes the miner printed since the last report that got an answer ride on it. |
stop | On a clean stop only, holding the exit 2 seconds at most. |
- A crash sends nothing: the missing beat says it.
- A report that does not go through is lost: never queued, never sent again, never sent later in a burst. Only its error counts wait for the next report.
- The miner never reads the answer and logs a failure at debug level only: it mines the same whether telemetry.fearminer.com answers, refuses or is down for weeks.
- In the figures, a rig connected now is a rig seen in the last 20 minutes, so at the default interval one late beat does not drop it.
Why not every minute: a rig does not change its algorithm, its cards or its country from one minute to the next, so a minute cadence would multiply the volume by fifteen and tell nothing more. Following one rig minute by minute is what the cockpit does for its owner, not what an anonymous count is for.
07 · where it goes
Where it goes, and what is kept #
telemetry.fearminer.com is a service of its own: a Cloudflare Worker that checks each report and writes it down.
| request | One HTTPS POST of a few hundred bytes of JSON to https://telemetry.fearminer.com/v1/beat, with the User-Agent fearminer/<version>, five seconds at most, through the proxy and resolver the pools use; the ingestion refuses more than 8 KiB. The answer is a status code and nothing else: never a setting, never an order. |
|---|---|
| country | Read from Cloudflare, which carries the request: two letters, T1 for Tor, XX when unknown. Never a city, a region or a time zone; the miner itself sends no location. |
| address | Never read by the ingestion and never stored, not even in a log: the Worker's logs are off. Cloudflare sees it to carry the request, as any server you connect to does. |
| written | One data point per report in Cloudflare Workers Analytics Engine: the fields above and the country, with the install id as the point's index. Each error code adds a small point of its own. |
| kept | The raw points about 3 months, then they are gone. Each day, the day before is summed into counts of distinct installs per value, without any install id, and these daily counts are kept longer. The count outlives the raw point, never the reverse. |
| read by | FearMiner's maintainers, on an internal dashboard behind an access check: rigs connected now, by country, version, algorithm, system and GPU model; how fast a release is adopted; which features are in use; the most frequent error codes. |
| switched off | The service can stop for weeks: no rig notices, and none sends a burst when it is back. |
08 · the wall
The wall with the cockpit #
The cockpit's relay and this telemetry are two services that never meet: separate code, keys, storage and logs, and access to one gives nothing of the other.
- Nothing of the cockpit is ever sent here: no rig fingerprint, no fleet or rig key, no enrolment code, no relay address. The
cockpitflag says a rig is enrolled, never where. - The install id is drawn at random and derived from nothing: not from the rig's name in the cockpit, not from a key, a hash or a date.
- The two are never joined: no table, query, export or support ticket puts a rig of the cockpit next to an install of the telemetry.
- The relay is never a source of telemetry: what it knows about the rigs connected to it stays in it.
The reason is structural. The cockpit promises that its relay holds nothing it can read. A relay that could tell that one of its rigs is an install seen in some country with six cards and some hashrate would hold exactly what it promised not to hold. So the two stay apart, even when their counts of rigs differ.
09 · large farms
Large farms: the risk, and the switch #
Stated plainly: a hashrate bucket, GPU models and a country, taken together, can point at a large farm, because there are not ten installs of 400 cards of one model in one country. That is why the hashrate is a wide bucket, why the location stops at the country, and why the install id carries nothing else. It narrows the risk; for the largest farms it does not remove it.
A farm that would rather send nothing at all uses --no-telemetry. It turns everything off: no install id is drawn or kept, no start, no beat, no stop, no error count; and the miner loses no feature: mining, the cockpit, the API and the notifications work the same.
$ fearminer -o stratum+ssl://POOL:PORT -u YOUR_WALLET --no-telemetry $ FEARMINER_NO_TELEMETRY=1 fearminer -o stratum+ssl://POOL:PORT -u YOUR_WALLET # fearminer.toml [output] no_telemetry = true
10 · see it, turn it off
See it, reset it, turn it off #
| command | what it does |
|---|---|
fearminer telemetry show | Prints the beat the running miner would send now, and sends nothing; give it the run's options (--config fearminer.toml, for example). It draws the install id if there is none yet, never when the telemetry is off. What only a running miner measures is shown as at a start: the rate bucket "0" (null when there is nothing to mine), the uptime lt1h, no errors, the engine null, the gpu, cpu, oc, msr and hugepages flags off. --json prints the JSON alone; with the telemetry off it prints a sentence saying so (null with --json). |
fearminer telemetry rotate-id | Draws a new install id: from the miner's next start, this machine counts as a new install. The old id is linked to nothing, and its points expire with the raw points. |
--no-telemetry | Turns everything off: no install id is drawn or kept, nothing is sent, and no other option turns any part of it back on. The same as FEARMINER_NO_TELEMETRY=1, or no_telemetry = true under [output] in the configuration file. The miner loses no feature. |
--telemetry-interval | Minutes between two beats, 5 to 1440, 15 by default: under 5 is raised to 5, over a day lowered to a day. Also FEARMINER_TELEMETRY_INTERVAL, or telemetry_interval under [output] in the configuration file. |
egress | The line every start prints. With the telemetry on, its part reads telemetry.fearminer.com (telemetry every 15 min: event, install id, format, version, system, mining, hardware, hashrate bucket, features, uptime bucket, errors, pool host; fearminer telemetry show, fearminer.com/telemetry); with it off, no telemetry (--no-telemetry). |
telemetry-id | The install id (32 random hex digits) and the version of its last run, in the state directory (~/.cache/fearminer by default, FEARMINER_STATE_DIR moves it), readable by your account only; never written with --no-telemetry. |
On by default, because only representative numbers are worth collecting: an opt-in would lose most reports and hide every less common system, backend or error. The price of that choice is this page, the egress line and one switch that turns it all off.
11 · history
Change history #
Every change to what is sent gets a dated line here with its schema number, and the miner's egress line and readme change with it.
- schema 1 The flag tls-insecure is added, still schema 1: that the pools' certificates are not verified, never which pool.
- schema 1 First version of the telemetry and of this page, schema 1.