Skip to main content

Platform configuration

This section details the configuration files used by the fluxrig platform.

Configuration precedence & environment variables​

To support modern containerized deployments (Docker/Kubernetes), fluxrig merges configuration from multiple sources, evaluated in the following order of precedence (highest to lowest):

  1. CLI Flags (--level debug)
  2. Environment Variables (FLUXRIG_LEVEL=debug)
  3. Config File (fluxrig.toml)
  4. Static Defaults

The environment variable mapping replaces dots (.) with underscores (_) and uppercases the key. For example, base.name becomes FLUXRIG_BASE_NAME.

Top-level overrides for troubleshooting:

  • FLUXRIG_TRACE=true: Forces all logging to TRACE level (high volume).
  • FLUXRIG_DEBUG=true: Forces all logging to DEBUG level.
  • FLUXRIG_DISABLE_TELEMETRY=true: Master switch to stop all self-monitoring reporting.

Validation at startup​

Both binaries validate their configuration when they load it, and refuse to start on either of these:

  • A duration that does not parse. Every setting whose value is a duration (its name ends in _timeout, _interval, _wait, _delay, _age, _duration or _ttl) is parsed at load time. A typo such as operation_timeout = "5 seconds" fails the start and names the field. Before this check, a bad duration could reach a consumer that ignored the parse error and treated zero as real, which fires the timer immediately.
  • A key that maps to no setting. A misspelled section or field, such as [observabilitty], fails the start and names the key. Before this check, the key was ignored and the process ran with a default the operator meant to override.

Some keys are read by the loader itself rather than by a struct field, and are accepted: the Rack's rack.bus.* and legacy bus.* aliases, store.state_file and store.scenario_file, and the Mixer's mixer.mixer_name.

Secret management​

fluxrig does not store secrets in plaintext TOML. For sensitive values (e.g., database passwords, API keys):

  1. Use Environment Variables at runtime (FLUXRIG_STORE_DATABASE_PASSWORD).
  2. Use the State Envelope (Passport): secrets are carried in the signed envelope rather than in plaintext TOML. The envelope is cryptographically signed (Ed25519); at-rest encryption is not yet implemented (see the security reference).

Rack configuration (fluxrig)​

The static binary fluxrig loads its configuration from fluxrig.toml by default.

File: fluxrig.toml​

Configuration is namespaced to separate global/shared settings from component-specific ones.

[Logging] (Rack)​

Shared logging content.

FieldTypeDefaultDescription
levelstring"info"Verbosity: debug, info, warn, error.
filenamestring"logs/fluxrig.log"Path to log file.
max_size_mbint100Max size in MB before rotation.
max_backupsint7Max number of old log files to keep.
compressbooltrueCompress rotated log files (gzip).
traceboolfalseHard-override to enable trace level.
debugboolfalseHard-override to enable debug level.

Throttling settings

FieldTypeDefaultDescription
throttling.enabledbooltrueToggle log throttling protection.
throttling.ratefloat500.0Max lines per second per gear.
throttling.burstint50Temporary log burst capacity.

[Base] (Common)​

Foundational identity and path settings.

FieldTypeDefaultDescription
namestring"node-01"Unique Name. Claims this specific identity.
state_dirstring"./data"Root directory for state and WAL.
state_filestring"rack.flux"Signed State Bundle (CBOR). Persists Identity, Config, and Secrets.
scenario_filestring"scenario.flux"The Rack's own copy of the last scenario it applied, in state_dir (CBOR, mode 0600). The Rack resumes it at start without waiting for the Mixer to send it again. Empty keeps no copy. Also settable as store.scenario_file.

[Rack]​

Rack-specific settings.

