Skip to content
SOC FluentSpeak SIEM and EDR

Filters in ElasticvsQueries in Elastic

Kibana KQL vs ES|QL

Kibana KQL and ES|QL both live in Elastic, but they do different jobs. Kibana KQL is a filter. You type it in the search bar to narrow down which events show. ES|QL is a full query language. It can filter too, but it can also count, group, sort, pick columns and work out new values. Use KQL to find events, and ES|QL to answer questions about them.

Side by side

WhatKibana KQLES|QL
What it doesFilters eventsFilters, counts, groups, sorts and reshapes results
Where you write itThe search bar in Discover, dashboards and Elastic SecurityDiscover in ES|QL mode, Elastic Security and ES|QL detection rules
What you get backThe matching eventsA table you shape yourself
How a query looksfield : value, joined with and, or and notFROM, then one step per line, each after a |
Which dataThe data view picked above the search barThe index pattern after FROM
Match a valueprocess.name : "cmd.exe"WHERE process.name == "cmd.exe"
Wildcardshost.name : dc-*WHERE host.name LIKE "dc-*"
One of several valuesprocess.name : ("cmd.exe" or "powershell.exe")WHERE process.name IN ("cmd.exe", "powershell.exe")
Count and groupNot possible, use a visualisationSTATS n = COUNT(*) BY host.name
Sort and limitNot possible, sort the table by handSORT n DESC, then LIMIT 10
Ignore caseDepends on the field. Keyword fields are case-sensitiveWrap the field in TO_LOWER()
Time rangeThe time pickerThe time picker, or WHERE @timestamp > NOW() - 24 hours

Same question, both languages

Show every PowerShell or cmd process on the domain controllers.
Kibana KQL
process.name : ("powershell.exe" or "cmd.exe")
  and host.name : dc-*
ES|QL
FROM logs-endpoint.events.process-*
| WHERE process.name IN ("powershell.exe", "cmd.exe")
    AND host.name LIKE "dc-*"
| KEEP @timestamp, host.name, user.name, process.command_line
| SORT @timestamp DESC
Which accounts had the most failed Windows logons today?
Kibana KQL
event.code : "4625"
ES|QL
FROM logs-*
| WHERE event.code == "4625"
| STATS failures = COUNT(*) BY user.name
| SORT failures DESC
| LIMIT 10

Kibana KQL can only find the events. To count them by account you’d build a visualisation, or switch to ES|QL.

What catches people out when switching

  • Kibana KQL shares a name with Microsoft’s KQL, but it’s a different language. A Sentinel query won’t run in Kibana.
  • Kibana KQL can only filter. As soon as the question asks how many, or which is the most, you need ES|QL.
  • Quotes matter in Kibana KQL. "dc-*" looks for those exact characters, so leave wildcards unquoted, like dc-*.
  • == in ES|QL is case-sensitive, so CMD.EXE won’t match cmd.exe. Wrap the field in TO_LOWER() when the case varies.
  • In ES|QL, a filter on a field that holds several values, like event.category, skips those rows and shows a warning above the results. Check the warnings when rows seem to be missing.
  • ES|QL returns 1,000 rows unless you set your own LIMIT.

Practise both on the same exercise

SOC Fluent launches with Elastic KQL and ES|QL. Every exercise works in both, so you learn when to filter and when to query.

Free to join. Students get 50% off at launch.