Cybersecurity & Information Security

EQL vs ES|QL: When to use each language in security investigations

6 min readPublished: August 5, 2026
Professional visual illustration of EQL vs ES|QL in SIEM and detection
Quick answer

EQL is suitable when the order of events and their relationships are at the heart of the question: A Process started, then communication was established, or an expected event did not appear. ES|QL is suitable when a Pipeline of filtering, calculation, field modification, Aggregation, and Statistics is needed. If a single field match is sufficient, a simple Custom query might be easier than both.

Elastic offers several Query languages because security questions are not identical. Sometimes you want to find a single Event. Sometimes you want a chronological sequence. Sometimes you want to summarize thousands of Events into a table showing Count, Distinct users, or a computed field. EQL and ES|QL overlap in some capabilities, but were built around different models.

EQL — Event Query Language — focuses on event-based data and temporal relationships. ES|QL — Elasticsearch Query Language — uses a Pipeline that starts with FROM and passes a table through commands like WHERE, EVAL, and STATS. The choice should start with the investigative question, not the language name.

What EQL solves

EQL is particularly suitable for time-ordered sequences. A Rule can search for a Process start followed by a Network event from the same process.entity_id. Events can be linked by a shared field using by, define Timestamp, Event category, and Tiebreaker, and even search for Missing events in certain scenarios.

The advantage is that the logic reflects a story: phase A occurred before phase B. Instead of summarizing two types of Events in the same window and assuming they are related, EQL checks the order and the linking Key. Therefore, it is useful for Process chains, Authentication sequences, File then Process, or an Event that is expected to arrive but does not.

sequence by process.entity_id
  [process where event.type == "start" and process.name == "lab-tool.exe"]
  [network where event.type == "connection" and network.direction == "egress"]
sequence by process.entity_id [process where event.type == "start" and process.name : "lab-tool.exe"] [network where event.type == "connection" and process.name : "lab-tool.exe"]

The example uses a fictitious name and lab data. It searches for a Process followed by a Network connection from the same Process entity. It does not prove maliciousness; Destination, Signer, Parent, User, and Host context should be checked.

What ES|QL solves

ES|QL operates on tables and supports Pipeline processing. You start with FROM, filter with WHERE, create fields with EVAL, summarize using STATS ... BY, sort, and display Columns. An ES|QL Detection of this type turns each Result row into an Alert.

It is suitable when the question is quantitative or requires Transformation: how many Hosts executed a certain tool, which Users generated an abnormal volume, what is the ratio between Success and Failure, or which computed field crosses a Threshold. It is not the natural choice when the order of Event A then B is paramount; Elastic recommends using EQL for ordered sequences.

FROM logs-endpoint.events.*
| WHERE event.category == "process" AND event.type == "start"
| WHERE process.name == "lab-tool.exe"
| STATS executions = COUNT(*), hosts = COUNT_DISTINCT(host.id) BY user.name
| WHERE executions >= 5
FROM logs-endpoint.events.process-* | WHERE process.name : "lab-tool.exe" | STATS process_count = COUNT() BY user.name, host.id | WHERE process_count > 5 | SORT process_count DESC

This Query summarizes executions by user and filters Users with five or more executions. It answers a different question from EQL: “Who executed the tool how many times and on how many Hosts?”, not “Did a specific Process create a Connection afterwards?”

Sequence vs Pipeline

FeatureEQLES|QL
ModelEvents and temporal sequencesTable undergoing a Pipeline
Primary useOrdered sequence, missing event, event correlationAggregation, transformation, computed fields
Linkingby on a shared field throughout the SequenceSTATS BY and table fields; capabilities vary by version
Basic dataTimestamp, event.category, and linking fieldsIndices and fields required for FROM and commands
Detection outputEvent or Sequence creates an AlertEach Row in the result creates an Alert
Typical caseProcess then Network connectionCount by User/Host and Threshold filtering

The same scenario in two approaches

Suppose the general scenario is a lab tool named lab-tool.exe that may operate in an unusual context. First, define the precise question:

  • EQL question: Did a specific Instance of the tool start and then create a Network connection?
  • ES|QL question: Which users or Hosts ran the tool with unusual frequency?
  • Custom query question: Was the tool run at all with an unexpected Parent?

The three questions can support the same Use Case, but they are not equivalent. EQL provides chronological context. ES|QL provides a Baseline or Aggregation. A Custom query provides a direct match. A good Detection architecture may use several Rules, but duplications should be avoided, and what each Rule adds should be defined.