FieldTypeDefaultDescription
name_prefixstring"node-"Ephemeral Prefix. Used if base.name is empty.
ipstring""Manual IP Override. If empty, the Rack autodetects its local primary IP via netutil.
max_hopsint64Max Routing Hops. Prevents infinite loops.
max_payload_sizeint2097152Max Payload Size (Bytes). Default: 2MB.
enrollment_timeoutstring"15s"Timeout for enrollment handshake.
heartbeat_intervalstring"30s"Frequency of Registry heartbeats.
enrollment_intervalstring"2s"Wait between enrollment attempts while a Rack is not yet adopted.
handshake_intervalstring"500ms"Re-emission of the connectivity probes sent before gears are activated.
convergence_timeoutstring"5s"How long a Rack waits for every wire to confirm reachable before giving up on the convergence phase.
drain_timeoutstring"35s"How long in-flight messages are given to finish on shutdown before gears are stopped.
lane_queue_sizeint1024Messages each hot lane wire holds in memory between the gear that emits and the gear that consumes.
lane_send_timeoutstring"5s"How long a gear that emits waits for room in a full hot lane queue before it gets an error.
outbox_max_messagesint10000Bus-bound emissions parked in memory while the bus is down, forwarded when it returns. When full the oldest is dropped and counted; the gear is never blocked.
outbox_drain_retriesint3More attempts the drain makes on a parked emission the bus refuses before it moves on. The emission stays parked for the next drain. Only an emission the bus can never accept is dropped.
outbox_orderstring"subject"Drain order. subject never forwards an emission ahead of an older one on the same subject. none forwards whatever the bus takes, in the order the bus takes it.
outbox_backpressure_timeoutstring"1s"With subject order, how long a live emission waits for older parked messages on its subject to drain while the bus is up. Then it goes to the bus, or parks behind them if the wait ends first. The wait slows the gear to the drain's pace, so the outbox does not fill and drop messages. With the bus down, nothing waits. "0s" turns the wait off.
cleanup_timeoutstring"2s"Grace given to release resources after draining.
bootstrap_secretstring"fluxrig"Shared secret this Rack presents on its very first Hello, before it has a Passport of its own. Must match the Mixer's enrollment.bootstrap_secret. Once enrolled, the Rack presents its own per-Rack secret instead; this only matters for that first contact.

[Store]​

Data storage settings.

FieldTypeDefaultDescription
dirstring"./data"Root directory for data storage.

[Snake] (NATS/JetStream)​

Configuration for the underlying transport bus.

FieldTypeDefaultDescription
urlstring"nats://localhost:4222"NATS Server URL.
domainstring"flux"JetStream Domain. Must match Mixer cluster name.
stream_namestring"flux-msg"Primary JetStream stream name.
connect_timeoutstring"10s"Initial connection timeout.
reconnect_waitstring"1s"Wait time between reconnect attempts.
convergence_delaystring"100ms"Safety delay for consumer convergence.
operation_timeoutstring"5s"Deadline for a single bus operation.
subscription_retry_waitstring"200ms"Wait between attempts to establish a subscription.
subscription_retry_attemptsint5Attempts before a subscription is reported failed.
initial_retry_waitstring"500ms"Wait before the first reconnect attempt, with exponential backoff on repeats.
initial_retry_attemptsint10Attempts before an initial connection is reported failed.
offline_start_timeoutstring"3s"Longest a Rack holding a passport waits for the bus at start before it runs offline. A Rack without a passport keeps the full initial_retry_* schedule. 0s removes the bound.
offline_retry_intervalstring"5s"How often a Rack that started offline probes the bus. When it answers, the Rack restarts its session and goes online. 0s turns the probe off, and the Rack stays offline until restarted.
store_encryptionbooltrueMixer only. Encrypts the message store of the bus on disk: every message, stream and key-value bucket. See data at rest.
store_cipherstring"chacha"Mixer only. chacha (ChaCha20-Poly1305) or aes (AES-GCM).
store_key_filestring""Mixer only. File holding the store key, at least 32 characters. Empty derives the key from the cluster key.
store_old_key_filestring""Mixer only. The key the store had before store_key_file, for the start that rotates it.
stream_max_agestring"24h"Mixer only. Oldest message a bus stream keeps. Empty keeps them without an age limit.
stream_max_bytesint1073741824Mixer only. Largest size of a bus stream, in bytes. 0 means no limit.
inactive_thresholdstring"30s"Silence after which a consumer is treated as inactive.
root_ca_filestring""CA bundle verifying the Mixer's bus certificate. Also settable as rack.bus.root_ca_file.
insecure_skip_verifyboolfalseSkip verification of the bus certificate. Development only. Also settable as rack.bus.insecure_skip_verify.
allow_non_tlsboolfalseMixer only. Lets a plaintext client connect alongside a TLS one once tls_cert_file/tls_key_file are set. Off by default, so configuring TLS actually requires it instead of just offering it.
tls_ca_filestring""Mixer only. CA a Rack's own client certificate is verified against, for mTLS.
tls_verifyboolfalseMixer only. Requires a Rack to present a client certificate, verified against tls_ca_file.
kv_max_bytesint1073741824Mixer only. Largest size of a key-value bucket the Mixer provisions, in bytes. Caps it the same way stream_max_bytes caps a stream.
kv_max_value_sizeint1048576Mixer only. Largest single value a key-value bucket accepts, in bytes.
kv_ttlstring"0s"Mixer only. Expiry for a key-value bucket entry. 0s means no expiry.

