All Products
Search
Document Center

Time Series Database:InfluxQL reference

Last Updated:Mar 28, 2026

InfluxQL (Influx Query Language) is an SQL-like query language for TSDB for InfluxDB. This reference covers the complete syntax specification, including notation, literals, statements, clauses, expressions, and query engine internals.

On this page

Notation

InfluxQL syntax is specified using Extended Backus-Naur Form (EBNF), the same notation as the Go programming language specification.

Production  = production_name "=" [ Expression ] "." .
Expression  = Alternative { "|" Alternative } .
Alternative = Term { Term } .
Term        = production_name | token [ "…" token ] | Group | Option | Repetition .
Group       = "(" Expression ")" .
Option      = "[" Expression "]" .
Repetition  = "{" Expression "}" .

Notation operators in order of increasing precedence:

|   alternation
()  grouping
[]  option (0 or 1 times)
{}  repetition (0 to n times)

Query elements

Characters

InfluxQL supports Unicode text encoded in UTF-8.

newline      = /* the Unicode code point U+000A */ .
unicode_char = /* an arbitrary Unicode code point except newline */ .

Letters and digits

InfluxQL letters include ASCII characters and underscores. Underscores (U+005F) behave as letters. InfluxQL supports decimal digits only.

letter       = ascii_letter | "_" .
ascii_letter = "A" … "Z" | "a" … "z" .
digit        = "0" … "9" .

Identifiers

Identifiers name databases, retention policies, users, measurements, tag keys, and field keys.

Double-quoted identifiers can:

  • Contain Unicode characters (but not line feeds)

  • Use \" to escape double quotes

  • Contain InfluxQL keywords

Unquoted identifiers must:

  • Start with an ASCII letter or underscore

  • Contain only ASCII letters, digits, and underscores

identifier          = unquoted_identifier | quoted_identifier .
unquoted_identifier = ( letter ) { letter | digit } .
quoted_identifier   = `"` unicode_char { unicode_char } `"` .

Examples:

cpu
_cpu_stats
"1h"
"anything really"
"1_Crazy-1337.identifier>NAME"

Keywords

ALL           ALTER         ANY           AS            ASC           BEGIN
BY            CREATE        CONTINUOUS    DATABASE      DATABASES     DEFAULT
DELETE        DESC          DESTINATIONS  DIAGNOSTICS   DISTINCT      DROP
DURATION      END           EVERY         EXPLAIN       FIELD         FOR
FROM          GRANT         GRANTS        GROUP         GROUPS        IN
INF           INSERT        INTO          KEY           KEYS          KILL
LIMIT         SHOW          MEASUREMENT   MEASUREMENTS  NAME          OFFSET
ON            ORDER         PASSWORD      POLICY        POLICIES      PRIVILEGES
QUERIES       QUERY         READ          REPLICATION   RESAMPLE      RETENTION
REVOKE        SELECT        SERIES        SET           SHARD         SHARDS
SLIMIT        SOFFSET       STATS         SUBSCRIPTION  SUBSCRIPTIONS TAG
TO            USER          USERS         VALUES        WHERE         WITH
WRITE

When used as identifiers in query statements, keywords must be enclosed in double quotation marks.

Exception: `time`

The time keyword can be used as an identifier without double quotation marks in the following names: continuous query, database, measurement, retention policy, subscription, and user. However, time cannot be used as a field key or tag key — attempting to write data with time as a field key or tag key returns an error.

Literals

Integers

InfluxQL supports decimal integers only. Hexadecimal and octal integers are not supported.

int_lit = ( "1" … "9" ) { digit } .

Floats

InfluxQL supports floating-point numbers but not exponents.

float_lit = int_lit "." int_lit .

Strings

Strings must be enclosed in single quotation marks. Use \' to escape single quotes within a string.

string_lit = `'` { unicode_char } `'` .

Durations

A duration literal consists of an integer followed immediately by a time unit — no spaces between them. Multiple units can be combined to express a duration.