Data requirements

EQL requires a reliable Timestamp and Event category. Sequences benefit from a Tiebreaker when Events share the same time. The linking field should be stable: process.entity_id is generally preferred over process.name, because several Processes can share a name. If entity_id is missing or changes between Sources, the Sequence will not work as expected.

ES|QL requires that Indices are accessible and fields match the commands. Aggregation on a text type Field instead of keyword, Null values, or inconsistent Schema can change Results. In a Detection Rule, Deduplication of Alerts, Schedule, and Lookback should be considered. Certain capabilities and Metadata requirements vary between Elastic versions, so the version documentation should be checked.

Advantages and limitations

EQL advantages

  • Expresses Event order readably.
  • Links steps by a shared Entity.
  • Suitable for Process lineage and behavioral sequences.
  • Can express the absence of an expected Event in supported scenarios.

EQL limitations

  • Not the natural tool for complex Aggregation and Statistics.
  • Highly dependent on Timestamp, event.category, and a stable Key.
  • Too broad a Sequence can be expensive or noisy.

ES|QL advantages

  • Clear Pipeline for filtering, calculation, and Aggregation.
  • Creation of derived fields using EVAL.
  • STATS ... BY enables Detection on aggregated values.
  • Suitable for Hunting and tabular reports.

ES|QL limitations

  • Does not replace EQL when Event order is the central requirement.
  • Each Row becomes an Alert, so the Grain of the result must be planned.
  • Aggregation can lose Raw event context if the Investigation Guide does not provide Drill-down.

Selection matrix

The questionFirst choiceNote
Single Event by field conditionsCustom queryThe simpler solution is often better
Process then Network by the same entityEQLSequence and temporal order
More than N Events by UserThreshold or ES|QLDepending on the need for Transformation
Calculate Ratio or derived fieldES|QLEVAL and STATS
IOC vs EventsIndicator matchDo not build a manual Join if a dedicated Rule type is suitable
New value not seen beforeNew termsIntended for First seen
Anomaly without rigid PatternMachine learningRequires Job and Baseline

Lab exercise

  1. Create five fictitious Process events and two Network events with process.entity_id.
  2. Write an EQL that returns a Sequence only when Network follows Process on the same entity.
  3. Write an ES|QL that summarizes the number of executions by user.name and host.id.
  4. Change the Timestamp of one Event and check what happens to the sequence.
  5. Remove process.entity_id from an event and check how data quality affects it.
  6. For each Query, write a sentence: what it proves, what it does not prove, and what Drill-down is required.

Common mistakes

  • Using ES|QL to mimic a complex Sequence when EQL is suitable.
  • Using EQL for a simple Count question.
  • Linking by process.name instead of a stable Entity.
  • Ignoring Time zone, Ingestion delay, and Tiebreaker.
  • Turning Aggregation into an Alert row without fields that allow investigation.
  • Copying a Query from another version without checking Syntax and Metadata requirements.

Summary and CTA

Before writing a Query, write the question on paper: Am I looking for an Event, Sequence, Count, Transformation, IOC, or Anomaly? The choice of language almost stems from the answer. In HPI practice, it is recommended to keep the same Telemetry and run EQL and ES|QL on it, to see how the question model changes the investigation result.

FAQ

Does ES|QL replace EQL?

No. ES|QL is strong in Pipeline, Aggregation, and Transformation; EQL is designed for sequences and temporal relationships. Elastic continues to present them as different Rule types.

Can EQL search for a single Event?

Yes, but if it is a simple field match, a Custom query might be easier to maintain.

What happens if two Events share a Timestamp?

EQL can use a Tiebreaker field to determine deterministic order. Ensure the field exists and is reliable.

Does each Row in ES|QL create an Alert?

In an ES|QL Detection Rule, each Row in the Query result becomes an Alert, so it is important to choose the correct Grain and use Suppression where appropriate.

Can both languages be used for the same Use Case?

Yes, if each Rule answers a different question and adds coverage. Overlap should be documented, and duplicate Alerts prevented.

Want to check if this track is right for you?

Leave your details and an HPI advisor will get back to you for a short, no-obligation fit call.

Your details are stored securely.

For SOC and cyber studies within the Cybersecurity & AI program

Want to hear the details? Leave your info and we'll get back to you.

Related articles