vexlo. It ingests records from relay daemons, owns storage,
and serves the /v1 API and the UI from one address. This page builds it, starts it, and
explains every flag vexlo serve and vexlo check take. Tokens are on
Authentication and tokens; the daemon that feeds the server is on
The relay daemon.
Flags are spelled with a single dash throughout, as the binary’s own -h output prints them.
The binary accepts the double-dash spelling too.
Requirements
The server repository is not yet public, so the build starts from a checkout rather than a download. It needs:- Go 1.27
- Node.js 22.12 or later, for the UI that the binary embeds
- A C toolchain. The SQLite driver is cgo, and the Makefile exports
CGO_ENABLED=1for every target that needs it.
Build
make build has to run before a bare go build ./... works: the server embeds the built UI with
//go:embed, so web/dist must exist before the Go build that embeds it can compile.
Running the binary with no arguments lists its commands and exits 1:
vexlo. From a checkout that is bin/vexlo, unless bin/ is
on your PATH.
The six commands
Each leaf command prints its own flags:
vexlo serve -h, vexlo check -h,
vexlo relay run -h, vexlo relay status -h, vexlo token create -h (and list,
revoke), vexlo policy set -h (and show). Each exits 1 after printing, and its last line
reads vexlo: flag: help requested. vexlo token -h, vexlo policy -h,
vexlo relay -h, and vexlo -h print no flags: each reads -h as a command name it does
not recognize, prints the names it does accept, and exits 1.
Run the server
127.0.0.1:8080, applies its database migrations on startup (a
fresh, empty database file needs no separate migration step), and stores everything under
~/.vexlo/data: the SQLite file vexlo.db and the value store directory values/. That
directory is the server storage directory. vexlo serve resolves it from -db-path and
-value-store-dir, each falling back to its own environment variable, then to
VEXLO_DATA_DIR, then to ~/.vexlo/data. It never reads the -data-dir flag vexlo token
takes, so a token minted under an explicit -data-dir is found on the first start only when
the server names the same directory.
The first log line records the eight settings it names and no others: the bind address,
whether TLS is required, -no-auth and -header-trust, the two storage paths, and the two
retention settings. -team, -tls-cert, -tls-key, and -allow-insecure-http never appear in it.
The request log lines that follow are omitted here. The run below bound a non-default port
and named a scratch server storage directory with -db-path and -value-store-dir:
Authorization header is never logged. Ctrl-C (SIGINT) or SIGTERM stops the server: new
requests are refused and in-flight ones get 30 seconds to finish. On a clean drain the last
line is msg="serve: shutting down" and the exit code is 0. A request still running after
those 30 seconds is abandoned, and the process exits 1 with an error on its last line
instead.
Loopback or TLS
The server refuses to bind a non-loopback address without a TLS certificate. Loopback means a host of127.0.0.1, ::1, or localhost, matched as a string once it is lowercased and a
trailing dot is dropped, never resolved through DNS. vexlo check applies the same rule as
vexlo serve and reports it without opening a port:
- Terminate TLS in the binary
- Terminate TLS in a reverse proxy
- Accept plaintext
Pass A plain
-tls-cert and -tls-key (or VEXLO_TLS_CERT_FILE and VEXLO_TLS_KEY_FILE). Both
files are loaded at startup, so a missing or malformed pair fails vexlo check and
vexlo serve alike rather than a first request. A supplied certificate is always used, even
on a loopback bind. The certificate below is self-signed, on a loopback address:http:// request to that port is answered
400 Bad Request with the body Client sent an HTTP request to an HTTPS server.Check the configuration
vexlo check resolves the identical configuration vexlo serve would run with, validates it,
reports free disk on the value store’s filesystem, and prints the retention arithmetic. It never
opens the database or the value store. Run it with the same flags and environment you will start
the server with.
On the default retention settings it exits 1. A 20 GiB value budget at the default expected
write rate of 2 traces per second holds about 104 hours of values, and the default shape
retention is 168 hours, so every trace would lose its values before it ages out of search. The
run below names a scratch server storage directory; the defaults are
~/.vexlo/data/vexlo.db and ~/.vexlo/data/values:
-allow-overcommit is the lever to pick. The check then
exits 0 and prints the same arithmetic with one extra line:
vexlo serve has no -allow-overcommit flag and applies no overcommit check of its own: it
starts on the configuration vexlo check rejects. The check is where the arithmetic is read.
-expected-write-rate changes the figure the arithmetic is computed at. vexlo check has no
live traffic to measure it from, so a production estimate has to be passed in.
Flag reference
Both commands share one flag set;check adds two of its own. The serve -h output as printed:
-db-path and -value-store-dir render their placeholder as vexlo token; both take a path.
The phrase is the help text’s reference to vexlo token’s own storage, picked up as the
value name.vexlo check -h prints the same flags plus -allow-overcommit and -expected-write-rate:
vexlo check -h
vexlo check -h
-shape-retention-days, -value-budget-bytes,
-allow-overcommit, and -expected-write-rate. The rest resolve flag first, then environment
variable, then default; -db-path and -value-store-dir take one step more,
VEXLO_DATA_DIR, before that default. The three boolean environment variables
(VEXLO_ALLOW_INSECURE_HTTP, VEXLO_NO_AUTH, VEXLO_HEADER_TRUST) count as set for any
value other than empty, 0, or false, case-insensitive.
-no-auth, -team, -header-trust, and -header-trust-secret are explained on
Authentication and tokens.
Retention
Shape (traces, steps, attempts, tags) is kept by day count,-shape-retention-days, default 7.
Values are kept against the byte budget, -value-budget-bytes, default 20 GiB: when the budget
is full the oldest values go first, and the trace keeps its shape. The function index (observed
callers and callees per function) is kept for 90 days and has no flag. vexlo check’s
“effective value retention” line is how long values last at the expected write rate, which is
the number to compare against the shape retention.