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 laylight version 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=0 or DO_NOT_TRACK=1.

How it is collected

Which runs report

CommandReports
check, drc, lym, ir, build, decompile, blackbox, unbox, netlist, lvs, fmt, parseone event after the command finishes
lspone event when an editor starts the language server; nothing while it runs
--version, help, telemetry, unknown commandsnothing

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_ID or BITBUCKET_BUILD_NUMBER. CI runs report only if you opted in explicitly, with LAYLIGHT_TELEMETRY=1 or laylight 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

  1. The command runs as usual; telemetry does not change what it does or prints.

  2. laylight builds 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.

  3. It starts curl in 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/events

    The request goes over HTTPS through your proxy settings (HTTPS_PROXY). If curl is not installed, the network is down or the server does not answer, the event is lost. Nothing is retried, queued or written to disk.

  4. 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 }
}
FieldContent
schema, product, eventThe event format version, laylight-cli, and command
versionThe version of laylight
commandThe command run, such as build
optionsThe 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_kindThe kind of the main input, from its extension: lyl, lyir, gds, oas, json, other or none
input_files, input_bytesHow many input files, and their total size in bytes
output_kind, output_bytesThe kind and total size of the files written, for a successful run
duration_msThe run time in milliseconds
outcomeok, failed (errors were reported in the input) or error (wrong usage, unreadable files)
os, arch, cpusOperating system (linux, macos, windows), CPU architecture (x86_64, aarch64) and the number of CPU threads
callerWhat ran laylight: python/<version> for the Python library, vscode for the VS Code extension; absent otherwise
interactiveWhether stderr was a terminal (a person at a terminal rather than a script)
metricsCounts 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.

FieldContent
ts, dayWhen the event arrived (seconds) and its UTC date
country, region, continentDerived 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_orgThe network the connection came from: its autonomous system number and name, such as an internet provider, cloud or university
visitorA 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. laylight creates 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.gds

How 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.com

laylight 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.

On this page