duration_lit  = int_lit duration_unit .
duration_unit = "ns" | "u" | "µ" | "ms" | "s" | "m" | "h" | "d" | "w" .

Valid units

UnitDescription
nsNanosecond (one billionth of a second)
u or µMicrosecond (one millionth of a second)
msMillisecond (one thousandth of a second)
sSecond
mMinute
hHour
dDay
wWeek

Date and time

Date and time in InfluxQL follows Go's formatting and parsing rules rather than EBNF. The reference timestamp — January 2, 2006, 15:04:05 — defines the required format:

time_lit = "2006-01-02 15:04:05.999999" | "2006-01-02" .

Boolean values

bool_lit = TRUE | FALSE .

Regular expressions

regex_lit = "/" { unicode_char } "/" .

Operators: =~ matches, !~ does not match.

Regular expressions can be used for:

  • Field keys and tag keys in SELECT clauses

  • Measurements in FROM clauses

  • Tag values in WHERE clauses

  • Tag keys in GROUP BY clauses

Regular expressions cannot be used for:

  • Non-string field values in WHERE clauses

  • Databases

  • Retention policies

Queries

A query consists of one or more statements separated by semicolons (;).

query     = statement { ";" statement } .

statement = alter_retention_policy_stmt |
            create_continuous_query_stmt |
            create_database_stmt |
            create_retention_policy_stmt |
            create_subscription_stmt |
            create_user_stmt |
            delete_stmt |
            drop_continuous_query_stmt |
            drop_database_stmt |
            drop_measurement_stmt |
            drop_retention_policy_stmt |
            drop_series_stmt |
            drop_shard_stmt |
            drop_subscription_stmt |
            drop_user_stmt |
            explain_stmt |
            explain_analyze_stmt |
            grant_stmt |
            kill_query_statement |
            revoke_stmt |
            select_stmt |
            show_continuous_queries_stmt |
            show_databases_stmt |
            show_diagnostics_stmt |
            show_field_key_cardinality_stmt |
            show_field_keys_stmt |
            show_grants_stmt |
            show_measurement_cardinality_stmt |
            show_measurement_exact_cardinality_stmt |
            show_measurements_stmt |
            show_queries_stmt |
            show_retention_policies_stmt |
            show_series_cardinality_stmt |
            show_series_exact_cardinality_stmt |
            show_series_stmt |
            show_shard_groups_stmt |
            show_shards_stmt |
            show_stats_stmt |
            show_subscriptions_stmt |
            show_tag_key_cardinality_stmt |
            show_tag_key_exact_cardinality_stmt |
            show_tag_keys_stmt |
            show_tag_values_stmt |
            show_tag_values_cardinality_stmt |
            show_users_stmt .

Statements

DELETE

Important

TSDB for InfluxDB® supports delete operations. Due to the underlying delete syntax in InfluxDB®, delete operations may cause deadlocks and result in read/write failures. Avoid performing delete operations in TSDB for InfluxDB®.

delete_stmt = "DELETE" ( from_clause | where_clause | from_clause where_clause ) .

Examples:

DELETE FROM "cpu"
DELETE FROM "cpu" WHERE time < '2000-01-01T00:00:00Z'
DELETE WHERE time < '2000-01-01T00:00:00Z'

EXPLAIN

EXPLAIN parses and plans a query, then returns an estimated resource cost summary.

Unlike SQL engines that support join operations, InfluxQL does not support joins. The plan output reflects costs specific to InfluxQL queries: the number of time series accessed, the number of iterators reading Time-Structured Merge Tree (TSM) files, and the number of TSM blocks scanned.

An EXPLAIN result includes:

  • Expression

  • Auxiliary fields

  • Number of shards

  • Number of series

  • Cached values

  • Number of files

  • Number of blocks

  • Size of blocks

Example:

> EXPLAIN SELECT sum(pointReq) FROM "_internal"."monitor"."write" GROUP BY hostname;
QUERY PLAN
----------
EXPRESSION: sum(pointReq::integer)
NUMBER OF SHARDS: 2
NUMBER OF SERIES: 2
CACHED VALUES: 110
NUMBER OF FILES: 1
NUMBER OF BLOCKS: 1
SIZE OF BLOCKS: 931

