At a glance
Search Latency p95 (ms) is the time below which 95% of search queries complete: only the slowest 5% take longer. This is the storefront-facing number that matters most to real users. The median (p50) can look healthy while p95 is quietly miserable, and it is the p95 experience that shows up as a sluggish search box on a category page. For a storefront backed by Elasticsearch, p95 is directly user-impacting, which is why it carries a hard 200ms alert.
Calculation
Elasticsearch exposes two monotonic counters per node in the search index stats:query_total (the number of query-phase operations completed) and query_time_in_millis (the cumulative milliseconds spent in the query phase). On their own these give only a lifetime average. Vortex IQ samples the counters on each poll, takes the delta between consecutive samples, and aggregates the per-shard service times into a distribution across the rolling 5-minute window. The 95th percentile is read from that distribution and reported as the card value in milliseconds.
Because the figure is a percentile and not a counter ratio, it is robust to a few very slow queries skewing a window average, and it captures the experience of the unlucky tail. The value is cluster-wide by default: it blends every searchable index. Where a connector is scoped to a specific index pattern (for example the product catalogue index that powers storefront search), the distribution is built only from those shards, which is the reading most ops teams want because it isolates the customer-facing path from background analytics queries.
Worked example
A platform team runs a 6-node Elasticsearch cluster behind a high-traffic storefront. The product-search index has 3 primary shards and 1 replica each. Snapshot taken on 14 Apr 26 at 19:40 BST during the evening traffic peak.
The p95 card has crossed its 200ms threshold and is outlined as a breach. The median is fine at 38ms, so this is not a broad slowdown: the typical query is fast, but the slow tail has widened. The team reads three things at once:
- The breach is in the tail, not the bulk. p50 at 38ms against p95 at 264ms is a 7x spread. That pattern points at a subset of expensive queries, not at an undersized cluster. Likely culprits: deep pagination (
from+sizereaching into the thousands), unbounded wildcard or leading-wildcard terms, or a heavy aggregation riding on the same index. - It co-occurs with the peak. The breach started at 19:25 as traffic climbed. Pairing with Search Queries per Second (live) shows QPS up 40% over the afternoon baseline, so the tail is partly load-driven. The search thread pool is queueing.
- Heap is warm but not critical. JVM Heap Used % reads 71%, just below the 75% GC-pressure line. Garbage-collection pauses are starting to nibble at the tail.
search_after. The takeaway: p95 is the number that tells you customers are feeling it, well before any error card lights up.
Sibling cards
Reconciling against the source
Where to look in Elasticsearch’s own tooling:Why our number may legitimately differ:GET /_nodes/stats/indices/searchfor the rawquery_totalandquery_time_in_milliscounters per node; the lifetime ratio isquery_time_in_millis / query_total.GET /<index>/_stats/searchfor the same counters scoped to a single index pattern. Kibana Stack Monitoring → Overview → Search for the latency chart over time, and the search-slowlog (configured viaindex.search.slowlog.threshold.query.warn) for the actual slow queries. On Elastic Cloud or AWS OpenSearch Service, the search-latency series appears in the cluster’s monitoring dashboard.
Cross-connector reconciliation:
Known limitations / FAQs
My users complain search is slow but p95 reads 90ms. Why? p95 measures only the query phase service time on the data nodes. The user’s experience also includes browser-to-app network latency, application-tier query construction, the fetch phase for large result payloads, and any front-end rendering. If p95 is healthy but users are not, look upstream of Elasticsearch, or check Search Latency p99 (ms) in case the specific users hitting trouble are in the worst 1%. Why 200ms as the threshold and not something lower? 200ms is the point at which a noticeable share of shoppers begin to perceive the search box as laggy on a storefront. It is a sensible default, not a law. The threshold is configurable per profile in the Alert Rules tab; a latency-sensitive catalogue may want 150ms, a complex faceted search may tolerate 300ms. p95 spiked for one window then recovered. Should I worry? A single 5-minute spike that self-recovers is often a segment merge, a brief GC pause, or a one-off heavy aggregation. Worry when the breach is sustained across several windows, or when it recurs at the same time each day (a scheduled job or a daily traffic pattern). Pair with GC Pause Time (5m total ms) to rule out garbage collection. Does p95 include aggregation queries? By default the card blends all query-phase operations on the in-scope indices, which includes aggregations. Heavy aggregations are a common tail driver. If you want to isolate plain search from analytics, scope the connector to the storefront index pattern only. How is the percentile calculated if Elasticsearch only exposes counters? Elasticsearch node stats give cumulativequery_total and query_time_in_millis, which alone yield only an average. Vortex IQ samples per-shard deltas across the 5-minute window and reconstructs a distribution, then reads the 95th percentile from it. This is why the card value can sit above the simple counter ratio you would compute by hand.
Can a healthy p50 hide a bad p95?
Yes, and that is exactly why p95 is a Key Metric card. A median of 35ms with a p95 of 280ms means most queries are fine but the slow tail is wide enough to hurt conversion. Always read p50 and p95 together; the gap between them is the diagnostic.