At a glance
Query Latency p95 (ms) is the 95th-percentile read latency for the MongoDB deployment over a rolling 5-minute window: 95% of reads finish faster than this number, and the slowest 5% finish slower. For a platform team this is the honest “tail” reading. The p50 (median) hides the slow queries; the p95 is where users actually start to feel pain. When p95 crosses 200ms the card alerts, because at that point a meaningful slice of application requests are waiting long enough to degrade page loads, API responses, or checkout calls that sit on top of the database.
Calculation
MongoDB does not expose a true streaming percentile inserverStatus; it exposes cumulative counters. The card works from latencies.reads (the opLatencies.reads document), which carries a running total latency (in microseconds) and a running count ops. Two things happen:
- Windowing. The engine samples the counters at the start and end of each 5-minute window and takes the delta:
(latency_end - latency_start)over(ops_end - ops_start). This yields the average read latency for that window only, stripping out the long-running cumulative average since process start. - Percentile estimation. Where the deployment exposes the latency histogram (
opLatencieswithhistogram: true, available on modern builds and surfaced natively on Atlas), the engine reads the 95th-percentile bucket directly. Where only the scalar counters are available, the card reports the windowed mean as a conservative proxy and flags the reading as an average rather than a true percentile.
Worked example
A platform team runs a 3-node replica set (1 primary, 2 secondaries) backing the product and session services for a high-traffic storefront. Snapshot taken on 14 Apr 26 at 20:15 BST, during an evening traffic peak.
The p50 has only drifted from 3ms to 9ms, which on its own looks benign. The p95, though, has gone from 41ms to 263ms, a 6x blow-out. That divergence is the diagnostic signal: the typical read is still fast, but the slowest 5% are now taking a quarter of a second. The cause here is the working set spilling out of the WiredTiger cache as traffic climbed, so a growing fraction of reads have to fetch pages from disk.
- Read p95 against p50, not in isolation. A high p95 with a low p50 is a tail problem (specific slow queries); a high p95 with a high p50 is a systemic problem (capacity). The remedy is different.
- 200ms is a database-layer threshold, not an end-user one. By the time a slow MongoDB read reaches the user it has accumulated application, network, and rendering time on top. A 250ms database p95 can easily become a 1s+ page.
- The tail moves before the median. p95 is an early-warning line. If you wait for p50 to climb you have already let the deployment degrade for everyone, not just the unlucky 5%.
Sibling cards
Reconciling against the source
Where to look in MongoDB’s own tooling:RunWhy our number may legitimately differ from MongoDB’s native view:db.serverStatus().opLatencies.readsinmongoshto read the cumulativelatency(microseconds) andopscounters; the windowed average is(latency2 - latency1) / (ops2 - ops1) / 1000between two samples. Usemongostatfor a live, low-overhead per-second view of operation rates and latency trends. On MongoDB Atlas, the Metrics tab exposes “Read Latency” with native p50 / p95 / p99 percentile lines per node; pick the primary (or the node serving the workload) and match the 5-minute window. Enable the database profiler (db.setProfilingLevel(1, { slowms: 100 })) and querysystem.profileto see the individual slow reads that are inflating the percentile.
Cross-connector reconciliation: pair with MongoDB Pool Saturation vs Traffic Burst and Slow Ops During Checkout Window (5m) to tie a latency tail to the revenue-bearing path. For divergence investigations, use Vortex Mind.
Known limitations / FAQs
Why does this card track reads only, not writes? Read tail latency is the most common cause of user-visible slowness, because the read path sits directly under page loads and API calls. Write latency is tracked separately. If your workload is write-heavy (event ingestion, logging), watch the write and command latency surfaces alongside this card rather than treating p95 reads as the whole story. My p50 is fine but p95 alerted. Is that a false alarm? No, that is exactly the signal this card exists to catch. A healthy median with a blown-out 95th percentile means a specific subset of queries is slow (missing index, COLLSCAN, a hot document, or cache misses) while most queries stay fast. Use Slow Ops (15m, >100ms) to find which queries, then add an index or fix the query plan. The card says “average” not “percentile” for my deployment. Why? Older or minimally configured deployments expose only the scalaropLatencies counters, not the latency histogram needed for a true percentile. In that mode the card reports a windowed mean as a conservative proxy and labels it accordingly. To get a real p95, run a modern MongoDB build with operation-latency histograms enabled, or read the percentile directly from the Atlas Metrics view.
Should I alert at 200ms for my workload too?
200ms is a sensible default for an interactive OLTP workload sitting under a storefront. Analytical or batch workloads tolerate far higher latency, and ultra-low-latency caches expect single-digit milliseconds. The alert threshold is configurable per profile in the Alert Rules tab; set it to your own baseline rather than the generic default.
p95 spiked but ops/sec did not change. What happened?
A latency rise with flat throughput is a regression, not a capacity issue. The usual causes are a deploy that changed a query plan, an index that was dropped or not yet built, a COLLSCAN entering a hot path, or a background operation (compaction, index build, balancer migration) competing for I/O. Check COLLSCAN Operations (24h) and recent deploy timing first.
Does reading from secondaries affect this number?
It can. The card reads the node the connector targets. If your application uses a secondaryPreferred read preference, the latency your users experience is a blend across nodes, which a single-node reading will not capture. Point the connector at the node (or nodes) actually serving the read workload, and cross-check the per-node Atlas percentiles.