﻿---
title: Event correlation (EQL) rules
description: Create detection rules using Event Query Language (EQL) to detect event sequences and correlations.
url: https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/detect-and-alert/eql
products:
  - Elastic Cloud Serverless
  - Elastic Security
applies_to:
  - Serverless Security projects: Generally available
  - Elastic Stack: Generally available
---

# Event correlation (EQL) rules
Event correlation rules use [Event Query Language (EQL)](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/reference/query-languages/eql/eql-syntax) to detect ordered sequences of events, single events with complex conditions, or the absence of expected events. EQL is purpose-built for event-based data and excels at expressing time-ordered relationships that other query languages cannot.

### When to use an EQL rule

EQL rules are the right fit when:
- You need to detect a **sequence** of events that must occur in a specific order, such as a process creation followed by a network connection from the same process.
- You want to detect **missing events** in a sequence, for example, a login that is never followed by a logout within a time window.
- The detection logic involves correlating events by a **shared field** (such as `process.entity_id` or `host.id`) across time.
- You need richer event-level logic than KQL allows, such as filtering by event category within a sequence step.

EQL rules are **not** the best fit when:
- A single-event match is sufficient. Use a [custom query rule](https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/detect-and-alert/custom-query) instead.
- You need to count how often something happens. Use a [threshold rule](https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/detect-and-alert/threshold) instead.
- You need aggregation, transformations, or pipe-based processing. Use an [ES|QL rule](https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/detect-and-alert/esql) instead.


### Data requirements

EQL rules require at least one Elasticsearch index pattern or [data view](https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/get-started/data-views-elastic-security). The indexed data must include a timestamp field (defaults to `@timestamp`) and an event category field (defaults to `event.category`). Sequence queries also benefit from a tiebreaker field to resolve events that share the same timestamp.

## Annotated examples

The following examples use the [detections API](https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/detect-and-alert/using-the-api) request format to show how EQL rules are defined. Each example is followed by a breakdown of the EQL-specific fields. For common fields like `name`, `severity`, and `interval`, refer to the [detections API documentation](https://www.elastic.co/docs/api/doc/kibana/group/endpoint-detection-engine-rules-api).

### Sequence query with shared field

This rule detects when `msxsl.exe` starts and then makes an outbound network connection from the same process instance, a known living-off-the-land binary (LOLBin) technique.
```json
{
  "type": "eql",
  "language": "eql",
  "name": "MSXSL network connection after process start",
  "description": "Detects msxsl.exe starting and making an outbound network connection.",
  "query": "sequence by process.entity_id [process where event.type == \"start\" and process.name == \"msxsl.exe\"] [network where event.type == \"connection\" and network.direction == \"egress\"]",
  "index": ["winlogbeat-*", "logs-endpoint.events.*"],
  "severity": "high",
  "risk_score": 73,
  "interval": "5m",
  "from": "now-6m"
}
```


| Field               | Value                                                                   | Purpose                                                                                                                                                                                                                                                        |
|---------------------|-------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type` / `language` | `"eql"` / `"eql"`                                                       | Both must be `"eql"`. Unlike custom query rules, the `language` field is fixed and not interchangeable.                                                                                                                                                        |
| `query`             | `sequence by process.entity_id [process where ...] [network where ...]` | A two-step sequence. The `by process.entity_id` clause ensures both events came from the same process instance. The first bracket matches a process-start event for `msxsl.exe`, and the second matches an outbound network connection from that same process. |
| `index`             | `["winlogbeat-*", "logs-endpoint.events.*"]`                            | Covers Winlogbeat and Elastic Defend indices. Both must contain process and network events for the sequence to match.                                                                                                                                          |


### Single-event query with EQL settings

This rule detects `certutil.exe` being used to download files and demonstrates the EQL-specific settings fields.
```json
{
  "type": "eql",
  "language": "eql",
  "name": "File download via certutil",
  "description": "Detects certutil.exe being used to download files, a common LOLBin technique.",
  "query": "process where event.type == \"start\" and process.name == \"certutil.exe\" and process.args : \"-urlcache\"",
  "index": ["winlogbeat-*", "logs-endpoint.events.*"],
  "event_category_override": "event.category",
  "tiebreaker_field": "event.sequence",
  "timestamp_field": "@timestamp",
  "severity": "medium",
  "risk_score": 47,
  "interval": "5m",
  "from": "now-6m"
}
```


| Field                     | Value                                                                        | Purpose                                                                                                                                                                                 |
|---------------------------|------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `query`                   | `process where event.type == "start" and ... and process.args : "-urlcache"` | A single-event EQL query. The `:` operator performs a wildcard match on `process.args`, unlike the strict `==` equality used for other fields.                                          |
| `event_category_override` | `"event.category"`                                                           | Specifies which field contains the event classification (such as `process`, `file`, `network`). Defaults to `event.category`. Override this when your data uses a different field name. |
| `tiebreaker_field`        | `"event.sequence"`                                                           | A secondary sort field for events that share the same timestamp. Ensures deterministic event ordering in sequence queries.                                                              |
| `timestamp_field`         | `"@timestamp"`                                                               | The field used for ordering events in sequences. Defaults to `@timestamp`. Different from the `timestamp_override` advanced setting, which controls the query time range.               |


## EQL rule field reference

The following settings appear in the **Define rule** section when creating an EQL rule. For settings shared across all rule types, refer to [Rule settings reference](https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/detect-and-alert/common-rule-settings).
<definitions>
  <definition term="Index patterns or data view">
    The Elasticsearch indices or data view the rule searches when querying for events.
  </definition>
  <definition term="EQL query">
    The [EQL query](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/reference/query-languages/eql/eql-syntax) that defines the detection logic. Can be a single-event query, a sequence, or a sequence with missing events. Documents or sequences matching this query generate alerts.
  </definition>
  <definition term="EQL settings (optional)">
    Additional fields used by [EQL search](/elastic/docs-builder/docs/3028/explore-analyze/query-filter/languages/eql#specify-a-timestamp-or-event-category-field):
    - **Event category field**: The field containing event classification (such as `process`, `file`, or `network`). Typically a [keyword family](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/reference/elasticsearch/mapping-reference/keyword) field. Defaults to `event.category`.
    - **Tiebreaker field**: A secondary field for sorting events in ascending, lexicographic order when they share the same timestamp.
    - **Timestamp field**: The field containing the event timestamp, used for ordering sequence events. Defaults to `@timestamp`. This is different from the **Timestamp override** advanced setting, which controls the query time range.
  </definition>
  <definition term="Suppress alerts by (optional)">
    Reduce repeated or duplicate alerts by grouping them on one or more fields. For details, refer to [Alert suppression](https://www.elastic.co/elastic/docs-builder/docs/3028/solutions/security/detect-and-alert/alert-suppression).
  </definition>
</definitions>