From 6ae619a625183b90345af55cfab284ae22b1137e Mon Sep 17 00:00:00 2001 From: Adam Valenta Date: Mon, 8 Jun 2026 16:46:49 +0200 Subject: [PATCH 1/6] GH-16875: Document telemetry (README + User Guide page) Add a Privacy & Telemetry section to the README and a Telemetry page under the User Guide, noting opt-out anonymous usage telemetry starting in 3.46.0.12: what is sent (coarse bucketed metrics plus version/OS), what is never sent, and the opt-out switches. --- README.md | 26 ++++++++++++++++++++++++-- h2o-docs/src/product/index.rst | 5 +++++ h2o-docs/src/product/telemetry.rst | 28 ++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 h2o-docs/src/product/telemetry.rst diff --git a/README.md b/README.md index 730f1e7469ef..bcc186468c66 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ H2O-3 (this repository) is the third incarnation of H2O, and the successor to [H * [Building H2O on Hadoop](#BuildingHadoop) * [Sparkling Water](#Sparkling) * [Documentation](#Documentation) +* [Privacy & Telemetry](#Privacy) * [Citing H2O](#Citing) * [Community](#Community) / [Advisors](#Advisors) / [Investors](#Investors) @@ -661,8 +662,29 @@ If the build fails, try `gradlew clean`, then `git clean -f`. Documentation for each bleeding edge nightly build is available on the [nightly build page](http://s3.amazonaws.com/h2o-release/h2o/master/latest.html). + +## 9. Privacy & Telemetry + +H2O-3 sends anonymous usage telemetry to help us prioritize features and platforms. Here is what happens: + +- **Default is on.** Opt-out, industry-standard for open-source server software. Setting an environment variable below stops everything instantly. +- **One small ping per `h2o.init()`** plus one per major user action (training, scoring, MOJO download, upload, import, save/load, AutoML). Each ping is ~200 bytes of JSON over HTTPS. +- **Standalone & Hadoop clusters too.** A cluster started directly with `java -jar h2o.jar` or `hadoop jar h2odriver.jar` — even with no Python/R client attached — sends one ping when the cluster forms. Same fields, same opt-outs. +- **What's sent:** version strings, OS, an ephemeral session UUID regenerated on every `h2o.init()`, a Unix timestamp, the algorithm name, and coarse bucket labels for counts (rows, columns, durations, sizes). Numeric values are always ranges, never raw integers. +- **What's never sent:** code, file paths, dataset names, model names, column names, hyperparameter values, hostnames, usernames, email addresses, or any user-generated content. +- **Opt out anytime.** Either set an environment variable: + ```bash + export H2O_DISABLE_TELEMETRY=1 # or + export DO_NOT_TRACK=1 + ``` + Or pass `telemetry=False` (Python) / `telemetry = FALSE` (R) to `h2o.init()`. For a cluster launched directly on the JVM, the same environment variables work, or pass `-Dsys.ai.h2o.telemetry.disabled=true`. +- **Fire-and-forget.** Every call runs on a background task with a 2-second timeout. If the receiver is unreachable, your code returns exactly as if telemetry never happened — never blocks, never raises, never retries. + +The full wire contract and the receiver software are open source in the [`h2o-3-telemetry`](https://github.com/h2oai/h2o-3-telemetry) repository. To run a private receiver, set `H2O_TELEMETRY_URL` to your `/v1/event` endpoint. + + -## 9. Citing H2O +## 10. Citing H2O If you use H2O as part of your workflow in a publication, please cite your H2O resource(s) using the following BibTex entry: @@ -702,7 +724,7 @@ Arora, A., Candel, A., Lanford, J., LeDell, E., and Parmar, V. (Oct. 2016). _Dee Click, C., Lanford, J., Malohlava, M., Parmar, V., and Roark, H. (Oct. 2016). _Gradient Boosted Models with H2O_. . -## 10. Community +## 11. Community H2O has been built by a great many number of contributors over the years both within H2O.ai (the company) and the greater open source community. You can begin to contribute to H2O by answering [Stack Overflow](http://stackoverflow.com/questions/tagged/h2o) questions or [filing bug reports](https://github.com/h2oai/h2o-3/issues). Please join us! diff --git a/h2o-docs/src/product/index.rst b/h2o-docs/src/product/index.rst index db42db053a4a..2f88e14c0211 100644 --- a/h2o-docs/src/product/index.rst +++ b/h2o-docs/src/product/index.rst @@ -154,6 +154,11 @@ The following are additional resources to learn more information about H2O-3: security +.. toctree:: + :maxdepth: 2 + + telemetry + .. toctree:: :maxdepth: 1 diff --git a/h2o-docs/src/product/telemetry.rst b/h2o-docs/src/product/telemetry.rst new file mode 100644 index 000000000000..37f30809993a --- /dev/null +++ b/h2o-docs/src/product/telemetry.rst @@ -0,0 +1,28 @@ +Telemetry +========= + +Starting with version **3.46.0.12**, H2O-3 sends anonymous usage telemetry to help the team prioritize features and platforms. It is **opt-out** and designed to be invisible: every send is fire-and-forget with a short timeout, so if the receiver is unreachable your code behaves exactly as if telemetry never ran — it never blocks, raises, or retries. + +What is sent +------------ + +- One small ping when you start or connect to H2O (``h2o.init()`` / ``h2o.connect()`` in Python or R, or a standalone ``java -jar h2o.jar`` / ``hadoop jar h2odriver.jar`` cluster), plus one per major action: training, scoring, MOJO and model download, upload, import, parse, AutoML, and model save/load. +- Each ping contains the H2O version, the client (``python`` / ``r`` / ``jvm``), the operating system, an ephemeral session ID regenerated on every start, a timestamp, the algorithm name, and **coarse range buckets** for counts such as rows, columns, durations, and sizes. Numeric values are always ranges, never exact figures. + +What is never sent +------------------ + +Code, file paths, dataset or model names, column names, parameter values, hostnames, usernames, email addresses, or any user-generated content. + +Opting out +---------- + +Any one of the following disables telemetry completely: + +- Set an environment variable: ``H2O_DISABLE_TELEMETRY=1`` or ``DO_NOT_TRACK=1``. +- Pass ``telemetry=False`` (Python) or ``telemetry = FALSE`` (R) to ``h2o.init()``. +- For a cluster started directly on the JVM, add ``-Dsys.ai.h2o.telemetry.disabled=true``. + +The wire format and the receiver software are open source in the +`h2o-3-telemetry `__ repository. To send +telemetry to your own receiver instead, set the ``H2O_TELEMETRY_URL`` environment variable. From 48959a5fc2a3606dbdb5276e7f899e307dd01aec Mon Sep 17 00:00:00 2001 From: Adam Valenta Date: Mon, 8 Jun 2026 18:43:36 +0200 Subject: [PATCH 2/6] =?UTF-8?q?GH-16875:=20Correct=20telemetry=20wording?= =?UTF-8?q?=20=E2=80=94=20small-cluster=20node=20counts=20are=20exact,=20n?= =?UTF-8?q?ote=20DNT/Sec-GPC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Drop the inaccurate 'numeric values are always ranges' claim: a small cluster's node count (1-16) is sent exactly; larger clusters are bucketed. - Note that the receiver also honors the W3C DNT: 1 and Sec-GPC: 1 request headers (verified in h2o-3-telemetry app/transport/http.py). --- README.md | 2 +- h2o-docs/src/product/telemetry.rst | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bcc186468c66..79e4d91ef8d8 100644 --- a/README.md +++ b/README.md @@ -670,7 +670,7 @@ H2O-3 sends anonymous usage telemetry to help us prioritize features and platfor - **Default is on.** Opt-out, industry-standard for open-source server software. Setting an environment variable below stops everything instantly. - **One small ping per `h2o.init()`** plus one per major user action (training, scoring, MOJO download, upload, import, save/load, AutoML). Each ping is ~200 bytes of JSON over HTTPS. - **Standalone & Hadoop clusters too.** A cluster started directly with `java -jar h2o.jar` or `hadoop jar h2odriver.jar` — even with no Python/R client attached — sends one ping when the cluster forms. Same fields, same opt-outs. -- **What's sent:** version strings, OS, an ephemeral session UUID regenerated on every `h2o.init()`, a Unix timestamp, the algorithm name, and coarse bucket labels for counts (rows, columns, durations, sizes). Numeric values are always ranges, never raw integers. +- **What's sent:** version strings, OS, an ephemeral session UUID regenerated on every `h2o.init()`, a Unix timestamp, the algorithm name, and coarse bucket labels for counts (rows, columns, durations, sizes) — reported as ranges, not raw integers. One exception: a small cluster's exact node count (1–16) is sent, since 1-node vs 4-node is operationally meaningful; larger clusters are bucketed. - **What's never sent:** code, file paths, dataset names, model names, column names, hyperparameter values, hostnames, usernames, email addresses, or any user-generated content. - **Opt out anytime.** Either set an environment variable: ```bash diff --git a/h2o-docs/src/product/telemetry.rst b/h2o-docs/src/product/telemetry.rst index 37f30809993a..6273b88fef75 100644 --- a/h2o-docs/src/product/telemetry.rst +++ b/h2o-docs/src/product/telemetry.rst @@ -7,7 +7,7 @@ What is sent ------------ - One small ping when you start or connect to H2O (``h2o.init()`` / ``h2o.connect()`` in Python or R, or a standalone ``java -jar h2o.jar`` / ``hadoop jar h2odriver.jar`` cluster), plus one per major action: training, scoring, MOJO and model download, upload, import, parse, AutoML, and model save/load. -- Each ping contains the H2O version, the client (``python`` / ``r`` / ``jvm``), the operating system, an ephemeral session ID regenerated on every start, a timestamp, the algorithm name, and **coarse range buckets** for counts such as rows, columns, durations, and sizes. Numeric values are always ranges, never exact figures. +- Each ping contains the H2O version, the client (``python`` / ``r`` / ``jvm``), the operating system, an ephemeral session ID regenerated on every start, a timestamp, the algorithm name, and **coarse range buckets** for counts such as rows, columns, durations, and sizes. These counts are reported as ranges rather than exact figures. One notable exception: a small cluster's node count (1–16) is sent exactly, since 1-node vs 4-node is operationally meaningful; larger clusters are bucketed. What is never sent ------------------ @@ -23,6 +23,10 @@ Any one of the following disables telemetry completely: - Pass ``telemetry=False`` (Python) or ``telemetry = FALSE`` (R) to ``h2o.init()``. - For a cluster started directly on the JVM, add ``-Dsys.ai.h2o.telemetry.disabled=true``. +The receiver also honors the standard ``DNT: 1`` (Do Not Track) and ``Sec-GPC: 1`` +(Global Privacy Control) request headers: any event arriving with either header set +is dropped and never stored. + The wire format and the receiver software are open source in the `h2o-3-telemetry `__ repository. To send telemetry to your own receiver instead, set the ``H2O_TELEMETRY_URL`` environment variable. From 97817eb9571f1c4e1ad91ada7abdfeee8d58ea71 Mon Sep 17 00:00:00 2001 From: Adam Valenta Date: Mon, 8 Jun 2026 18:48:36 +0200 Subject: [PATCH 3/6] GH-16875: Drop private-receiver / H2O_TELEMETRY_URL claims from telemetry docs The h2o-3-telemetry receiver repo is private, so describing it as open source and telling users to point H2O_TELEMETRY_URL at their own receiver doesn't hold for end users. Remove that paragraph from the README and the User Guide page. --- README.md | 2 -- h2o-docs/src/product/telemetry.rst | 4 ---- 2 files changed, 6 deletions(-) diff --git a/README.md b/README.md index 79e4d91ef8d8..37f7950548e4 100644 --- a/README.md +++ b/README.md @@ -680,8 +680,6 @@ H2O-3 sends anonymous usage telemetry to help us prioritize features and platfor Or pass `telemetry=False` (Python) / `telemetry = FALSE` (R) to `h2o.init()`. For a cluster launched directly on the JVM, the same environment variables work, or pass `-Dsys.ai.h2o.telemetry.disabled=true`. - **Fire-and-forget.** Every call runs on a background task with a 2-second timeout. If the receiver is unreachable, your code returns exactly as if telemetry never happened — never blocks, never raises, never retries. -The full wire contract and the receiver software are open source in the [`h2o-3-telemetry`](https://github.com/h2oai/h2o-3-telemetry) repository. To run a private receiver, set `H2O_TELEMETRY_URL` to your `/v1/event` endpoint. - ## 10. Citing H2O diff --git a/h2o-docs/src/product/telemetry.rst b/h2o-docs/src/product/telemetry.rst index 6273b88fef75..bc18baf0f004 100644 --- a/h2o-docs/src/product/telemetry.rst +++ b/h2o-docs/src/product/telemetry.rst @@ -26,7 +26,3 @@ Any one of the following disables telemetry completely: The receiver also honors the standard ``DNT: 1`` (Do Not Track) and ``Sec-GPC: 1`` (Global Privacy Control) request headers: any event arriving with either header set is dropped and never stored. - -The wire format and the receiver software are open source in the -`h2o-3-telemetry `__ repository. To send -telemetry to your own receiver instead, set the ``H2O_TELEMETRY_URL`` environment variable. From 8a97b017c8d608bc8eeddb21631a5f38afe891b2 Mon Sep 17 00:00:00 2001 From: Adam Valenta Date: Tue, 9 Jun 2026 18:52:58 +0200 Subject: [PATCH 4/6] GH-16875: Document the first-run telemetry disclosure notice --- README.md | 3 ++- h2o-docs/src/product/telemetry.rst | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37f7950548e4..42d47929e43b 100644 --- a/README.md +++ b/README.md @@ -672,12 +672,13 @@ H2O-3 sends anonymous usage telemetry to help us prioritize features and platfor - **Standalone & Hadoop clusters too.** A cluster started directly with `java -jar h2o.jar` or `hadoop jar h2odriver.jar` — even with no Python/R client attached — sends one ping when the cluster forms. Same fields, same opt-outs. - **What's sent:** version strings, OS, an ephemeral session UUID regenerated on every `h2o.init()`, a Unix timestamp, the algorithm name, and coarse bucket labels for counts (rows, columns, durations, sizes) — reported as ranges, not raw integers. One exception: a small cluster's exact node count (1–16) is sent, since 1-node vs 4-node is operationally meaningful; larger clusters are bucketed. - **What's never sent:** code, file paths, dataset names, model names, column names, hyperparameter values, hostnames, usernames, email addresses, or any user-generated content. +- **One-time notice.** The first time telemetry is active in an environment, H2O-3 prints a short notice (what's collected and how to opt out) and never repeats it, so collection is never silent. - **Opt out anytime.** Either set an environment variable: ```bash export H2O_DISABLE_TELEMETRY=1 # or export DO_NOT_TRACK=1 ``` - Or pass `telemetry=False` (Python) / `telemetry = FALSE` (R) to `h2o.init()`. For a cluster launched directly on the JVM, the same environment variables work, or pass `-Dsys.ai.h2o.telemetry.disabled=true`. + Or pass `telemetry=False` (Python) / `telemetry = FALSE` (R) to `h2o.init()` or `h2o.connect()`. For a cluster launched directly on the JVM, the same environment variables work, or pass `-Dsys.ai.h2o.telemetry.disabled=true`. - **Fire-and-forget.** Every call runs on a background task with a 2-second timeout. If the receiver is unreachable, your code returns exactly as if telemetry never happened — never blocks, never raises, never retries. diff --git a/h2o-docs/src/product/telemetry.rst b/h2o-docs/src/product/telemetry.rst index bc18baf0f004..13b563513eda 100644 --- a/h2o-docs/src/product/telemetry.rst +++ b/h2o-docs/src/product/telemetry.rst @@ -14,13 +14,29 @@ What is never sent Code, file paths, dataset or model names, column names, parameter values, hostnames, usernames, email addresses, or any user-generated content. +First-run notice +---------------- + +So that telemetry is never silent, the first time it is active in an environment H2O-3 prints a short one-time notice and then never repeats it. The notice reads approximately: + +.. code-block:: text + + H2O-3 collects anonymous usage telemetry (H2O version, OS, algorithm names, and + coarse usage buckets) to help prioritize features and platforms. It never sends + your code, data, file paths, or any identifiers. + + To opt out: set H2O_DISABLE_TELEMETRY=1 (or DO_NOT_TRACK=1), or pass + telemetry=False to h2o.init() / h2o.connect(). See the Telemetry docs for details. + + This notice is shown only once. + Opting out ---------- Any one of the following disables telemetry completely: - Set an environment variable: ``H2O_DISABLE_TELEMETRY=1`` or ``DO_NOT_TRACK=1``. -- Pass ``telemetry=False`` (Python) or ``telemetry = FALSE`` (R) to ``h2o.init()``. +- Pass ``telemetry=False`` (Python) or ``telemetry = FALSE`` (R) to ``h2o.init()`` or ``h2o.connect()``. - For a cluster started directly on the JVM, add ``-Dsys.ai.h2o.telemetry.disabled=true``. The receiver also honors the standard ``DNT: 1`` (Do Not Track) and ``Sec-GPC: 1`` From a49845536a4c1d9e59e9b030595fc8bee3936d1b Mon Sep 17 00:00:00 2001 From: Adam Valenta Date: Wed, 1 Jul 2026 16:30:44 +0200 Subject: [PATCH 5/6] GH-16875: Document telemetry getter/setter; drop first-run notice section --- README.md | 13 ++++----- h2o-docs/src/product/telemetry.rst | 46 +++++++++++++++++++----------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 42d47929e43b..5f783d874c6b 100644 --- a/README.md +++ b/README.md @@ -672,13 +672,12 @@ H2O-3 sends anonymous usage telemetry to help us prioritize features and platfor - **Standalone & Hadoop clusters too.** A cluster started directly with `java -jar h2o.jar` or `hadoop jar h2odriver.jar` — even with no Python/R client attached — sends one ping when the cluster forms. Same fields, same opt-outs. - **What's sent:** version strings, OS, an ephemeral session UUID regenerated on every `h2o.init()`, a Unix timestamp, the algorithm name, and coarse bucket labels for counts (rows, columns, durations, sizes) — reported as ranges, not raw integers. One exception: a small cluster's exact node count (1–16) is sent, since 1-node vs 4-node is operationally meaningful; larger clusters are bucketed. - **What's never sent:** code, file paths, dataset names, model names, column names, hyperparameter values, hostnames, usernames, email addresses, or any user-generated content. -- **One-time notice.** The first time telemetry is active in an environment, H2O-3 prints a short notice (what's collected and how to opt out) and never repeats it, so collection is never silent. -- **Opt out anytime.** Either set an environment variable: - ```bash - export H2O_DISABLE_TELEMETRY=1 # or - export DO_NOT_TRACK=1 - ``` - Or pass `telemetry=False` (Python) / `telemetry = FALSE` (R) to `h2o.init()` or `h2o.connect()`. For a cluster launched directly on the JVM, the same environment variables work, or pass `-Dsys.ai.h2o.telemetry.disabled=true`. +- **Opt out anytime** — any of the following disables telemetry (any opt-out wins; `DO_NOT_TRACK` always takes precedence): + - **Environment variable:** `export DO_NOT_TRACK=1` (the cross-tool standard). + - **Programmatic, persistent:** call the setter `h2o.set_telemetry(False)` to opt out (or `True` to opt back in) and the getter `h2o.telemetry_enabled()` to read the current state. Both are available in the Python and R clients (`h2o.set_telemetry(FALSE)` in R), apply immediately, and are saved under `~/.h2oai` so later sessions honor the choice. + - **This session only:** pass `telemetry=False` (Python) / `telemetry = FALSE` (R) to `h2o.init()` or `h2o.connect()`. + - **Config file:** add `general.telemetry = false` under `[general]` in `~/.h2oconfig`. + - **JVM cluster:** set `DO_NOT_TRACK=1` in its environment, or pass `-Dsys.ai.h2o.telemetry.disabled=true`. - **Fire-and-forget.** Every call runs on a background task with a 2-second timeout. If the receiver is unreachable, your code returns exactly as if telemetry never happened — never blocks, never raises, never retries. diff --git a/h2o-docs/src/product/telemetry.rst b/h2o-docs/src/product/telemetry.rst index 13b563513eda..b57380f8768b 100644 --- a/h2o-docs/src/product/telemetry.rst +++ b/h2o-docs/src/product/telemetry.rst @@ -14,30 +14,44 @@ What is never sent Code, file paths, dataset or model names, column names, parameter values, hostnames, usernames, email addresses, or any user-generated content. -First-run notice ----------------- +Opting out +---------- -So that telemetry is never silent, the first time it is active in an environment H2O-3 prints a short one-time notice and then never repeats it. The notice reads approximately: +Telemetry is on by default. Any one of the following disables it — if **any** opt-out is in effect, nothing is sent, and ``DO_NOT_TRACK`` always takes precedence over the other settings. -.. code-block:: text +**Per session** (applies to the current process only): - H2O-3 collects anonymous usage telemetry (H2O version, OS, algorithm names, and - coarse usage buckets) to help prioritize features and platforms. It never sends - your code, data, file paths, or any identifiers. +- Pass ``telemetry=False`` (Python) or ``telemetry = FALSE`` (R) to ``h2o.init()`` or ``h2o.connect()``. - To opt out: set H2O_DISABLE_TELEMETRY=1 (or DO_NOT_TRACK=1), or pass - telemetry=False to h2o.init() / h2o.connect(). See the Telemetry docs for details. +**Persistent** (remembered across sessions): - This notice is shown only once. +- **Environment variable** — set ``DO_NOT_TRACK=1`` (the cross-tool standard from `consoledonottrack.com `__). It always wins, and is honored by the Python client, the R client, and the JVM server. +- **Programmatic switch** — use the setter ``h2o.set_telemetry()`` to change telemetry and the getter ``h2o.telemetry_enabled()`` to read the current state. Both are available in the Python and R clients; the setting applies immediately and is saved under ``~/.h2oai/telemetry`` so later sessions honor it. -Opting out ----------- + Python: -Any one of the following disables telemetry completely: + .. code-block:: python -- Set an environment variable: ``H2O_DISABLE_TELEMETRY=1`` or ``DO_NOT_TRACK=1``. -- Pass ``telemetry=False`` (Python) or ``telemetry = FALSE`` (R) to ``h2o.init()`` or ``h2o.connect()``. -- For a cluster started directly on the JVM, add ``-Dsys.ai.h2o.telemetry.disabled=true``. + h2o.set_telemetry(False) # opt out (persisted across sessions) + h2o.set_telemetry(True) # opt back in + h2o.telemetry_enabled() # -> True or False + + R: + + .. code-block:: r + + h2o.set_telemetry(FALSE) # opt out (persisted across sessions) + h2o.set_telemetry(TRUE) # opt back in + h2o.telemetry_enabled() # -> TRUE or FALSE + +- **Config file** — add a ``general.telemetry`` key to ``~/.h2oconfig`` in your home directory: + + .. code-block:: ini + + [general] + telemetry = false + +For a cluster started directly on the JVM (``java -jar h2o.jar`` / ``hadoop jar h2odriver.jar``), add ``-Dsys.ai.h2o.telemetry.disabled=true`` or set ``DO_NOT_TRACK=1`` in its environment. The receiver also honors the standard ``DNT: 1`` (Do Not Track) and ``Sec-GPC: 1`` (Global Privacy Control) request headers: any event arriving with either header set From dd7c5bc233335248fc9be8b360d83b0e7426c9d0 Mon Sep 17 00:00:00 2001 From: Adam Valenta Date: Wed, 15 Jul 2026 15:46:17 +0200 Subject: [PATCH 6/6] GH-16875: Document telemetry as opt-in (default off) --- README.md | 18 +++++++-------- h2o-docs/src/product/telemetry.rst | 37 +++++++++++++++++++----------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 5f783d874c6b..d01715b55679 100644 --- a/README.md +++ b/README.md @@ -665,19 +665,19 @@ Documentation for each bleeding edge nightly build is available on the [nightly ## 9. Privacy & Telemetry -H2O-3 sends anonymous usage telemetry to help us prioritize features and platforms. Here is what happens: +H2O-3 can send anonymous usage telemetry to help us prioritize features and platforms. It is **opt-in and off by default** — nothing is sent unless you turn it on. Here is what happens when enabled: -- **Default is on.** Opt-out, industry-standard for open-source server software. Setting an environment variable below stops everything instantly. +- **Default is off (opt-in).** Nothing is sent until you explicitly turn telemetry on; the choice is remembered across sessions. - **One small ping per `h2o.init()`** plus one per major user action (training, scoring, MOJO download, upload, import, save/load, AutoML). Each ping is ~200 bytes of JSON over HTTPS. -- **Standalone & Hadoop clusters too.** A cluster started directly with `java -jar h2o.jar` or `hadoop jar h2odriver.jar` — even with no Python/R client attached — sends one ping when the cluster forms. Same fields, same opt-outs. +- **Standalone & Hadoop clusters too.** A cluster started directly with `java -jar h2o.jar` or `hadoop jar h2odriver.jar` can send one ping when the cluster forms — if the server administrator enables it. Same fields. - **What's sent:** version strings, OS, an ephemeral session UUID regenerated on every `h2o.init()`, a Unix timestamp, the algorithm name, and coarse bucket labels for counts (rows, columns, durations, sizes) — reported as ranges, not raw integers. One exception: a small cluster's exact node count (1–16) is sent, since 1-node vs 4-node is operationally meaningful; larger clusters are bucketed. - **What's never sent:** code, file paths, dataset names, model names, column names, hyperparameter values, hostnames, usernames, email addresses, or any user-generated content. -- **Opt out anytime** — any of the following disables telemetry (any opt-out wins; `DO_NOT_TRACK` always takes precedence): - - **Environment variable:** `export DO_NOT_TRACK=1` (the cross-tool standard). - - **Programmatic, persistent:** call the setter `h2o.set_telemetry(False)` to opt out (or `True` to opt back in) and the getter `h2o.telemetry_enabled()` to read the current state. Both are available in the Python and R clients (`h2o.set_telemetry(FALSE)` in R), apply immediately, and are saved under `~/.h2oai` so later sessions honor the choice. - - **This session only:** pass `telemetry=False` (Python) / `telemetry = FALSE` (R) to `h2o.init()` or `h2o.connect()`. - - **Config file:** add `general.telemetry = false` under `[general]` in `~/.h2oconfig`. - - **JVM cluster:** set `DO_NOT_TRACK=1` in its environment, or pass `-Dsys.ai.h2o.telemetry.disabled=true`. +- **Turn it on** — any of the following enables telemetry: + - **Programmatic, persistent:** call `h2o.set_telemetry(True)` (`h2o.set_telemetry(TRUE)` in R), and read the state with `h2o.telemetry_enabled()`. Applies immediately and is saved under `~/.h2oai` so later sessions honor it. + - **This session only:** pass `telemetry=True` (Python) / `telemetry = TRUE` (R) to `h2o.init()` or `h2o.connect()`. + - **Config file:** add `general.telemetry = true` under `[general]` in `~/.h2oconfig`. + - **JVM cluster:** the admin sets `H2O_ENABLE_TELEMETRY=1` in its environment, or passes `-Dsys.ai.h2o.telemetry.enabled=true`. +- **Keep it off / turn it back off** — `DO_NOT_TRACK=1` is a hard opt-out that always wins (honored by Python, R, and the JVM server); or use `h2o.set_telemetry(False)`, `telemetry=False`, `general.telemetry = false`, or (JVM) `-Dsys.ai.h2o.telemetry.disabled=true`. - **Fire-and-forget.** Every call runs on a background task with a 2-second timeout. If the receiver is unreachable, your code returns exactly as if telemetry never happened — never blocks, never raises, never retries. diff --git a/h2o-docs/src/product/telemetry.rst b/h2o-docs/src/product/telemetry.rst index b57380f8768b..76537ed36d35 100644 --- a/h2o-docs/src/product/telemetry.rst +++ b/h2o-docs/src/product/telemetry.rst @@ -1,10 +1,10 @@ Telemetry ========= -Starting with version **3.46.0.12**, H2O-3 sends anonymous usage telemetry to help the team prioritize features and platforms. It is **opt-out** and designed to be invisible: every send is fire-and-forget with a short timeout, so if the receiver is unreachable your code behaves exactly as if telemetry never ran — it never blocks, raises, or retries. +Starting with version **3.46.0.12**, H2O-3 can send anonymous usage telemetry to help the team prioritize features and platforms. It is **opt-in and off by default** — nothing is sent unless you turn it on. It is also designed to be invisible when enabled: every send is fire-and-forget with a short timeout, so if the receiver is unreachable your code behaves exactly as if telemetry never ran — it never blocks, raises, or retries. -What is sent ------------- +What is sent (when enabled) +--------------------------- - One small ping when you start or connect to H2O (``h2o.init()`` / ``h2o.connect()`` in Python or R, or a standalone ``java -jar h2o.jar`` / ``hadoop jar h2odriver.jar`` cluster), plus one per major action: training, scoring, MOJO and model download, upload, import, parse, AutoML, and model save/load. - Each ping contains the H2O version, the client (``python`` / ``r`` / ``jvm``), the operating system, an ephemeral session ID regenerated on every start, a timestamp, the algorithm name, and **coarse range buckets** for counts such as rows, columns, durations, and sizes. These counts are reported as ranges rather than exact figures. One notable exception: a small cluster's node count (1–16) is sent exactly, since 1-node vs 4-node is operationally meaningful; larger clusters are bucketed. @@ -14,34 +14,33 @@ What is never sent Code, file paths, dataset or model names, column names, parameter values, hostnames, usernames, email addresses, or any user-generated content. -Opting out ----------- +Enabling telemetry +------------------ -Telemetry is on by default. Any one of the following disables it — if **any** opt-out is in effect, nothing is sent, and ``DO_NOT_TRACK`` always takes precedence over the other settings. +Telemetry is **off by default**. Any one of the following turns it on: **Per session** (applies to the current process only): -- Pass ``telemetry=False`` (Python) or ``telemetry = FALSE`` (R) to ``h2o.init()`` or ``h2o.connect()``. +- Pass ``telemetry=True`` (Python) or ``telemetry = TRUE`` (R) to ``h2o.init()`` or ``h2o.connect()``. **Persistent** (remembered across sessions): -- **Environment variable** — set ``DO_NOT_TRACK=1`` (the cross-tool standard from `consoledonottrack.com `__). It always wins, and is honored by the Python client, the R client, and the JVM server. - **Programmatic switch** — use the setter ``h2o.set_telemetry()`` to change telemetry and the getter ``h2o.telemetry_enabled()`` to read the current state. Both are available in the Python and R clients; the setting applies immediately and is saved under ``~/.h2oai/telemetry`` so later sessions honor it. Python: .. code-block:: python - h2o.set_telemetry(False) # opt out (persisted across sessions) - h2o.set_telemetry(True) # opt back in + h2o.set_telemetry(True) # opt in (persisted across sessions) + h2o.set_telemetry(False) # opt back out h2o.telemetry_enabled() # -> True or False R: .. code-block:: r - h2o.set_telemetry(FALSE) # opt out (persisted across sessions) - h2o.set_telemetry(TRUE) # opt back in + h2o.set_telemetry(TRUE) # opt in (persisted across sessions) + h2o.set_telemetry(FALSE) # opt back out h2o.telemetry_enabled() # -> TRUE or FALSE - **Config file** — add a ``general.telemetry`` key to ``~/.h2oconfig`` in your home directory: @@ -49,9 +48,19 @@ Telemetry is on by default. Any one of the following disables it — if **any** .. code-block:: ini [general] - telemetry = false + telemetry = true + +For a cluster started directly on the JVM (``java -jar h2o.jar`` / ``hadoop jar h2odriver.jar``), the server administrator enables it with ``-Dsys.ai.h2o.telemetry.enabled=true`` or by setting ``H2O_ENABLE_TELEMETRY=1`` in its environment. + +Turning it off again +-------------------- + +Since telemetry is off by default you normally don't need to do anything. To turn it off after enabling it — or to guarantee it stays off regardless of any of the settings above — use any of: -For a cluster started directly on the JVM (``java -jar h2o.jar`` / ``hadoop jar h2odriver.jar``), add ``-Dsys.ai.h2o.telemetry.disabled=true`` or set ``DO_NOT_TRACK=1`` in its environment. +- Pass ``telemetry=False`` (Python) / ``telemetry = FALSE`` (R) to ``h2o.init()`` / ``h2o.connect()`` for the current session, or ``h2o.set_telemetry(False)`` to persist it. +- Set ``general.telemetry = false`` in ``~/.h2oconfig``. +- Set ``DO_NOT_TRACK=1`` (the cross-tool standard from `consoledonottrack.com `__). This is a **hard opt-out**: it always wins over every enable setting above, and is honored by the Python client, the R client, and the JVM server. +- For a JVM-launched cluster, ``-Dsys.ai.h2o.telemetry.disabled=true`` (also a hard opt-out). The receiver also honors the standard ``DNT: 1`` (Do Not Track) and ``Sec-GPC: 1`` (Global Privacy Control) request headers: any event arriving with either header set