Schema Reference¶
Reference for all views, data types, and field definitions available in Micromegas SQL queries.
Views Overview¶
Micromegas organizes telemetry data into several views that can be queried using SQL:
| View | Description | Use Cases |
|---|---|---|
processes |
Process metadata and system information | System overview, process tracking |
streams |
Data stream information within processes | Stream debugging, data flow analysis |
blocks |
Core telemetry block metadata | Low-level data inspection |
log_entries |
Application log messages with levels | Error tracking, debugging, monitoring |
log_stats |
Aggregated log statistics by process, level, and target | Log volume analysis, monitoring trends |
measures |
Numeric metrics and performance data | Performance monitoring, alerting |
thread_spans |
Synchronous execution spans and timing | Performance profiling, call tracing |
async_events |
Asynchronous event lifecycle tracking | Async operation monitoring |
net_spans |
Network bandwidth spans (Connection / Object / Property / RPC) | Replication bandwidth attribution, bit-axis flame charts |
otel_spans |
OpenTelemetry spans materialized from OTLP-ingested traces | Distributed tracing, OTel SDK interop |
images |
Screenshots and image data captured via send_image() |
Visual telemetry, screenshot history |
list_view_sets() returns this same inventory plus any DDL-defined materialized
view an admin has created — their schemas are
deployment-specific, since an admin controls what such a view projects, unlike the built-in views
documented below.
Core Views¶
processes¶
Contains metadata about processes that have sent telemetry data.
| Field | Type | Description |
|---|---|---|
process_id |
Utf8 |
Unique identifier for the process |
exe |
Utf8 |
Executable name |
username |
Utf8 |
User who ran the process |
realname |
Utf8 |
Real name of the user |
computer |
Utf8 |
Computer/hostname |
distro |
Utf8 |
Operating system distribution |
cpu_brand |
Utf8 |
CPU brand information |
tsc_frequency |
Int64 |
Time stamp counter frequency |
start_time |
Timestamp(Nanosecond) |
Process start time |
start_ticks |
Int64 |
Process start time in ticks |
insert_time |
Timestamp(Nanosecond) |
When the process data was first inserted |
parent_process_id |
Utf8 |
Parent process identifier |
properties |
Dictionary(Int32, Binary) |
Additional process metadata (JSONB format) |
last_update_time |
Timestamp(Nanosecond) |
When the process data was last updated |
last_block_end_ticks |
Int64 |
Tick count when the last block ended |
last_block_end_time |
Timestamp(Nanosecond) |
Timestamp when the last block ended |
audience |
Dictionary(Int32, Utf8) |
This process's own write audience; written server-side, never client-settable, never NULL |
Example Queries:
-- Get all processes from the last day
SELECT process_id, exe, computer, start_time
FROM processes
WHERE start_time >= NOW() - INTERVAL '1 day'
ORDER BY start_time DESC;
-- Find processes by executable name
SELECT process_id, exe, username, computer
FROM processes
WHERE exe LIKE '%analytics%';
streams¶
Contains information about data streams within processes.
| Field | Type | Description |
|---|---|---|
stream_id |
Utf8 |
Unique identifier for the stream |
process_id |
Utf8 |
Reference to the parent process |
dependencies_metadata |
Binary |
Stream dependency metadata |
objects_metadata |
Binary |
Stream object metadata |
tags |
List<Utf8> |
Stream tags |
properties |
Dictionary(Int32, Binary) |
Stream properties (JSONB format) |
insert_time |
Timestamp(Nanosecond) |
When the stream data was first inserted |
format |
Utf8 |
Stream payload format (e.g. for OTLP support) |
last_update_time |
Timestamp(Nanosecond) |
When the stream data was last updated |
audience |
Dictionary(Int32, Utf8) |
This stream's own write audience; see processes.audience; never NULL |
Example Queries:
-- Get streams for a specific process
SELECT stream_id, tags, properties
FROM streams
WHERE process_id = 'my_process_123';
-- Join streams with process information
SELECT s.stream_id, s.tags, p.exe, p.computer
FROM streams s
JOIN processes p ON s.process_id = p.process_id;
blocks¶
Core table containing telemetry block metadata with joined process and stream information.
| Field | Type | Description |
|---|---|---|
block_id |
Utf8 |
Unique identifier for the block |
stream_id |
Utf8 |
Stream identifier |
process_id |
Utf8 |
Process identifier |
begin_time |
Timestamp(Nanosecond) |
Block start time |
begin_ticks |
Int64 |
Block start time in ticks |
end_time |
Timestamp(Nanosecond) |
Block end time |
end_ticks |
Int64 |
Block end time in ticks |
nb_objects |
Int32 |
Number of objects in block |
object_offset |
Int64 |
Offset to objects in storage |
payload_size |
Int64 |
Size of block payload |
insert_time |
Timestamp(Nanosecond) |
When block was inserted |
Joined Stream Fields:
| Field | Type | Description |
|---|---|---|
streams.dependencies_metadata |
Binary |
Stream dependency metadata |
streams.objects_metadata |
Binary |
Stream object metadata |
streams.tags |
List<Utf8> |
Stream tags |
streams.properties |
Dictionary(Int32, Binary) |
Stream properties (JSONB format) |
streams.insert_time |
Timestamp(Nanosecond) |
When stream was inserted |
streams.format |
Utf8 |
Stream payload format (e.g. for OTLP support) |
Joined Process Fields:
| Field | Type | Description |
|---|---|---|
processes.start_time |
Timestamp(Nanosecond) |
Process start time |
processes.start_ticks |
Int64 |
Process start ticks |
processes.tsc_frequency |
Int64 |
Time stamp counter frequency |
processes.exe |
Utf8 |
Executable name |
processes.username |
Utf8 |
User who ran the process |
processes.realname |
Utf8 |
Real name of the user |
processes.computer |
Utf8 |
Computer/hostname |
processes.distro |
Utf8 |
Operating system distribution |
processes.cpu_brand |
Utf8 |
CPU brand information |
processes.insert_time |
Timestamp(Nanosecond) |
When process was inserted |
processes.parent_process_id |
Utf8 |
Parent process identifier |
processes.properties |
Dictionary(Int32, Binary) |
Process properties (JSONB format) |
audience |
Dictionary(Int32, Utf8) |
This block's own write audience (not derived from process_id/stream_id); never NULL |
Example Queries:
-- Analyze block sizes and object counts
SELECT
process_id,
AVG(payload_size) as avg_block_size,
AVG(nb_objects) as avg_objects_per_block,
COUNT(*) as total_blocks
FROM blocks
WHERE insert_time >= NOW() - INTERVAL '1 hour'
GROUP BY process_id;
Observability Data Views¶
log_entries¶
Text-based log entries with levels and structured data.
| Field | Type | Description |
|---|---|---|
process_id |
Dictionary(Int32, Utf8) |
Process identifier |
stream_id |
Dictionary(Int32, Utf8) |
Stream identifier |
block_id |
Dictionary(Int32, Utf8) |
Block identifier |
insert_time |
Timestamp(Nanosecond) |
Block insertion time |
exe |
Dictionary(Int32, Utf8) |
Executable name |
username |
Dictionary(Int32, Utf8) |
User who ran the process |
computer |
Dictionary(Int32, Utf8) |
Computer/hostname |
time |
Timestamp(Nanosecond) |
Log entry timestamp |
target |
Dictionary(Int32, Utf8) |
Module/target |
level |
Int32 |
Log level (see Log Levels) |
msg |
Utf8 |
Log message |
properties |
Dictionary(Int32, Binary) |
Log-specific properties (JSONB format) |
process_properties |
Dictionary(Int32, Binary) |
Process-specific properties (JSONB format) |
audience |
Dictionary(Int32, Utf8) |
The audience of the block this log entry came from; never NULL |
Log Levels¶
Micromegas uses numeric log levels for efficient filtering:
| Level | Name | Description |
|---|---|---|
| 1 | Fatal | Critical errors that cause application termination |
| 2 | Error | Errors that don't stop execution but need attention |
| 3 | Warn | Warning conditions that might cause problems |
| 4 | Info | Informational messages about normal operation |
| 5 | Debug | Detailed information for debugging |
| 6 | Trace | Very detailed tracing information |
Example Queries:
-- Get recent error and warning logs
SELECT time, process_id, level, target, msg
FROM log_entries
WHERE level <= 3 -- Fatal, Error, Warn
AND time >= NOW() - INTERVAL '1 hour'
ORDER BY time DESC;
-- Count logs by level for a specific process
SELECT level, COUNT(*) as count
FROM view_instance('log_entries', 'my_process_123')
WHERE time >= NOW() - INTERVAL '1 day'
GROUP BY level
ORDER BY level;
log_stats¶
Materialized view of aggregated log statistics by process, minute, level, and target — for analyzing log volume trends and patterns over time.
log_stats is a seeded DDL-defined materialized view rather
than a built-in view baked into the server binary — an admin may extend or replace it. The
schema below is its shipped default, not a guarantee: list_view_sets() reflects a deployment's
actual current schema for it, the same as for any other view set (built-in or DDL-defined).
| Field | Type | Description |
|---|---|---|
time_bin |
Timestamp(Nanosecond) |
1-minute time bucket for aggregation |
process_id |
Dictionary(Int32, Utf8) |
Process identifier |
level |
Int32 |
Log level (see Log Levels) |
target |
Dictionary(Int32, Utf8) |
Module/target that generated the logs |
count |
Int64 |
Number of log entries in this aggregation |
audience |
Dictionary(Int32, Utf8) |
The audience of the blocks aggregated into this row (grouped separately per audience); never NULL |
Pre-aggregated by 1-minute intervals and daily-partitioned; updated automatically as new log data arrives.
Example Queries:
-- Analyze log volume trends over the last hour
SELECT
time_bin,
SUM(count) as total_logs,
SUM(CASE WHEN level <= 2 THEN count ELSE 0 END) as error_count
FROM log_stats
WHERE time_bin >= NOW() - INTERVAL '1 hour'
GROUP BY time_bin
ORDER BY time_bin;
-- Find noisiest modules by log volume
SELECT
target,
SUM(count) as total_logs,
COUNT(DISTINCT time_bin) as active_minutes
FROM log_stats
WHERE time_bin >= NOW() - INTERVAL '1 day'
GROUP BY target
ORDER BY total_logs DESC
LIMIT 20;
-- Monitor error rate by process
SELECT
process_id,
time_bin,
SUM(CASE WHEN level <= 2 THEN count ELSE 0 END) * 100.0 / SUM(count) as error_percentage
FROM log_stats
WHERE time_bin >= NOW() - INTERVAL '6 hours'
GROUP BY process_id, time_bin
HAVING SUM(count) > 100 -- Filter out low-volume periods
ORDER BY time_bin, error_percentage DESC;
-- Compare log levels distribution
SELECT
level,
SUM(count) as total_count,
SUM(count) * 100.0 / (SELECT SUM(count) FROM log_stats WHERE time_bin >= NOW() - INTERVAL '1 day') as percentage
FROM log_stats
WHERE time_bin >= NOW() - INTERVAL '1 day'
GROUP BY level
ORDER BY level;
measures¶
Numerical measurements and counters.
| Field | Type | Description |
|---|---|---|
process_id |
Dictionary(Int32, Utf8) |
Process identifier |
stream_id |
Dictionary(Int32, Utf8) |
Stream identifier |
block_id |
Dictionary(Int32, Utf8) |
Block identifier |
insert_time |
Timestamp(Nanosecond) |
Block insertion time |
exe |
Dictionary(Int32, Utf8) |
Executable name |
username |
Dictionary(Int32, Utf8) |
User who ran the process |
computer |
Dictionary(Int32, Utf8) |
Computer/hostname |
time |
Timestamp(Nanosecond) |
Measurement timestamp |
target |
Dictionary(Int32, Utf8) |
Module/target |
name |
Dictionary(Int32, Utf8) |
Metric name |
unit |
Dictionary(Int32, Utf8) |
Measurement unit. May be an ISO 4217 currency code (e.g. USD, CAD, EUR); the web app renders these as currency. CloudWatch/OTLP UCUM unit codes (e.g. By, MBy/s) and dimensionless units (e.g. 1, {Count}) are also normalized and rendered adaptively |
value |
Float64 |
Metric value |
properties |
Dictionary(Int32, Binary) |
Metric-specific properties (JSONB format) |
process_properties |
Dictionary(Int32, Binary) |
Process-specific properties (JSONB format) |
audience |
Dictionary(Int32, Utf8) |
The audience of the block this measure came from; never NULL |
Example Queries:
-- Get CPU metrics over time
SELECT time, value, unit
FROM measures
WHERE name = 'cpu_usage'
AND time >= NOW() - INTERVAL '1 hour'
ORDER BY time;
-- Aggregate memory usage by process
SELECT
process_id,
AVG(value) as avg_memory,
MAX(value) as peak_memory,
unit
FROM measures
WHERE name LIKE '%memory%'
AND time >= NOW() - INTERVAL '1 hour'
GROUP BY process_id, unit;
thread_spans¶
Derived view for analyzing span durations and hierarchies. Access via view_instance('thread_spans', stream_id).
A thread_spans view instance scan is ordered by begin, so an ORDER BY begin on it is free (no
extra sort).
| Field | Type | Description |
|---|---|---|
id |
Int64 |
Span identifier |
parent |
Int64 |
Parent span identifier |
depth |
UInt32 |
Nesting depth in call tree |
hash |
UInt32 |
Span hash for deduplication |
begin |
Timestamp(Nanosecond) |
Span start time |
end |
Timestamp(Nanosecond) |
Span end time |
duration |
Int64 |
Span duration in nanoseconds |
name |
Dictionary(Int32, Utf8) |
Span name (function) |
target |
Dictionary(Int32, Utf8) |
Module/target |
filename |
Dictionary(Int32, Utf8) |
Source file |
line |
UInt32 |
Line number |
Example Queries:
-- Get slowest functions in a stream
SELECT name, AVG(duration) as avg_duration_ns, COUNT(*) as call_count
FROM view_instance('thread_spans', 'stream_123')
WHERE duration > 1000000 -- > 1ms
GROUP BY name
ORDER BY avg_duration_ns DESC
LIMIT 10;
-- Analyze call hierarchy
SELECT depth, name, duration
FROM view_instance('thread_spans', 'stream_123')
WHERE parent = 42 -- specific parent span
ORDER BY begin;
Process-level access: Use process_spans(process_id, types) to query thread spans, async spans, or both across all CPU streams of a process with stream_id and thread_name columns prepended.
async_events¶
Asynchronous span events for tracking async operations with call hierarchy depth information.
| Field | Type | Description |
|---|---|---|
stream_id |
Dictionary(Int32, Utf8) |
Thread stream identifier |
block_id |
Dictionary(Int32, Utf8) |
Block identifier |
time |
Timestamp(Nanosecond) |
Event timestamp |
event_type |
Dictionary(Int32, Utf8) |
"begin" or "end" |
span_id |
Int64 |
Async span identifier |
parent_span_id |
Int64 |
Parent span identifier |
depth |
UInt32 |
Nesting depth in async call hierarchy |
hash |
UInt32 |
Hash of the span's scope descriptor |
name |
Dictionary(Int32, Utf8) |
Span name (function) |
filename |
Dictionary(Int32, Utf8) |
Source file |
target |
Dictionary(Int32, Utf8) |
Module/target |
line |
UInt32 |
Line number |
Example Queries:
-- Find top-level async operations (depth = 0) with performance metrics
SELECT
name,
depth,
AVG(duration_ms) as avg_duration,
COUNT(*) as operation_count
FROM (
SELECT
begin_events.name,
begin_events.depth,
CAST((end_events.time - begin_events.time) AS BIGINT) / 1000000 as duration_ms
FROM
(SELECT * FROM view_instance('async_events', 'my_process_123') WHERE event_type = 'begin') begin_events
LEFT JOIN
(SELECT * FROM view_instance('async_events', 'my_process_123') WHERE event_type = 'end') end_events
ON begin_events.span_id = end_events.span_id
WHERE end_events.span_id IS NOT NULL AND begin_events.depth = 0
)
GROUP BY name, depth
ORDER BY avg_duration DESC;
-- Compare performance by call depth
SELECT
depth,
COUNT(*) as span_count,
AVG(duration_ms) as avg_duration,
MIN(duration_ms) as min_duration,
MAX(duration_ms) as max_duration
FROM (
SELECT
begin_events.depth,
CAST((end_events.time - begin_events.time) AS BIGINT) / 1000000 as duration_ms
FROM
(SELECT * FROM view_instance('async_events', 'my_process_123') WHERE event_type = 'begin') begin_events
LEFT JOIN
(SELECT * FROM view_instance('async_events', 'my_process_123') WHERE event_type = 'end') end_events
ON begin_events.span_id = end_events.span_id
WHERE end_events.span_id IS NOT NULL
)
GROUP BY depth
ORDER BY depth;
-- Find operations that spawn many nested async calls
SELECT
name,
depth,
COUNT(*) as nested_count
FROM view_instance('async_events', 'my_process_123')
WHERE depth > 0 AND event_type = 'begin'
GROUP BY name, depth
HAVING COUNT(*) > 5 -- Functions that create multiple nested async operations
ORDER BY nested_count DESC, depth DESC;
-- Analyze async call hierarchy and parent-child relationships
SELECT
parent.name as parent_operation,
parent.depth as parent_depth,
child.name as child_operation,
child.depth as child_depth,
COUNT(*) as relationship_count
FROM view_instance('async_events', 'my_process_123') parent
JOIN view_instance('async_events', 'my_process_123') child
ON parent.span_id = child.parent_span_id
WHERE parent.event_type = 'begin' AND child.event_type = 'begin'
GROUP BY parent.name, parent.depth, child.name, child.depth
ORDER BY relationship_count DESC;
-- Filter async operations by depth level for focused analysis
-- Shallow operations only (depth <= 2)
SELECT name, event_type, time, depth, span_id
FROM view_instance('async_events', 'my_process_123')
WHERE depth <= 2
ORDER BY time;
-- Deep nested operations only (depth >= 3)
SELECT name, depth, COUNT(*) as deep_operation_count
FROM view_instance('async_events', 'my_process_123')
WHERE depth >= 3 AND event_type = 'begin'
GROUP BY name, depth
ORDER BY depth DESC, deep_operation_count DESC;
-- Track async operation lifecycle with depth context
SELECT time, event_type, name, span_id, parent_span_id, depth
FROM view_instance('async_events', 'my_process_123')
WHERE span_id = 12345
ORDER BY time;
net_spans¶
Pre-paired network bandwidth spans materialized from a process's net-tagged stream. The X-axis in these rows is bits on the wire (begin_bits / end_bits), not time — each span's width represents its bit contribution to the parent scope. A Connection span wraps the bunch/packet, Object spans nest replicated actors/subobjects, RPC spans cover remote calls, and Property rows are point-in-time leaves.
The view is JIT-only and parameterized by process_id (there is no global instance). Partitions are built on demand when the view is first queried.
| Field | Type | Description |
|---|---|---|
process_id |
Dictionary(Int32, Utf8) |
Process id (the view parameter) |
stream_id |
Dictionary(Int32, Utf8) |
Source net stream (one per process) |
span_id |
Int64 |
Unique span id within the stream |
parent_span_id |
Int64 |
Span id of the enclosing span (-1 sentinel at the Connection root) |
depth |
UInt32 |
Tree depth (0 for Connection, 1+ inside) |
kind |
Dictionary(Int32, Utf8) |
connection, object, property, or rpc |
name |
Dictionary(Int32, Utf8) |
Connection / object / property / function name |
connection_name |
Dictionary(Int32, Utf8) |
Enclosing connection name (denormalized onto every row) |
is_outgoing |
Boolean |
Direction of the enclosing connection |
begin_bits |
Int64 |
Cumulative bit offset within the parent span (0 at the Connection root) |
end_bits |
Int64 |
begin_bits + bit_size |
bit_size |
Int64 |
Inclusive bit size attributed to this span |
begin_time |
Timestamp(Nanosecond) |
Timestamp of the span's Begin event |
end_time |
Timestamp(Nanosecond) |
Timestamp of the span's End event (equals begin_time for properties) |
Example queries:
-- Flame-chart-friendly query: feeds the Flame Graph cell with X=bits.
SELECT span_id AS id,
parent_span_id AS parent,
name,
depth,
begin_bits AS begin,
end_bits AS end,
bit_size,
kind,
connection_name,
is_outgoing
FROM view_instance('net_spans', '<process_id>')
WHERE connection_name = '127.0.0.1:7777' AND is_outgoing = false;
-- Top 10 properties by bandwidth across the whole capture
SELECT name, connection_name, SUM(bit_size) AS total_bits
FROM view_instance('net_spans', '<process_id>')
WHERE kind = 'property'
GROUP BY name, connection_name
ORDER BY total_bits DESC
LIMIT 10;
-- Per-connection outgoing bandwidth
SELECT connection_name, SUM(bit_size) AS bits
FROM view_instance('net_spans', '<process_id>')
WHERE kind = 'connection' AND is_outgoing = true
GROUP BY connection_name
ORDER BY bits DESC;
otel_spans¶
OpenTelemetry spans materialized from OTLP-ingested trace payloads. See OTLP Ingestion for how trace data lands in this view.
The view is JIT-only and parameterized by process_id — there is no global instance. Cross-process trace traversal (WHERE trace_id = X across services) requires UNION-ing across each participating process.
| Field | Type | Description |
|---|---|---|
process_id |
Dictionary(Int32, Utf8) |
Process id (the view parameter) |
stream_id |
Dictionary(Int32, Utf8) |
Trace stream identifier |
block_id |
Dictionary(Int32, Utf8) |
Block identifier |
insert_time |
Timestamp(Nanosecond) |
When the block was inserted |
exe |
Utf8 |
Executable name (joined from processes) |
username |
Utf8 |
User who ran the process (joined) |
computer |
Utf8 |
Computer/hostname (joined) |
process_properties |
Dictionary(Int32, Binary) |
Process-wide attributes (joined) |
trace_id |
FixedSizeBinary[16] |
W3C Trace Context trace id |
span_id |
FixedSizeBinary[8] |
W3C Trace Context span id |
parent_span_id |
FixedSizeBinary[8] (nullable) |
Parent span id (NULL for root spans) |
start_time |
Timestamp(Nanosecond) |
Span start time |
end_time |
Timestamp(Nanosecond) |
Span end time |
duration |
Int64 |
end_time − start_time, nanoseconds |
name |
Dictionary(Int32, Utf8) |
Span name |
kind |
Dictionary(Int32, Utf8) |
INTERNAL / SERVER / CLIENT / PRODUCER / CONSUMER / UNSPECIFIED |
status |
Dictionary(Int32, Utf8) |
OK / ERROR / UNSET |
status_message |
Utf8 (nullable) |
Human-readable status message |
properties |
Dictionary(Int32, Binary) |
Span attributes + scope info under otel.scope.* keys (JSONB) |
events |
Binary |
Span events as a JSONB array ([{time, name, attributes}, …]) |
links |
Binary |
Span links as a JSONB array ([{trace_id, span_id, attributes}, …]) |
trace_id and span_id are FixedSizeBinary (lengths fixed by W3C Trace Context). For human-readable display, render with encode(trace_id, 'hex') or an equivalent UDF at query time.
Example queries:
-- All spans in a single trace, ordered chronologically
SELECT name, kind, status, duration,
encode(span_id, 'hex') AS span,
encode(parent_span_id, 'hex') AS parent
FROM view_instance('otel_spans', '<process_id>')
WHERE trace_id = decode('0123456789abcdef0123456789abcdef', 'hex')
ORDER BY start_time;
-- Top 10 slowest server spans
SELECT name, AVG(duration) AS avg_ns, COUNT(*) AS calls
FROM view_instance('otel_spans', '<process_id>')
WHERE kind = 'SERVER'
GROUP BY name
ORDER BY avg_ns DESC
LIMIT 10;
-- Error spans with their scope library
SELECT name,
jsonb_as_string(jsonb_get(properties, 'otel.scope.name')) AS library,
status_message
FROM view_instance('otel_spans', '<process_id>')
WHERE status = 'ERROR'
ORDER BY start_time DESC;
-- Filter by instrumentation library
SELECT COUNT(*) AS span_count
FROM view_instance('otel_spans', '<process_id>')
WHERE jsonb_as_string(jsonb_get(properties, 'otel.scope.name'))
= 'opentelemetry.instrumentation.requests';
images¶
Screenshot and image data captured from instrumented processes via send_image(). The view is JIT-only and parameterized by process_id — there is no global instance.
| Field | Type | Description |
|---|---|---|
process_id |
Dictionary(Int32, Utf8) |
Process id (the view parameter) |
stream_id |
Dictionary(Int32, Utf8) |
Source image stream |
block_id |
Dictionary(Int32, Utf8) |
Block identifier |
insert_time |
Timestamp(Nanosecond) |
When the block was ingested |
exe |
Dictionary(Int32, Utf8) |
Executable name |
username |
Dictionary(Int32, Utf8) |
User who ran the process |
computer |
Dictionary(Int32, Utf8) |
Computer/hostname |
time |
Timestamp(Nanosecond) |
Timestamp when the image was captured |
name |
Utf8 |
Image name (e.g. "screenshot") |
format |
Dictionary(Int32, Utf8) |
Image format string (e.g. "png") |
payload_size |
Int64 |
Compressed byte size of the image data |
data |
Binary |
Raw image bytes |
Example queries:
-- List all screenshots captured by a process
SELECT time, name, format, payload_size
FROM view_instance('images', '<process_id>')
ORDER BY time DESC;
-- Count images per process in the last hour
SELECT process_id, exe, COUNT(*) AS image_count
FROM images
WHERE time >= NOW() - INTERVAL '1 hour'
GROUP BY process_id, exe
ORDER BY image_count DESC;
Data Types¶
Audience¶
audience is a documented, stable column on processes, streams, blocks, log_entries,
log_stats, and measures. On processes, streams, and blocks it is that row's own write
audience, written server-side, never derived from any other row (a block's own stamp is never
borrowed from the process_id/stream_id it points at). On log_entries, measures, and
log_stats it is the audience of the block the row came from. Never client-settable, and never
NULL.
Dictionary(Int32, Utf8) on all six views -- it compares against string literals normally.
It is not a filter a query needs to apply: enforcement happens unconditionally underneath every query, and a caller only ever sees rows whose audience is within their own read scope. The column exists for observability -- "whose data is this, how much of each" -- not as a user-authored access check.
Properties¶
Key-value pairs stored as dictionary-encoded JSONB with the following structure:
This format gives dictionary compression (repeated property sets stored once and referenced by index) and JSONB efficiency (native binary JSON format for fast property access).
Common properties fields:
properties- Event-specific metadata (log properties, metric properties)process_properties- Process-wide metadata shared across all events from a process
Querying properties:
-- Access property values using property_get function (works with all formats)
SELECT property_get(process_properties, 'thread-name') as thread_name
FROM log_entries
WHERE property_get(process_properties, 'thread-name') IS NOT NULL;
-- Count properties using properties_length
SELECT properties_length(properties) as prop_count
FROM log_entries
WHERE properties_length(properties) > 0;
Dictionary Compression¶
String fields in the event tables use dictionary compression (Dictionary(Int32, Utf8))
for storage efficiency: log_entries, log_stats, measures, thread_spans,
async_events, net_spans, otel_spans, and images (see each table's field reference
above). The processes/streams metadata tables store their string columns as plain
Utf8. Dictionary-compressed fields are transparent to SQL — query them as normal strings.
Timestamps¶
All time fields use Timestamp(Nanosecond) precision, UTC.
View Relationships¶
Views can be joined to combine information:
-- Join log entries with process information
SELECT l.time, l.level, l.msg, p.exe, p.computer
FROM log_entries l
JOIN processes p ON l.process_id = p.process_id
WHERE l.level <= 2; -- Fatal and Error only
-- Join measures with stream information
SELECT m.time, m.name, m.value, s.tags
FROM measures m
JOIN streams s ON m.stream_id = s.stream_id
WHERE m.name = 'cpu_usage';
Performance Considerations¶
Dictionary Fields¶
Dictionary-compressed fields are optimized for:
- Equality comparisons (
field = 'value') - IN clauses (
field IN ('val1', 'val2')) - LIKE patterns on repeated values
Time-based Queries¶
Always use time ranges for optimal performance:
-- Good - uses time index
WHERE time >= NOW() - INTERVAL '1 hour'
-- Avoid - full table scan
WHERE level <= 3
View Instances¶
Use view_instance() for process-specific queries:
-- Better performance for single process
SELECT * FROM view_instance('log_entries', 'process_123')
-- Less efficient for single process
SELECT * FROM log_entries WHERE process_id = 'process_123'
Next Steps¶
- Functions Reference - SQL functions available for queries
- Query Patterns - Common observability query patterns
- Performance Guide - Optimize your queries for best performance