EXPLAIN ANALYZE

EXPLAIN ANALYZE executes an InfluxQL query and returns the actual resource costs measured during execution.

explain_analyze_stmt = "EXPLAIN ANALYZE" select_stmt .

Example:

> EXPLAIN ANALYZE SELECT sum(pointReq) FROM "_internal"."monitor"."write" GROUP BY hostname;
EXPLAIN ANALYZE
---------------
.
└── select
    ├── execution_time: 242.167µs
    ├── planning_time: 2.165637ms
    ├── total_time: 2.407804ms
    └── field_iterators
        ├── labels
        │   └── statement: SELECT sum(pointReq::integer) FROM "_internal"."monitor"."write" GROUP BY hostname
        └── expression
            ├── labels
            │   └── expr: sum(pointReq::integer)
            ├── create_iterator
            │   ├── labels
            │   │   ├── measurement: write
            │   │   └── shard_id: 57
            │   ├── cursors_ref: 1
            │   ├── cursors_aux: 0
            │   ├── cursors_cond: 0
            │   ├── float_blocks_decoded: 0
            │   ├── float_blocks_size_bytes: 0
            │   ├── integer_blocks_decoded: 1
            │   ├── integer_blocks_size_bytes: 931
            │   ├── unsigned_blocks_decoded: 0
            │   ├── unsigned_blocks_size_bytes: 0
            │   ├── string_blocks_decoded: 0
            │   ├── string_blocks_size_bytes: 0
            │   ├── boolean_blocks_decoded: 0
            │   ├── boolean_blocks_size_bytes: 0
            │   └── planning_time: 1.401099ms
            └── create_iterator
                ├── labels
                │   ├── measurement: write
                │   └── shard_id: 58
                ├── cursors_ref: 1
                ├── cursors_aux: 0
                ├── cursors_cond: 0
                ├── float_blocks_decoded: 0
                ├── float_blocks_size_bytes: 0
                ├── integer_blocks_decoded: 0
                ├── integer_blocks_size_bytes: 0
                ├── unsigned_blocks_decoded: 0
                ├── unsigned_blocks_size_bytes: 0
                ├── string_blocks_decoded: 0
                ├── string_blocks_size_bytes: 0
                ├── boolean_blocks_decoded: 0
                ├── boolean_blocks_size_bytes: 0
                └── planning_time: 76.192µs

KILL QUERY

KILL QUERY stops a running query by its query ID.

kill_query_statement = "KILL QUERY" query_id .

To find the query ID, run SHOW QUERIES. The qid field in the result is the query ID.

Example:

-- Kill the query with qid 36
KILL QUERY 36

SELECT

select_stmt = "SELECT" fields from_clause [ into_clause ] [ where_clause ]
              [ group_by_clause ] [ order_by_clause ] [ limit_clause ]
              [ offset_clause ] [ slimit_clause ] [ soffset_clause ] [ timezone_clause ] .

Examples:

Query data from all measurements prefixed with cpu, write results to the same measurement names in the cpu_1h retention policy:

SELECT mean("value") INTO "cpu_1h".:MEASUREMENT FROM /cpu.*/

Query data from the cpu measurement, grouped by day in the America/Chicago timezone:

SELECT mean("value") FROM "cpu" GROUP BY region, time(1d) fill(0) tz('America/Chicago')

SHOW CARDINALITY

SHOW CARDINALITY is a family of commands for querying the cardinality of measurements, series, tag keys, tag values, and field keys.

Two modes are available:

  • Estimated cardinality: calculated from an internal plan. Low overhead regardless of data size. Use this by default.

  • Exact cardinality: calculated from TSM data. High overhead for large datasets. Use only when your use case requires precision.

Time-based filtering is available only when the Time Series Index (TSI) feature is enabled for your database.

For individual statement syntax, see:

SHOW CONTINUOUS QUERIES

