Telemetry
How the laylight command line collects anonymous usage statistics, exactly what it collects, how the data is kept, and how to turn it off.
The laylight command line collects anonymous usage statistics (telemetry). They tell us which commands and options people use, how large real layouts are, how long compilation takes and which systems to build for. This page describes how they are collected and lists everything that is collected.
In short
- What: the command, the names of the options given, the kinds and sizes of the files, run time, outcome, the
laylightversion and the system. The server adds the country, region and network of the connection. - Never: file names, paths, file contents, option values, cell or layer names, your IP address, or any identifier of you or your machine.
- How: one HTTPS request per command to
telemetry.photonstack.io, sent in the background after the command finishes. - When not: never on the first run (a notice is shown instead), never in CI, never after you opt out with
laylight telemetry disable,LAYLIGHT_TELEMETRY=0orDO_NOT_TRACK=1.
How it is collected
Which runs report
| Command | Reports |
|---|---|
check, drc, lym, ir, build, decompile, blackbox, unbox, netlist, lvs, fmt, parse | one event after the command finishes |
lsp | one event when an editor starts the language server; nothing while it runs |
--version, help, telemetry, unknown commands | nothing |
A run reports nothing when any of these holds:
- You opted out (see Turning it off).
- A CI variable is set:
CI,CONTINUOUS_INTEGRATION,BUILD_NUMBER,RUN_ID,GITHUB_ACTIONS,GITLAB_CI,TF_BUILD,BUILDKITE,CIRCLECI,TRAVIS,JENKINS_URL,TEAMCITY_VERSION,CODEBUILD_BUILD_IDorBITBUCKET_BUILD_NUMBER. CI runs report only if you opted in explicitly, withLAYLIGHT_TELEMETRY=1orlaylight telemetry enable. - The notice has not been shown yet (see below).
The first-run notice
The first time a command would report, laylight prints this notice to stderr instead and sends nothing for that run:
notice: laylight collects anonymous usage statistics to improve the tool: the
notice: command, option names, file kinds and sizes, run time, outcome, version and
notice: OS, and the region and network the request comes from. No file names or
notice: contents, no option values and no IP address are kept. Nothing was sent for
notice: this run. To opt out, run `laylight telemetry disable` or set
notice: LAYLIGHT_TELEMETRY=0.
notice: Details: https://laylight.photonstack.io/telemetry/It records the date of the notice in its settings file and reports from the next run on. An editor's language server (laylight lsp) never shows the notice, since its stderr only goes to the editor's log: it reports only after the notice has appeared in a terminal or through the Python library. If the settings file cannot be written, the notice shows again on every run and nothing is ever sent.
How an event is sent
-
The command runs as usual; telemetry does not change what it does or prints.
-
laylightbuilds the event from the command line and the file system. It takes the option names from a fixed list, the file kinds from the extensions and the file sizes from the file metadata. Files are never opened or read for telemetry. -
It starts
curlin the background, posts the event as JSON on its standard input, and exits without waiting for it:curl --silent --max-time 10 --header "content-type: application/json" \ --data-binary @- https://telemetry.photonstack.io/v1/eventsThe request goes over HTTPS through your proxy settings (
HTTPS_PROXY). Ifcurlis not installed, the network is down or the server does not answer, the event is lost. Nothing is retried, queued or written to disk. -
The server, a Cloudflare Worker, checks every field against a fixed format and rejects events that do not match. It then adds what it derives from the connection (below) and stores the event in a Cloudflare D1 database.
What is collected
Sent by laylight
An event looks like this:
{
"schema": 1, "product": "laylight-cli", "version": "0.3.0", "event": "command",
"command": "build", "options": ["-o", "--dummy"],
"input_kind": "lyl", "input_files": 1, "input_bytes": 18234,
"output_kind": "gds", "output_bytes": 1048576,
"duration_ms": 412, "outcome": "ok",
"os": "linux", "arch": "x86_64", "cpus": 16,
"caller": "python/0.3.0", "interactive": false,
"metrics": { "cells": 42, "tiles": 120000 }
}| Field | Content |
|---|---|
schema, product, event | The event format version, laylight-cli, and command |
version | The version of laylight |
command | The command run, such as build |
options | The names of the options given, from this list only: -o, --output, --top, --dummy, --layers, --netlist, --gds, --whitebox, --allow-revision, --partial, --verify, --check, --deck, --report, --markers, --rules, --lym, --json, --list, --stdio. Never their values: no paths, cell names, layer names or fill rules |
input_kind | The kind of the main input, from its extension: lyl, lyir, gds, oas, json, other or none |
input_files, input_bytes | How many input files, and their total size in bytes |
output_kind, output_bytes | The kind and total size of the files written, for a successful run |
duration_ms | The run time in milliseconds |
outcome | ok, failed (errors were reported in the input) or error (wrong usage, unreadable files) |
os, arch, cpus | Operating system (linux, macos, windows), CPU architecture (x86_64, aarch64) and the number of CPU threads |
caller | What ran laylight: python/<version> for the Python library, vscode for the VS Code extension; absent otherwise |
interactive | Whether stderr was a terminal (a person at a terminal rather than a script) |
metrics | Counts from the run: cells written, dummy fill tiles, design rule violations |
lsp events leave out the files, run time and outcome. Fields not in this table are not sent; the server discards any that are.
Added by the server
Like any web server, the server receives the IP address of the connection. It uses the address for the fields below and then discards it. The address is not stored or logged.
| Field | Content |
|---|---|
ts, day | When the event arrived (seconds) and its UTC date |
country, region, continent | Derived from the address by Cloudflare: the country (ISO 3166 code), its first-level subdivision such as a state or province, and the continent. Not the city, postal code or coordinates |
asn, as_org | The network the connection came from: its autonomous system number and name, such as an internet provider, cloud or university |
visitor | A daily anonymous visitor, used to count users per day (see below) |
The daily visitor is a SHA-256 hash of the address, the product, the OS and the architecture, together with a random salt made for that UTC day. The salt is deleted once the day is over. After that, the hash cannot be turned back into an address or matched with any other day's.
Never collected
- File names, paths, directory names, file contents, and the names of cells, layers or ports.
- Option values, error messages and other output, environment variables, user names and host names.
- Your IP address. It is used only as described above.
- Any identifier of you or your machine.
laylightcreates no install ID. Its settings file only holds your choice and the date of the notice.
To see exactly what your own runs report, print the event instead of sending it:
LAYLIGHT_TELEMETRY_DEBUG=1 laylight build ring.lyl -o ring.gdsHow the data is kept
- Where: a Cloudflare D1 database in the Asia-Pacific region, written by a Cloudflare Worker. Cloudflare processes the requests and stores the data on our behalf.
- How long: events are deleted after 13 months, and each day's salt after that day.
- Who and what for: only the maintainers of Laylight can access the data. They use it only for aggregate statistics about how Laylight is used, such as commands per version, file size ranges, platforms and countries. It is not sold or shared.
- Logs: the Worker keeps no per-request logs, which would hold the address.
Turning it off
Any one of these stops all reporting, including the notice:
laylight telemetry disable # saved in the settings file
export LAYLIGHT_TELEMETRY=0 # this environment only
export DO_NOT_TRACK=1 # the cross-tool convention, https://consoledonottrack.comlaylight telemetry status shows whether telemetry is on and why. laylight telemetry enable turns it back on. An opt-out always wins: with laylight telemetry disable saved, LAYLIGHT_TELEMETRY=1 does not turn it on.
The settings file is telemetry.toml in the configuration directory. LAYLIGHT_CONFIG_DIR points laylight at another directory.
- Linux:
~/.config/laylight/(or$XDG_CONFIG_HOME/laylight/) - macOS:
~/Library/Application Support/laylight/ - Windows:
%APPDATA%\laylight\
The Python library and editors
The Python library compiles layouts by running laylight. Its runs report the same events with caller set to python/<version>, and it passes the one-time notice on to stderr. LAYLIGHT_TELEMETRY=0 in the environment of the Python process turns telemetry off.
The VS Code extension starts laylight lsp with caller set to vscode. Other editors report lsp events without a caller.
Contact
Send questions about telemetry, or requests about your data, to [email protected]. The data cannot be linked to a person, so we cannot find or delete what a particular user sent. Opting out stops all future reporting.