Skip to content

Use PromQL to Query Data

EMQX Tables supports Prometheus Query Language (PromQL) in addition to SQL, allowing you to query time-series data using familiar Prometheus semantics.

EMQX Tables is built on GreptimeDB, which provides a native PromQL implementation. This means you can directly use PromQL to analyze metrics-style data stored in EMQX Tables, without converting queries to SQL.

In the Data Explorer of EMQX Cloud, you can switch between SQL and PromQL modes to query the same underlying data.

When to Use PromQL

PromQL is especially useful in the following scenarios:

  • You are already familiar with Prometheus and PromQL.
  • You want to perform time-series–oriented calculations, such as rates, increases, or rolling aggregations.
  • You are querying metrics-like data produced by IoT devices, message flows, or system monitoring.

Query Time Range and Step

When using PromQL in the EMQX Tables Data Explorer, the query time range and resolution are controlled by the UI:

  • Time Range: Defines the start and end time of the query
  • Step: Defines the query resolution (for example, 30s)

These parameters are applied automatically to your PromQL query, similar to how Prometheus evaluates range queries.

Data Model Mapping in EMQX Tables

EMQX Tables uses a time-series table model inherited from GreptimeDB. When querying data with PromQL, this model is mapped to PromQL concepts as follows:

PromQL ConceptEMQX Tables Concept
MetricTable
LabelTag column
Sample valueField column
TimestampTime index column

In this model, a single table can contain multiple field columns. Each field is exposed as an independent PromQL value stream, sharing the same metric name, labels, and timestamps.

This differs from the traditional Prometheus data model, where each metric contains only one value.

Query Specific Fields

By default, a PromQL query runs against all numeric fields in a table. To query a specific field, use the special label matcher __field__.

Query a Single Field

mqtt_messages{__field__="count"}

Exclude a Field

mqtt_messages{__field__!="count"}

Match Multiple Fields Using Regex

mqtt_messages{__field__=~"count|bytes"}

Exclude Multiple Fields Using Regex

mqtt_messages{__field__!~"error_.*"}

This extension is specific to EMQX Tables (via GreptimeDB) and is not part of standard PromQL.

Cross-Database Queries

EMQX Tables supports querying data across databases using the special label matcher __database__.

mqtt_messages{__database__="production"}

Notes:

  • Only the equality matcher (=) is supported.
  • This is an extension beyond standard PromQL.

Supported Data Types and Limitations

PromQL queries in EMQX Tables currently operate on the following data types:

  • Timestamp: Timestamp
  • Label (tag): String
  • Value (field): Double

High-precision timestamps (microseconds or nanoseconds) are supported for storage, but PromQL calculations use millisecond precision, as defined by the PromQL specification.

PromQL Feature Support

EMQX Tables supports over 90% of PromQL features, covering the most common querying and aggregation scenarios.

Literals

  • String and float literals are supported.
  • Behavior follows the standard PromQL specification.

Selectors

  • Instant selectors and range selectors are supported.
  • Time duration and offset modifiers are supported.
  • The @ modifier is not currently supported.

Notes:

  • Negative matching on metric names (for example, {__name__!="metric"}) is not allowed, consistent with Prometheus behavior.
  • Selecting non-existent columns does not raise an error; they are treated as empty values ("").
  • Selecting a non-existent metric name results in an error.

Binary Operators

EMQX Tables supports all standard PromQL binary operators. The table below shows the mapping between GreptimeDB internal operators and their corresponding PromQL syntax.

OperatorPromQL SyntaxExample
add+mqtt_bytes_in + mqtt_bytes_out
sub-mqtt_bytes_in - mqtt_bytes_out
mul*mqtt_msg_rate * 100
div/mqtt_bytes_in / mqtt_connections
mod%mqtt_packets % 10
power^mqtt_latency ^ 2
eqlc==mqtt_status == 1
neq!=mqtt_status != 0
gtr>mqtt_latency > 100
lss<mqtt_latency < 50
gte>=mqtt_connections >= 1000
lte<=mqtt_connections <= 100
andandmqtt_connections and mqtt_sessions
orormqtt_errors or mqtt_timeouts
unlessunlessmqtt_connections unless mqtt_sessions
atan2atan2()atan2(y_metric, x_metric)

Aggregation Operators

Supported aggregation operators include:

AggregatorExample
sumsum by (clientid)(mqtt_messages)
avgavg by (topic)(mqtt_latency)
minmin by (node)(cpu_usage)
maxmax by (node)(cpu_usage)
countcount(mqtt_connections)
count_valuescount_values("version", build_info)
topktopk(5, rate(mqtt_messages[5m]))
bottomkbottomk(5, rate(mqtt_messages[5m]))
quantilequantile(0.95, mqtt_latency)
stddevstddev(mqtt_latency)
stdvarstdvar(mqtt_latency)

Instant Functions

EMQX Tables supports a wide range of PromQL instant functions, which operate on instant vectors and return instant results, including but not limited to:

  • Math functions: abs, ceil, floor, sqrt, exp, ln
  • Trigonometric functions: sin, cos, tan, and variants
  • Utility functions: timestamp, scalar, sort, sort_desc
  • Histogram: histogram_quantile
  • Prediction: predict_linear
  • Query utility: absent

The table below lists supported functions along with example PromQL expressions.

FunctionExample
absabs(mqtt_latency)
ceilceil(cpu_usage)
floorfloor(cpu_usage)
sqrtsqrt(sensor_value)
expexp(metric)
lnln(metric)
log2log2(metric)
log10log10(metric)
acosacos(metric)
asinasin(metric)
atanatan(metric)
sinsin(metric)
coscos(metric)
tantan(metric)
acoshacosh(metric)
asinhasinh(metric)
atanhatanh(metric)
sinhsinh(metric)
coshcosh(metric)
tanhtanh(metric)
sgnsgn(metric)
scalarscalar(metric)
timestamptimestamp(mqtt_messages)
sortsort(http_requests_total)
sort_descsort_desc(http_requests_total)
histogram_quantilehistogram_quantile(0.95, mqtt_latency_bucket)
predict_linearpredict_linear(cpu_usage[5m], 120)
absentabsent(nonexistent{job="myjob"})
pipi()
degdeg(metric)
radrad(metric)
clampclamp(metric, 0, 100)
clamp_minclamp_min(metric, 0)
clamp_maxclamp_max(metric, 100)

Notes:

  • v represents an instant vector.
  • Functions such as predict_linear require a range vector as input.
  • All functions follow standard PromQL semantics.

Range Functions

The following commonly used range functions are supported:

FunctionExample
ideltaidelta(metric[5m])
derivderiv(metric[5m])
stdvar_over_timestdvar_over_time(metric[5m])
resetreset(metric[5m])
raterate(mqtt_messages[5m])
irateirate(mqtt_messages[1m])
increaseincrease(mqtt_messages[10m])
deltadelta(sensor_value[5m])
changeschanges(connection_state[5m])
<aggr>_over_timeavg_over_time(cpu_usage[5m])
stddev_over_timestddev_over_time(latency[5m])

Label Manipulation Functions

The following label processing functions are fully supported:

FunctionExample
label_joinlabel_join(mqtt_metrics{src1="a",src2="b"}, "dst", ",", "src1", "src2")
label_replacelabel_replace(mqtt_metrics{job="api-server"}, "service", "$1", "job", "(.*)-server")
sort_by_labelsort_by_label(mqtt_metrics{node="node1"}, "node")
sort_by_label_descsort_by_label_desc(mqtt_metrics{node="node1"}, "node")