show_continuous_queries_stmt = "SHOW CONTINUOUS QUERIES" .

Example:

-- List all continuous queries
SHOW CONTINUOUS QUERIES

SHOW DATABASES

show_databases_stmt = "SHOW DATABASES" .

Example:

-- List all databases
SHOW DATABASES

SHOW DIAGNOSTICS

Returns node information including build info, runtime details, hostname, server configuration, memory usage, and Go runtime diagnostics.

show_diagnostics_stmt = "SHOW DIAGNOSTICS" .

SHOW FIELD KEY CARDINALITY

Returns the estimated or exact cardinality of the field key set. Without an ON clause, the current database is used.

Using optional clauses returns exact cardinality. Time filtering requires TSI; the time filter cannot be used in WHERE clauses.

show_field_key_cardinality_stmt =
    "SHOW FIELD KEY CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

show_field_key_exact_cardinality_stmt =
    "SHOW FIELD KEY EXACT CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

Examples:

-- Estimated cardinality for the current database
SHOW FIELD KEY CARDINALITY

-- Exact cardinality for a specified database
SHOW FIELD KEY EXACT CARDINALITY ON mydb

SHOW FIELD KEYS

show_field_keys_stmt = "SHOW FIELD KEYS" [ on_clause ] [ from_clause ] .

Examples:

-- Show field keys and value types from all measurements
SHOW FIELD KEYS

-- Show field keys and value types from a specific measurement
SHOW FIELD KEYS FROM "cpu"

SHOW GRANTS

show_grants_stmt = "SHOW GRANTS FOR" user_name .

Example:

-- Show grants for jdoe
SHOW GRANTS FOR "jdoe"

SHOW MEASUREMENT CARDINALITY

Returns the estimated or exact cardinality of the measurement set. Without an ON clause, the current database is used.

Using optional clauses returns exact cardinality. Time filtering requires TSI; the time filter cannot be used in WHERE clauses.

show_measurement_cardinality_stmt =
    "SHOW MEASUREMENT CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

show_measurement_exact_cardinality_stmt =
    "SHOW MEASUREMENT EXACT CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

Examples:

-- Estimated cardinality for the current database
SHOW MEASUREMENT CARDINALITY

-- Exact cardinality for a specified database
SHOW MEASUREMENT EXACT CARDINALITY ON mydb

SHOW MEASUREMENTS

show_measurements_stmt = "SHOW MEASUREMENTS" [ on_clause ] [ with_measurement_clause ] [ where_clause ] [ limit_clause ] [ offset_clause ] .

Examples:

-- List all measurements
SHOW MEASUREMENTS

-- Measurements where region = 'uswest' and host = 'serverA'
SHOW MEASUREMENTS WHERE "region" = 'uswest' AND "host" = 'serverA'

-- Measurements starting with 'h2o'
SHOW MEASUREMENTS WITH MEASUREMENT =~ /h2o.*/

SHOW QUERIES

show_queries_stmt = "SHOW QUERIES" .

Example:

-- List all currently running queries
SHOW QUERIES

SHOW RETENTION POLICIES

show_retention_policies_stmt = "SHOW RETENTION POLICIES" [ on_clause ] .

Example:

-- List all retention policies for a database
SHOW RETENTION POLICIES ON "mydb"

SHOW SERIES

show_series_stmt = "SHOW SERIES" [ on_clause ] [ from_clause ] [ where_clause ] [ limit_clause ] [ offset_clause ] .

Example:

SHOW SERIES FROM "telegraf"."autogen"."cpu" WHERE cpu = 'cpu8'

SHOW SERIES CARDINALITY

Returns the estimated or exact cardinality of the series set. Without an ON clause, the current database is used.

Series cardinality directly affects RAM usage.

Using optional clauses returns exact cardinality. Time filtering requires TSI; the time filter cannot be used in WHERE clauses.

show_series_cardinality_stmt =
    "SHOW SERIES CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

show_series_exact_cardinality_stmt =
    "SHOW SERIES EXACT CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