Telemetry settings

FieldTypeDefaultDescription
telemetry.service_namestring"flux.rack"Service name reported on every span, metric and log.
telemetry.base_subjectstring"flux.telemetry"Bus subject prefix telemetry batches are published on.
telemetry.batch_intervalstring"5s"How often a batch is flushed to the Mixer. On the Mixer it is also how often telemetry is flushed to persistent storage.
telemetry.max_batch_sizeint512Records per batch before it is flushed early.
telemetry.stream_namestring"flux-telemetry"Name of the JetStream stream that holds the telemetry batches.
telemetry.disabledboolfalseTurns telemetry off. Also settable with FLUXRIG_DISABLE_TELEMETRY.
telemetry.metrics.host_enabledboolfalseCollect host metrics (CPU, memory, disk, network).
telemetry.metrics.runtime_enabledboolfalseCollect Go runtime metrics.
telemetry.metrics.bento_enabledboolfalseCollect the metrics of the Bento gear.

Example​

[base]
name = "rack-nyc-01"
state_dir = "/var/lib/fluxrig/data"

[logging]
level = "debug"

[snake]
url = "nats://nats.fluxrig.internal:4222"

Note on Log Files:

  • Rack writes to <log_dir>/fluxrig-rack.log.
  • CLI writes to <log_dir>/fluxrig-cli.log (if enabled).

Mixer configuration (fluxrig-mixer)​

The dynamic binary fluxrig-mixer loads its configuration from fluxrig-mixer.toml.

File: fluxrig-mixer.toml​

Configuration is namespaced into granular sections.

[Logging] (Mixer)​

Shared logging content.

FieldTypeDefaultDescription
levelstring"info"Verbosity: debug, info, warn, error.
filenamestring"logs/mixer.log"Path to log file.
max_backupsint7Max number of old log files to keep.

[Mixer]​

General Mixer settings.

FieldTypeDefaultDescription
max_hopsint64Global Max Hops.
max_payload_sizeint2097152Global Max Payload (Bytes).
startup_scenariostring""Scenario reference to load on startup.
scenario_wait_timeoutstring"15s"Time to wait for Racks to converge when activating a scenario.

Registry-First Identity Model​

NOTE

Changed: the static machine_id configuration field is gone from both Rack and Mixer configurations, and is no longer read. fluxrig now enforces a Registry-First Enrollment Model.

  • Racks: Dynamically receive a 128-bit uuid.UUID Identity during the Enrollment Handshake, which is cryptographically signed and stored in the local rack.flux passport.
  • Mixers: Automatically generate a persistent cluster identity (UUID v7) on their first boot, which is recorded in the registry bucket (see [Registry]).

