Kibana Query Language (KQL): Syntax, Examples, and Lucene Comparison

Kibana Query Language (KQL) is the default search syntax used across Kibana's Discover, dashboards, and alerts to filter data in Elasticsearch. KQL is simpler than the Lucene query syntax it replaced, parses on the Kibana side, and translates to Elasticsearch DSL behind the scenes. It supports field-scoped queries, boolean operators, wildcards, ranges, and existence checks. KQL is case-insensitive on identifiers (operators, field names) but otherwise treats values exactly as you write them.

Quick Comparison: KQL vs Lucene Query Syntax

Feature KQL Lucene
Field syntax field : value field:value
Free text Searches the default field Searches the default field
Boolean operators and, or, not (case-insensitive) AND, OR, NOT (must be uppercase)
Wildcards * only (no ?) * and ?
Regex Not supported /pattern/
Fuzzy match Not supported term~ or term~N
Proximity Not supported "phrase"~N
Ranges field > 10 and field < 100 or field : { gte: 10, lt: 100 } field:[10 TO 100}
Nested fields First-class (user.name) Works via dotted notation
Existence field : * _exists_:field
Negation not field : value -field:value or NOT field:value

In Kibana, toggle between KQL and Lucene via the gear icon next to the search bar. KQL is the default since Kibana 7.0. Use Lucene only when you specifically need regex, fuzzy match, or proximity search.

KQL Syntax

Free-Text Search

Searches the default field configured on the data view:

error

Field-Scoped Search

status : "error"
service.name : "checkout"

Whitespace around the colon is optional but conventional. Field values with spaces or special characters need quotes: host : "web-01.prod".

Boolean Operators

status : "error" and user : "admin"
status : "error" or status : "warning"
not status : "success"

Operators are case-insensitive (and, AND, And all work). Parentheses group expressions:

(status : "error" or status : "warning") and user : "admin"

Wildcards

KQL supports * (zero or more characters) but not ? (single character):

user : john*
service.name : *checkout*
host : web-*-prod

Leading wildcards (*name) are allowed but slow because they prevent Elasticsearch from using the inverted index efficiently.

Range Queries

age >= 30 and age < 50
response_time > 1000
@timestamp > "2025-01-01T00:00:00Z"

Comparison operators: >, >=, <, <=. KQL does not have an inclusive-exclusive range like Lucene's [a TO b}.

Existence Checks

field_name : *

The _exists_ syntax that worked in earlier Kibana versions is deprecated in KQL; use field : * instead.

Nested Fields

KQL treats nested field references natively:

products.name : "widget"

For documents indexed as nested type, use the explicit nested syntax:

products : { name : "widget" and price > 50 }

The nested form enforces that both conditions match within the same nested document, which dotted notation does not.

What KQL Cannot Do

KQL is intentionally limited. Things that require dropping to Lucene or to raw Elasticsearch DSL:

  • Regex matching. KQL has no regex; Lucene supports /pattern/.
  • Fuzzy matching. No edit-distance match.
  • Proximity search. No "phrase"~3.
  • Boosting. No term^2.5.
  • Single-character wildcard. No ? operator.
  • Span queries. Use Elasticsearch DSL.

When you need any of these, switch the search bar to Lucene mode or build a saved query / filter via the filter UI (which renders to DSL).

KQL Performance Considerations

KQL parses on the Kibana node and translates to Elasticsearch query DSL. The query that hits Elasticsearch is what matters for performance, not the KQL syntax. A few patterns to avoid:

  1. Leading wildcards (*term) force a full-term scan. They're not blocked, but they don't use the inverted index efficiently.
  2. Wildcards on high-cardinality fields (request IDs, UUIDs) blow up term-expansion cost.
  3. not against very broad sets can be expensive; prefer constraining the positive side first.
  4. Range queries on text fields are not directly supported - cast the field to a date or numeric type at index time.

Operating Kibana and Elasticsearch in Production

KQL is the entry point to data, but the cluster underneath does the work. When a Kibana dashboard times out at the default 30-second limit (see Kibana request timeout after 30000ms), the cause is almost always on the Elasticsearch side: a slow shard, JVM pressure, hot node, or query that touches too much data.

Pulse monitors Elasticsearch and OpenSearch clusters with AI-powered root-cause analysis. When a KQL-backed dashboard slows down, Pulse identifies the specific shard, node, or aggregation responsible, rather than just paging on the symptom.

Frequently Asked Questions

Q: What's the difference between KQL and Lucene in Kibana?
A: KQL is Kibana's default, simpler search syntax for filtering Elasticsearch data. Lucene is the older, more permissive query syntax that supports regex, fuzzy match, proximity search, and boosting. Switch between them via the gear icon next to the search bar. Use KQL by default; use Lucene only when you need its specialized features.

Q: Does KQL support regex?
A: No. KQL has no regex operator. For regex matching, switch to Lucene mode (/pattern/) or use a runtime field with a Painless script.

Q: Is KQL case-sensitive?
A: Operators (and, or, not) and field names are case-insensitive. Field values are passed to Elasticsearch as-is, so case sensitivity on values depends on the field's analyzer. A keyword field with no normalizer is case-sensitive; a text field with the standard analyzer is lowercased at index time.

Q: How do I search for documents missing a field in KQL?
A: Use not field : *. KQL deprecated the _exists_ operator; field : * checks for existence, and not field : * checks for absence.

Q: Can I do fuzzy search in KQL?
A: No. KQL doesn't support fuzzy matching. Switch to Lucene syntax (term~) for edit-distance matching, or use a match query with fuzziness parameter via the filter UI.

Q: Why is my KQL wildcard query slow?
A: Leading wildcards (*term) and wildcards on high-cardinality fields (UUIDs, request IDs) prevent Elasticsearch from using the inverted index efficiently. Prefer trailing wildcards (term*), narrow the search field, and use keyword fields appropriately.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.