Examples:

-- Estimated cardinality for the current database
SHOW SERIES CARDINALITY

-- Estimated cardinality for a specified database
SHOW SERIES CARDINALITY ON mydb

-- Exact cardinality for the current database
SHOW SERIES EXACT CARDINALITY

-- Exact cardinality for a specified database
SHOW SERIES EXACT CARDINALITY ON mydb

SHOW SHARD GROUPS

show_shard_groups_stmt = "SHOW SHARD GROUPS" .

Example:

SHOW SHARD GROUPS

SHOW SHARDS

show_shards_stmt = "SHOW SHARDS" .

Example:

SHOW SHARDS

SHOW STATS

Returns statistical information about a TSDB for InfluxDB node and its available components.

show_stats_stmt = "SHOW STATS [ FOR '<component>' | 'indexes' ]"

SHOW STATS

Returns statistics for all components except index memory usage. Statistical values are stored in memory and reset to zero on node restart. TSDB for InfluxDB automatically runs SHOW STATS every 10 seconds to populate the _internal database.

SHOW STATS FOR \<component\>

Returns statistics for a specific component. For the runtime component, returns a memory usage summary based on the Go runtime package.

SHOW STATS FOR 'indexes'

Returns estimated memory usage for all indexes. This information is excluded from SHOW STATS because computing it is resource-intensive.

Example:

> SHOW STATS
name: runtime
-------------
Alloc   Frees   HeapAlloc  HeapIdle   HeapInUse  HeapObjects  HeapReleased  HeapSys   Lookups  Mallocs  NumGC  NumGoroutine  PauseTotalNs  Sys        TotalAlloc
4136056 6684537 4136056    34586624   5816320    49412        0             40402944  110      6733949  83     44            36083006      46692600   439945704

name: graphite
tags: proto=tcp
batches_tx  bytes_rx  connections_active  connections_handled  points_rx  points_tx
----------  --------  ------------------  -------------------  ---------  ---------
159         3999750   0                   1                    158110     158110

SHOW SUBSCRIPTIONS

show_subscriptions_stmt = "SHOW SUBSCRIPTIONS" .

Example:

SHOW SUBSCRIPTIONS

SHOW TAG KEY CARDINALITY

Returns the estimated or exact cardinality of the tag key set. Without an ON clause, the current database is used.

Using optional clauses returns exact cardinality. Time filtering requires TSI; the time filter cannot be used in WHERE clauses.

show_tag_key_cardinality_stmt =
    "SHOW TAG KEY CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

show_tag_key_exact_cardinality_stmt =
    "SHOW TAG KEY EXACT CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ]

Examples:

-- Estimated tag key cardinality
SHOW TAG KEY CARDINALITY

-- Exact tag key cardinality
SHOW TAG KEY EXACT CARDINALITY

SHOW TAG KEYS

show_tag_keys_stmt = "SHOW TAG KEYS" [ on_clause ] [ from_clause ] [ where_clause ]
                     [ limit_clause ] [ offset_clause ] .

Examples:

-- List all tag keys
SHOW TAG KEYS

-- Tag keys from the cpu measurement
SHOW TAG KEYS FROM "cpu"

-- Tag keys from cpu where region = 'uswest'
SHOW TAG KEYS FROM "cpu" WHERE "region" = 'uswest'

-- Tag keys where host = 'serverA'
SHOW TAG KEYS WHERE "host" = 'serverA'

SHOW TAG VALUES

show_tag_values_stmt = "SHOW TAG VALUES" [ on_clause ] [ from_clause ] with_tag_clause [ where_clause ]
                       [ limit_clause ] [ offset_clause ] .

Examples:

-- All tag values for the region tag across all measurements
SHOW TAG VALUES WITH KEY = "region"

-- Tag values for the region tag from the cpu measurement
SHOW TAG VALUES FROM "cpu" WITH KEY = "region"

-- Tag values for all tag keys that don't contain the letter 'c'
SHOW TAG VALUES WITH KEY !~ /.*c.*/