[Enrollment] (Mixer)​

Control how new Racks are admitted to the rig.

FieldTypeDefaultDescription
auto_adoptboolfalseIf true, any new Rack connecting will be immediately set to active. Use cautiously in production.
push_delaystring"1s"Delay before pushing the initial scenario to a newly adopted Rack.
bootstrap_secretstring"fluxrig"Shared secret for zero-config enrollment and identity adoption. It ships with a known value, so a deployment that does not set it is running the documented one.

[Registry] (Mixer)​

Where the Mixer keeps Rack records, the name index, scenario files and the active-scenario pointer, and how long a Rack counts as online. Both buckets live in the embedded NATS server's store (snake.store_dir). See Identity & registry.

FieldTypeDefaultDescription
bucketstring"fluxrig_registry"Key-value bucket for records, names, scenario files and the active pointer.
liveness_bucketstring"fluxrig_liveness"Key-value bucket for presence. Must differ from bucket.
replicasint1Replica count of both buckets. At least 1.
max_value_sizeint1048576Largest record in bytes, headers included. It bounds a scenario file: a larger one is refused on import.
liveness_ttlstring"90s"How long after its last heartbeat a Rack still counts as online. Three heartbeat intervals by default.
write_retriesint3How many times a registry write that met a concurrent one is read again and retried before it fails. 0 fails on the first conflict.
sweep_intervalstring"10m"How often the Mixer repairs what a crash between two registry writes left behind. It also sweeps once at startup.
orphan_min_agestring"5m"How old a registry record must be before the sweep treats it as left behind rather than in progress.

[Ingest] (Mixer)​

Telemetry ingestion buffering and flushing. Neither field is read today: the Mixer flushes telemetry to persistent storage every telemetry.batch_interval (default 5s).

FieldTypeDefaultDescription
flush_intervalstringn/a[Roadmap] Not read today. See telemetry.batch_interval.
buffer_sizeintn/a[Roadmap] Not read today.

[API]​

Mixer REST API settings.

FieldTypeDefaultDescription
portint8090Server Port for the HTTP/gRPC API listener.
read_header_timeoutstring"3s"Deadline for reading request headers, which bounds a slow-header client.
control_confirm_timeoutstring"2s"How long a simulator control command (/api/v1/control/sim/{action}) waits for a gear to acknowledge it before the request answers that nobody is listening.
tls_cert_filestring""Server certificate. The API serves HTTPS when this and tls_key_file are both set.
tls_key_filestring""Server private key.
auth_tokenstring""Bearer token required as Authorization: Bearer <token> on every route but /api/v1/health. The Mixer refuses to start with this unset unless auth_disabled_dangerously is set.
auth_disabled_dangerouslyboolfalseStarts the Mixer with no API authentication. The explicit, named opt-out for a deployment with no auth_token configured; logs a warning on every start.

[Wasm] (Mixer)​

Where signed Wasm gears and the keys that verify them are kept.

FieldTypeDefaultDescription
catalog_dirstring"./data/wasm"Directory holding imported Wasm modules.
trusted_keys_dirstring"./data/wasm/keys"Public keys a module's signature is checked against.

[Store] (Mixer)​

Local data storage: telemetry, and the topology rows derived from the active scenario. The registry itself is in [Registry].

FieldTypeDefaultDescription
database_filestring"flux.duckdb"DB filename (relative to store dir).
cluster_key_filestring"cluster.key"Key filename (relative to store dir).

[Snake]​

Embedded NATS Server (JetStream) settings.

