Type to search.

Threshold queries in Kibana Universal Alerting

Serverless

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Serverless interfaces and procedures might differ from classic Elastic Stack deployments.

Stack Planned

The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats.

Availability

  • Planned

    We plan to add this functionality in a future Elastic Stack update. Subject to changes.

Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments.

This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.

A threshold query in a Kibana Universal Alerting rule aggregates your data first, then applies an alert condition to the result. Use this pattern when a single matching event isn't enough to warrant an alert. You want to know whether a metric (count, rate, average) has crossed a limit over a time window.

Threshold queries come in two variants. A single-series threshold produces one result for all your data, and a grouped threshold tracks each subject (host, service, user) independently.

This query counts HTTP 5xx responses across all services combined and alerts when the overall error rate exceeds 10% over the lookback window.

ES|QL
FROM logs-*
| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend
| STATS
    error_count = COUNT_IF(http.response.status_code >= 500),
    total_count = COUNT(*)
| EVAL error_rate = error_count / total_count
| WHERE error_rate > 0.10
| KEEP error_rate, error_count, total_count
  1. Scope to the rule's configured lookback window
  2. Count only error responses
  3. Count all requests for the denominator
  4. Compute error rate as a fraction (0–1)
  5. Alert condition: An overall error rate above 10% is a breach

One window, one aggregate across all the data, one threshold check. The result is either a single breach or no breach.

Adding BY to the STATS command splits the result into one row per unique field value. Each row is evaluated independently against the alert condition, and each breach creates its own alert series.

This query tracks average CPU usage per host and alerts when any host exceeds 90%:

ES|QL
FROM metrics-*
| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend
| STATS avg_cpu = AVG(system.cpu.total.pct) BY host.name
| WHERE avg_cpu > 0.90
| KEEP host.name, avg_cpu
  1. One result row per host
  2. Each host above the threshold is a breach

Without the BY host.name clause, the query would produce a single average across all hosts combined. A cluster-wide spike might push the average above the threshold even if no single host is the problem. Grouping by host gives each host its own alert with its own lifecycle. If host A recovers but host B stays critical, those are tracked separately.

The BY fields you use here must match the grouping configuration in the rule. Refer to Rule grouping for how to align them.

If both of these patterns don't fit your use case, the next pages cover more specific detection problems: