Skip to content
sigiro
Esc
navigateopen⌘Jpreview
On this page

About the tables, and which machine they describe

The sigiro_* tables hold telemetry from whatever sent OTLP. The sys_* functions read the machine sigiro runs on. Confuse them and you get the wrong machine.

sigiro gives you two kinds of table, and they look alike in a query. One kind holds the telemetry that your services sent. The other kind reads the machine that sigiro itself runs on. Both answer a question about CPU, memory or disk, and neither one tells you which machine it means.

This page draws the line. It is the most valuable thing in this section, because the failure mode is not an error message. The failure mode is a number that looks correct and describes a machine you did not ask about.

Two families, two subjects

Family What it is Whose machine Time
sigiro_spans, sigiro_logs, sigiro_log_templates, sigiro_metrics_gauge, sigiro_metrics_sum, sigiro_metrics_histogram, sigiro_metrics_exp_histogram, sigiro_profiles, sigiro_anomalies Stored telemetry Whatever sent OTLP — your services, on your hosts, wherever they run Historical, with a timestamp column
sys_cpu_info(), sys_memory_info(), sys_disk_info(), sys_network_info(), sys_os_info() Live table functions The one machine this sigiro process runs on One measurement at this instant, with no history and no time column

The sigiro_* names are tables. The sys_* names are functions, and you call them with empty parentheses. That is the only visible difference, and it is not enough of a difference.

The trap, in one example

Suppose an agent asks: is the disk full on the checkout service?

-- WRONG for that question
SELECT * FROM sys_disk_info();

That query succeeds. It returns real mount points with real free bytes. Every number in it describes the machine that sigiro runs on. If checkout runs in another container, on another host, or in another region, the answer has nothing to do with checkout. On the hosted service the answer describes a machine that we operate, and you do not run anything on it.

The agent has no way to notice. There is no error, no null column and no message in the response. So the agent reports a disk figure with confidence, and the figure is about the wrong machine.

The question about checkout is answered from the metric your service sent:

-- RIGHT for that question
SELECT service_name, metric_name, value, timestamp
FROM sigiro_metrics_gauge
WHERE service_name = 'checkout'
  AND metric_name LIKE 'system.filesystem%'
  AND timestamp > now() - INTERVAL '1 hour'
ORDER BY timestamp DESC;

This reads what checkout’s own OpenTelemetry host metrics reported, from checkout’s own machine, over a window you chose. It is historical, so you can see a trend rather than one instant. If the row set is empty, that is a real and useful answer too: nothing sends host metrics for that service, and the fix is instrumentation rather than a different query.

Why sys_* exists at all

The sys_* functions are not a mistake. They answer one question well: what does this node look like right now? An operator with a self-hosted fleet asks that about each node, and the answer needs no telemetry pipeline, because the node reads its own kernel.

They also make a deliberate exception to sigiro’s SQL rules. Every other function that reads outside the database is blocked, because a caller could point it at a path: read_csv('/etc/passwd') is exactly the hole that the blocklist closes. The sys_* functions take no arguments, so there is no path for a caller to choose, and that is the property that let them through. sigiro rejects any sys_* call that carries arguments.

State the consequence plainly. On a self-hosted node the perimeter is the network, so sys_* is readable by anyone who can reach the query surface. On the hosted service, sys_* describes our machine and never yours. In both cases the rule is the same: sys_* is about the process that answers you.

The metric tables are four, and the reason is the write path

Metrics arrive in four tables rather than one:

  • sigiro_metrics_gauge — a value at a point in time
  • sigiro_metrics_sum — a counter, monotonic or not
  • sigiro_metrics_histogram — explicit bucket boundaries
  • sigiro_metrics_exp_histogram — exponential buckets

A single sigiro_metrics table was proposed and rejected. OTLP already carries these four shapes with different fields, so one table would mean a schema projection on every insert: null columns for the shape that does not apply, and a mapper that decides which. Four tables let each OTLP shape insert without a copy and without a projection. You pay for that with a UNION ALL when you want all metrics at once, which is what /v1/diagnose does internally.

sigiro_anomalies is the odd one in the family. It holds no telemetry. It holds the regime shifts that a scheduled pass has already detected, and GET /v1/anomalies serves the same rows as typed JSON. About evidence instead of a dashboard explains how those rows are produced.

There is no schema endpoint yet, and that is the gap

Everything above is knowledge you now hold and an agent does not.

sigiro publishes no schema description. There is no /v1/schema, and the tables carry no column comments, so an agent that reaches POST /v1/query makes a guess, or reads llms-full.txt on this site. Both work often enough to be dangerous: a guess of sys_disk_info() for a disk question is a good guess, and it produces a wrong answer.

We treat this as the most valuable gap in the API rather than a convenience gap, for exactly that reason. The distinction that has to become machine-readable is not “local or remote”. It is this: sys_* is a live measurement of the machine sigiro runs on, and sigiro_metrics_* is historical telemetry from whatever sent OTLP.

Until that endpoint exists, this page is the machine-readable version. It is served as Markdown at /docs/explanation/tables.md, and it is in llms.txt.

A rule you can apply every time

Ask which machine the question is about.

  • About a service you instrumented — use sigiro_*, and bound timestamp.
  • About the sigiro process itself — use sys_*, and expect one instant.
  • Not sure — use sigiro_*. An empty result is honest. A sys_* result is confident and possibly irrelevant.

Was this page helpful?