FieldTypeDefaultDescription
portint4222Server Port to listen on for NATS connections.
urlstring"nats://localhost:4222"URL to advertise to Racks.
domainstring"flux"JetStream Domain Name.
cluster_namestring"flux"JetStream domain the embedded server reports, and what a client uses to reach a domain-scoped server.
store_dirstring"./data/snake"Where the embedded server keeps its JetStream store. Empty keeps the default, a snake directory under store.dir.
stream_namestring"flux-msg"Name of the primary JetStream stream.
stream_subjects[]string["flux.msg.>", "flux.gear.>", "fluxrig.>"]Wildcard subjects to capture.
business_stream_max_agestringn/a[Roadmap] Not read today. The age limit of the message stream is stream_max_age, below.
telemetry_stream_max_agestringn/a[Roadmap] Not read today.
durablebooln/a[Roadmap] Not read today. The bus stores its data on disk.
dlq_enabledbooltrueRoute a message no consumer could process to the dead letter stream instead of dropping it. Off keeps the old behavior: log and discard.
dlq_subjectstring"flux.dlq"Subject prefix the dead letter stream captures. A failed message is republished as <prefix>.<origin-subject>.
dlq_max_agestring"720h"How long a dead letter is kept. Empty keeps the stream default (24h).

NOTE

The Mixer starts this server itself on every boot. There is no setting that points it at an existing NATS deployment, so these fields move the bus, they do not replace it.

Dead letter queue​

A message no consumer can process is not lost. The Mixer provisions a flux-dlq stream beside the message and telemetry streams, and the bus republishes the unprocessable message there. It is the answer to the three paths that used to drop a message with only a log line:

  • The payload does not decode.
  • The payload decodes but fails validation.
  • The handler fails on every redelivery, up to the redelivery bound.

The stored message keeps the original bytes unchanged, so a replay is byte-identical. The failure context is in headers:

HeaderMeaning
Flux-DLQ-Origin-SubjectThe subject the message was being consumed from.
Flux-DLQ-Reasondecode, validate, or redelivery-exhausted.
Flux-DLQ-DeliveriesThe delivery count when it was routed.
Flux-DLQ-AtWhen it was routed, in RFC 3339.

To replay one, read flux.dlq.> (with the nats tool or a small subscriber), fix the cause, and republish the original bytes to Flux-DLQ-Origin-Subject. Set snake.dlq_enabled = false to keep nothing.

The dead letter stream's subject must not fall under the message stream's subjects (flux.msg.>, flux.agent.>, flux.rack.>, flux.ctrl.>), or the stream cannot be created. The default flux.dlq does not overlap.

Example (Mixer)​

[base]
name = "mixer-prod-01"

[logging]
level = "info"

[mixer]
startup_scenario = "scenario_prod.yaml"

[api]
port = 8090

[store]
dir = "./data"

[snake]
port = 4222
url = "nats://localhost:4222"
domain = "flux"

[Roadmap] Observability tiers​

The platform is designed to support multiple observability tiers for various scales. In the current release, only the Embedded Tier is fully implemented.

TierBackend(s)Use CaseStatus
embeddedDuckDB + ParquetZero deps, development, edgeStable
standardArc + OpenSearchTeam deployments[Roadmap]
enterpriseClickHouse + SigNozPetabyte scale[Roadmap]

[Observability]​

Global observability settings.

FieldTypeDefaultDescription
enabledbooltrueEnable/disable observability collection.
tierstring"embedded"Backend tier. embedded is the only one built. otlp is [Roadmap].
sampling_ratefloatn/a[Roadmap] Not read today: every trace is kept.

Embedded tier configuration​

[Observability.embedded]​

Settings for the Embedded tier (DuckDB + Parquet).

FieldTypeDefaultDescription
data_dirstringn/a[Roadmap] Not read today. Telemetry is stored under the directory of [Store].
flush_intervalstringn/a[Roadmap] Not read today. See telemetry.batch_interval.
retention_daysint30Delete Parquet files older than N days. Read by the retention sweep. When it is positive it wins over rotation.max_age_days.