-- Tag values for region and host from cpu where service = 'redis'
SHOW TAG VALUES FROM "cpu" WITH KEY IN ("region", "host") WHERE "service" = 'redis'

SHOW TAG VALUES CARDINALITY

Returns the estimated or exact cardinality of tag values for specified tag keys. Without an ON clause, the current database is used.

Using optional clauses returns exact cardinality. Time filtering requires TSI.

show_tag_values_cardinality_stmt =
    "SHOW TAG VALUES CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ] with_key_clause

show_tag_values_exact_cardinality_stmt =
    "SHOW TAG VALUES EXACT CARDINALITY"
    [ on_clause ] [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ] with_key_clause

Examples:

-- Estimated cardinality for a tag key
SHOW TAG VALUES CARDINALITY WITH KEY = "myTagKey"

-- Exact cardinality for a tag key
SHOW TAG VALUES EXACT CARDINALITY WITH KEY = "myTagKey"

SHOW USERS

show_users_stmt = "SHOW USERS" .

Example:

-- List all users
SHOW USERS

Clauses

from_clause     = "FROM" measurements .

group_by_clause = "GROUP BY" dimensions fill(fill_option) .

into_clause     = "INTO" ( measurement | back_ref ) .

limit_clause    = "LIMIT" int_lit .

offset_clause   = "OFFSET" int_lit .

slimit_clause   = "SLIMIT" int_lit .

soffset_clause  = "SOFFSET" int_lit .

timezone_clause = tz(string_lit) .

on_clause       = "ON" db_name .

order_by_clause = "ORDER BY" sort_fields .

to_clause       = "TO" user_name .

where_clause    = "WHERE" expr .

with_measurement_clause = "WITH MEASUREMENT" ( "=" measurement | "=~" regex_lit ) .

with_tag_clause = "WITH KEY" ( "=" tag_key | "!=" tag_key | "=~" regex_lit | "IN (" tag_keys ")" ) .

Expressions

binary_op  = "+" | "-" | "*" | "/" | "%" | "&" | "|" | "^" | "AND" |
             "OR" | "=" | "!=" | "<>" | "<" | "<=" | ">" | ">=" .

expr       = unary_expr { binary_op unary_expr } .

unary_expr = "(" expr ")" | var_ref | time_lit | string_lit | int_lit |
             float_lit | bool_lit | duration_lit | regex_lit .

Other grammar elements

alias            = "AS" identifier .

back_ref         = ( policy_name ".:MEASUREMENT" ) |
                   ( db_name "." [ policy_name ] ".:MEASUREMENT" ) .

db_name          = identifier .

dimension        = expr .

dimensions       = dimension { "," dimension } .

field_key        = identifier .

field            = expr [ alias ] .

fields           = field { "," field } .

fill_option      = "null" | "none" | "previous" | int_lit | float_lit | "linear" .

host             = string_lit .

measurement      = measurement_name |
                   ( policy_name "." measurement_name ) |
                   ( db_name "." [ policy_name ] "." measurement_name ) .

measurements     = measurement { "," measurement } .

measurement_name = identifier | regex_lit .

password         = string_lit .

policy_name      = identifier .

privilege        = "ALL" [ "PRIVILEGES" ] | "READ" | "WRITE" .

query_id         = int_lit .

query_name       = identifier .

retention_policy = identifier .

retention_policy_option      = retention_policy_duration |
                               retention_policy_replication |
                               retention_policy_shard_group_duration |
                               "DEFAULT" .

retention_policy_duration    = "DURATION" duration_lit .

retention_policy_replication = "REPLICATION" int_lit .

retention_policy_shard_group_duration = "SHARD DURATION" duration_lit .

retention_policy_name = "NAME" identifier .

series_id        = int_lit .

shard_id         = int_lit .

sort_field       = field_key [ ASC | DESC ] .

sort_fields      = sort_field { "," sort_field } .

subscription_name = identifier .

tag_key          = identifier .

tag_keys         = tag_key { "," tag_key } .

user_name        = identifier .

