Skip to main content
MoleSignal exposes a single query endpoint backed by DataFusion. The endpoint supports full SQL, including joins, CTEs, and window functions, and a PromQL subset for metrics, all against the same store.

The query endpoint

The endpoint requires the streams.query permission.

Request body

The query string parameter clusters selects remote clusters for a federated search.

Response

The response carries columns, array-shaped rows, scanned_rows, and took_ms:
Each cell follows the type of its column: Federated responses can also carry federation metadata.
Send Accept: application/x-ndjson to stream one JSON object per row, followed by a final {"__meta__": {...}} record with scanned_rows and took_ms. Streaming bypasses the result cache.

Time ranges and asynchronous jobs

Use a bounded time_range for interactive queries. MoleSignal estimates the size of a query as the length of the range in seconds multiplied by [querier].estimate_throughput_per_sec. When the estimate reaches [querier].auto_async_threshold_rows, the query runs as a durable search job. With the defaults, that is a range of 50,000 seconds, or about 13.9 hours. An asynchronous query answers 202 with the job to follow:
Control the mode with the Prefer request header: Follow a job with these endpoints: A job keeps its result for seven days. Jobs report the states pending, running, done, failed, and cancelled. A job also reports its kind (query or backfill, with the pipeline_id of a backfill), the attempt, the submitted request, and the submitter as user_id and submitted_by. A caller reads and changes the jobs that the caller submitted. A caller with org.settings.manage reads and changes every job of the organization. A job of another user answers 404, the same as a job that does not exist. The list and the summary count only the jobs that the caller can read. The Search jobs page under Streams shows the same jobs. See Streams.

SQL

A SQL statement names a stream in FROM, and the stream field of the request names the same primary stream:

Join across signals

Logs, metrics, and traces live in the same store, so one query can join them. Name the primary stream in stream, and reference the other streams by name. For example, join error logs to the matching spans on trace_id:

Current versions of RUM rows

rum_views_latest and rum_sessions_latest read rum_views and rum_sessions with only the newest version of each view or session. Name the stream in stream, or the view itself, and the time range of the request bounds the rows, so SELECT count(*) FROM rum_views_latest WHERE "application.id" = 'shop' counts the views that began in the range. Field masking of the stream applies to them. MATCH_TEXT understands several words as an AND of tokens, "a b" as a phrase, error* and *error as wildcards, a OR b, and -a to exclude a term. Add the index when creating a stream or editing its schema. See Streams.

Timestamps in SQL

_timestamp is a Timestamp(µs, "UTC") column. An integer literal that is compared with _timestamp counts microseconds since the Unix epoch, so these two filters select the same rows:
Only a literal is read as microseconds. To compare _timestamp with an expression or another column, convert the value with to_timestamp_micros(...). Read the microseconds of a row with CAST(_timestamp AS BIGINT).

Encrypted fields

decrypt(field) restores the plaintext of a field that was marked encrypted. See Streams.

PromQL

Set language to promql to run PromQL over metric streams. A metric selector names a metric, which every metrics stream holding it answers: metric_name holds the metric, the value column holds the sample, and the other columns are labels. Through this endpoint, MoleSignal evaluates the expression as an instant query at time_range.end and returns one row per series, with value first and then the labels:
Coverage is broad. It includes the rate family and all *_over_time functions, the standard aggregations including topk and limitk, histogram_quantile, label_replace and label_join, math and trigonometry, the and, or, and unless set operators with on, ignoring, group_left, and group_right matching, the selector modifiers @ and offset, and subqueries.

PromQL support matrix

The full list of supported functions, operators, and modifiers, plus the known gaps (native-histogram functions and the binary default fill-in).

Search around an event

POST /api/v1/query/search_around returns the events immediately before and after a given one, so an investigation can read the context of a log line. See Search around an event.

Inspection and control

  • POST /api/v1/query/inspect plans a query without executing it and returns query metadata and the logical plan.
  • POST /api/v1/query/recommendations analyzes a query profile without executing the query.
  • GET /api/v1/query/running and POST /api/v1/query/{id}/cancel let organization administrators inspect and cancel active work.
  • GET /api/v1/query/sql/capabilities and GET /api/v1/query/promql/capabilities list the supported functions for editors.
Standard queries require streams.query. Active-query administration requires org.settings.read or org.settings.manage. Add ?clusters=local,cluster-name to the query endpoint for a federated search. An unreachable remote cluster appears as degraded in the federation metadata and never silently becomes local data. See Role-based deployment.

Stored fields

The fields of a stream depend on what senders provide. These are the fields that OTLP intake produces. Resource and record attributes become top-level fields with their original keys, such as service.name, and keep their numeric types.

OTLP log fields

Trace span fields

A span is identified by its trace_id and span_id. A span that is sent again is dropped as a duplicate.

OTLP metric fields

MoleSignal flattens every OTLP data point into one metric event. Resource, scope, and data-point attributes stay queryable fields. The reserved fields below take precedence over attributes of the same name. Histogram bucket boundaries and counts, and summary quantiles, are not stored. Delta points are stored as received. The PromQL rate family reads the stored temporality: increase sums delta values in the window, rate divides that sum by the range, and irate divides the latest delta value by its interval. For cumulative monotonic sums, counter resets are handled. If an exporter changes temporality inside one window, only the latest run with the same semantics is evaluated. OTLP over HTTP accepts protobuf (http/protobuf) and JSON for metrics, logs, and traces. The JSON encoding writes 64-bit integers as strings, such as "asInt": "340" and "count": "4". MoleSignal reads the strings and the plain numbers alike.

Caching

Queries use in-process caches for open index handles, results of closed time windows, search term counts, and index footers. For remote object storage, an on-disk cache keeps byte ranges of objects under ./data/cache/objects, 10 GiB by default. Caching is transparent to the response contract. Use /metrics to measure cache behavior, and see Configuration to size the caches.
Last modified on October 26, 2026