The retention sweep runs once when the Mixer starts and then at rotation.check_interval. It deletes .parquet files only, by the timestamp in the file name, falling back to the file's modification time. It does not delete rows from the DuckDB telemetry_* tables, so those tables keep their rows and must be managed separately.

[Observability.embedded.storage] [Roadmap]​

Storage format and organization. None of these settings is read today: telemetry is written as Parquet.

FieldTypeDefaultDescription
formatstring"parquet"Storage format: parquet, json.
partition_bystring"hour"Time partitioning: hour, day.
compressionstring"zstd"Compression: zstd, snappy, none.

[Observability.embedded.rotation]​

Retention settings for local Parquet files. check_interval and max_age_days are read today. policy and max_size_gb are [Roadmap].

FieldTypeDefaultDescription
policystring"time"[Roadmap] Rotation policy: time, size, both. Retention is age-based today.
max_age_daysint30Delete data older than N days. Used only when retention_days is not positive.
max_size_gbint10[Roadmap] Not read today. A size cap is not implemented.
check_intervalstring"1h"How often the retention sweep runs. The sweep also runs once at Mixer startup.

[Store] (embedded)​

  • dir: Root directory for data storage (e.g., ./data).
  • wal_max_size_mb: Max size for Write-Ahead Log.
  • database_file: Filename for DuckDB file.

The flux_id (serialized as flux_id in JSON and database schemas) is the unique 128-bit identifier used to trace a specific business signal across its entire lifecycle, from edge ingestion to cloud archival.

Embedded storage schema​

Data is organized into telemetry (system signals) and messages (business data):

./data/
├── telemetry/ # OTel signals (system observability)
│ ├── traces/
│ │ └── 2025/12/21/14/traces_001.parquet
│ ├── logs/
│ │ └── 2025/12/21/14/logs_001.parquet
│ └── metrics/
│ └── 2025/12/21/14/metrics_001.parquet
└── messages/ # Business data (fluxMsg)
├── generic/ # Default schema (raw_msg only)
│ └── 2025/12/21/14/fluxmsg_001.parquet
└── fluxSpec/ # Spec-driven schemas
└── visa-v1/ # Spec-specific subfolder
└── 2025/12/21/14/visa_001.parquet

Parquet Schema (Traces):

ColumnTypeDescription
tsTIMESTAMPEvent timestamp
trace_idVARCHARW3C TraceContext ID
span_idVARCHARSpan ID
parent_span_idVARCHARParent Span ID
flux_idUUIDUUID v7 business ID
entity_idUUIDUnified EntityID (128-bit UUID v7)
entity_nameTEXTHuman-readable Hostname (e.g., rack-sfo-01)
span_nameVARCHAROperation name
duration_msFLOATDuration in milliseconds
statusENUMok, error
attributesJSONAdditional attributes

Parquet Schema (Logs):

ColumnTypeDescription
tsTIMESTAMPLog timestamp
entity_idUUIDUnified EntityID
entity_nameTEXTHuman-readable Hostname
flux_idUUIDBusiness flow ID
levelENUMdebug, info, warn, error
messageVARCHARLog message
attributesJSONStructured fields

Parquet Schema (Metrics):

ColumnTypeDescription
tsTIMESTAMPMetric timestamp
nameVARCHARMetric name (e.g., gear_latency_ms)
entity_idUUIDUnified EntityID
entity_nameTEXTHuman-readable Hostname
typeENUMcounter, gauge, histogram
valueDOUBLEMetric value
labelsJSONDimension labels

Parquet Schema (fluxMsg / Data):

ColumnTypeDescription
tsTIMESTAMPMessage timestamp
trace_idVARCHARAssociated trace
flux_idUUIDPrimary business ID
entity_idUUIDNode EntityID
entity_nameTEXTHostname
src_gear_idVARCHARSource Gear
dst_gear_idVARCHARDestination Gear
msg_typeVARCHARMessage type identifier
directionENUMinbound, outbound, internal
statusENUMok, error
raw_msgBLOBFull CBOR payload
promotedJSONPromoted fields (spec-driven)