var_ref          = measurement .

Comments

Add comments in InfluxQL statements to document your queries.

  • Single-line comment: starts with --, ends at the next line feed. Cannot span multiple lines.

  • Multi-line comment: starts with /*, ends with */. Can span multiple lines. Nested multi-line comments are not supported.

Query engine internals

Understanding how the query engine executes InfluxQL helps you write efficient queries and interpret EXPLAIN ANALYZE output.

Query lifecycle

Each InfluxQL query follows four steps:

  1. The statement is tokenized and parsed into an abstract syntax tree (AST) — the in-memory representation of the query.

  2. The AST is passed to the query executor, which routes it to the appropriate handler. Metadata queries go to the metadata service; SELECT statements execute against shards.

  3. The query engine identifies shards matching the time range in the SELECT statement, then creates an iterator for each queried field.

  4. The iterators are passed to an emitter, which releases the iterators, combines the result data points, converts simple time-based data points into complex objects, and returns them to the client.

Iterators

Iterators are the core abstraction of the query engine. Each iterator provides a simple interface for streaming data points. For example, a FloatIterator streams floating-point data points:

type FloatIterator interface {
    Next() *FloatPoint
}

Iterators are created through the IteratorCreator interface:

type IteratorCreator interface {
    CreateIterator(opt *IteratorOptions) (Iterator, error)
}

IteratorOptions specifies which fields to read, the time range, and grouping dimensions. IteratorCreator is available at the Shards, Shard, and Engine levels, allowing the engine to push down operations — for example, pre-aggregating data before COUNT() returns results.

Iterators can be composed: DistinctIterator computes distinct values within each time window from an input iterator; FillIterator generates replacement values for missing data points.

A composed example — computing the derivative of an average:

SELECT DERIVATIVE(MEAN(value), 20m) FROM cpu GROUP BY time(10m)

This produces a mean iterator (from shards), wrapped by a derivative iterator at the engine level.

Auxiliary fields

Selector functions such as FIRST(), LAST(), MIN(), and MAX() return both the selected data point and related fields from the same row.

For example:

SELECT FIRST(value), host FROM cpu GROUP BY time(1h)

This returns the value of the first data point in each hour along with the associated host. Internally, the engine uses a single value data point type and attaches host as an auxiliary field — a field carried alongside the primary value until it reaches the emitter. The emitter then splits the auxiliary fields and routes them to their respective iterators.

Built-in iterators

The query engine provides the following built-in iterator types:

IteratorPurpose
Merge iteratorMerges one or more iterators of the same type without sorting by time. Used for aggregate queries that need fast access and don't require ordering.
Sorted merge iteratorMerges and sorts data points by time. Slower than merge iterators. Used for non-aggregate queries returning raw data in time order.
Limit iteratorLimits data points per name or tag group, based on LIMIT and OFFSET clauses.
Fill iteratorGenerates replacement values for missing data points: null, none, the previous value, a specified numeric value, or linear interpolation.
Buffered iteratorReturns data points to an unread state so they can be re-read. Used for time window look-ahead operations.
Reduce iteratorApplies a reduction function to each data point in a time window, returning all results after the window closes. Used for simple aggregates like COUNT().
Reduce slice iteratorCollects all data points in a time window, then passes the full slice to a reduction function. Used for aggregates like DERIVATIVE().
Transform iteratorApplies a transform function to each input data point to produce a binary expression result.
Dedupe iteratorDeduplicates data points and returns only unique values. Resource-intensive; only suitable for small datasets such as metadata queries.

Call iterators

InfluxQL functions execute at two levels:

  • Shard level: functions like COUNT() run within each shard. A count iterator aggregates multiple per-shard count iterators into a total. These iterators are created using NewCallIterator().

  • Engine level: functions like DERIVATIVE() require all data points in a time window before computing results. These iterators cannot be pushed down to individual shards — the query engine constructs them after collecting shard output.

InfluxDB® is a trademark registered by InfluxData, which is not affiliated with, and does not endorse, TSDB for InfluxDB®.