Embedded example​

[observability]
enabled = true
tier = "embedded"

# Where telemetry is stored is set by [store], and how often it is flushed by
# telemetry.batch_interval.

[Roadmap] OTLP tier configuration (vendor-neutral)​

[Roadmap] The OTLP tier is not built: fluxrig does not export to an external collector today, and none of the settings on this page under [Observability.otlp] is read. The design is an export to any OpenTelemetry-compatible backend.

[Observability.otlp]​

OpenTelemetry Protocol exporter settings.

FieldTypeDefaultDescription
endpointstring""OTLP gRPC endpoint (e.g., 127.0.0.1:4317).
endpoint_httpstring""OTLP HTTP endpoint (alternative to gRPC).
headersmap{}Custom headers (e.g., API keys).
insecureboolfalseSkip TLS verification.
timeoutstring"30s"Request timeout.

OTLP example [Roadmap]​

None of this is read today.

[observability]
enabled = true
tier = "otlp"

[observability.otlp]
endpoint = "otel-collector:4317"
insecure = false
headers = { "api-key" = "${OTEL_API_KEY}" }

# Optional: also store raw fluxMsg locally
[observability.otlp.messages]
enabled = true
data_dir = "./data/messages"

CLI query commands​

The fluxrig CLI provides commands for querying telemetry data.

fluxrig logs​

Query log entries.

# Filter by severity
fluxrig logs --min-level error --since 1h

# Filter by entity
fluxrig logs --entity rack-nyc-01 --limit 100
FlagTypeDescription
--min-levelstringMinimum log level: debug, info, warn, error.
--sincedurationTime window (e.g., 1h, 24h) or ISO timestamp.
--untilstringEnd time (ISO timestamp).
--entitystringFilter by Entity Name.
--limitintMax results (default: 50).
--api-urlstringMixer API URL (default: http://localhost:8090).

fluxrig metrics​

Query metrics data.

# Filter by metric name
fluxrig metrics --name flux.rack.heartbeats_sent

# Filter by entity
fluxrig metrics --entity mixer-01
FlagTypeDescription
--namestringFilter by metric name.
--entitystringFilter by Entity Name.
--sincedurationStart time.
--untilstringEnd time.
--limitintMax results (default: 50).
--api-urlstringMixer API URL (default: http://localhost:8090).

REST API endpoints​

The Mixer exposes telemetry query endpoints via a REST API.

NOTE

Every route here requires authentication. Send Authorization: Bearer <api.auth_token>. The Mixer refuses to start with no token configured, unless api.auth_disabled_dangerously is set explicitly (not recommended). The one exception is /api/v1/health, which stays open with no token.

Logs API​

GET /api/v1/telemetry/logs

Query Parameters:

ParameterTypeDescription
levelstringFilter by level.
sinceRFC3339Start time.
untilRFC3339End time.
rack_idstringFilter by Rack.
gear_idstringFilter by Gear.
qstringText search.
limitintMax results.
offsetintPagination offset.

Example:

curl -H "Authorization: Bearer $API_TOKEN" \
"http://mixer:8090/api/v1/telemetry/logs?level=error&since=2025-12-21T00:00:00Z&limit=50"

Traces API [Roadmap]​

Spans are collected and written to DuckDB and Parquet, and are queryable there today. The Mixer does not serve them over the API: GET /api/v1/telemetry/{type} answers logs and metrics and nothing else. Until it does, read them from the store, which the telemetry reference shows how to do.

Metrics API​

GET /api/v1/telemetry/metrics

Query Parameters:

ParameterTypeDescription
sinceRFC3339Start time.
untilRFC3339End time.
group_bystringAggregation key.
intervalstringTime bucket: 1m, 5m, 1h.