Skip to main content
Metrics type: Key MetricsCategory: Nerve Centre

At a glance

The alert feed for moments when the ClickHouse connection pool runs hot: concurrent connections sit above 90% of the configured max_connections ceiling for a sustained minute. When the pool saturates, new client connections are refused (you see Too many simultaneous queries or connection timeouts), so dashboards stall and ingest jobs back up. This card lists each saturation event with its start time, peak utilisation, and duration, so the on-call DBA can see whether the cause was a query storm, a connection leak, or genuine capacity demand.

Calculation

The detector computes pool utilisation as live concurrent connections over the configured ceiling:
The connection gauges come from system.metrics:
and the ceiling from the server configuration:
An alert row is created when saturation_pct > 90 holds continuously for 60 seconds. The “sustained 1 minute” gate is deliberate: connection counts are spiky by nature (every client connect/disconnect moves the gauge), and a momentary touch of 91% is not an incident. A full minute above the line means the pool is genuinely starved of headroom, not just briefly busy. Each row records the start time, the peak utilisation reached, and the duration until utilisation fell back below 90%.

Worked example

A platform team runs a ClickHouse instance with max_connections = 1000 serving both an ingest pipeline and a fleet of BI dashboards. Snapshot of the alert feed on 22 Apr 26. The Nerve Centre headline reads 1 active saturation alert, peak 97%, outlined red. The DBA reads the feed:
  1. The 08:31 event is a recurring pattern. It lands every weekday at the same minute. This is the classic “everyone opens their dashboard at the start of the day” storm: dozens of BI panels each opening a connection simultaneously. It self-resolves in minutes but each occurrence risks refused connections at the peak.
  2. The 19 Apr event is the dangerous one. It ran for 11.5 minutes and peaked at 99%. A duration that long with no obvious traffic trigger points to a connection leak: a service opening connections and not closing them. Left unchecked, the next one hits 100% and starts refusing connections.
  3. None of these show up in query latency. A refused connection never becomes a query, so Query Latency p95 (ms) can look perfectly healthy while clients are being turned away. This card is the only place the impact is visible.
For the recurring 08:31 storm the fix is on the client side: stagger dashboard auto-refresh schedules or put a connection pool in front of the BI tools so panels share connections instead of each opening their own. Raising max_connections adds headroom but does not stop a genuine leak from eventually exhausting any ceiling. Three takeaways:
  1. Saturation is invisible in query metrics. Refused connections never become queries, so latency and error-rate cards can look green while clients are locked out. Trust this card as the canonical view of pool starvation.
  2. Duration distinguishes traffic from leaks. A short spike at a predictable time is a refresh storm; a long, slowly climbing event with no traffic trigger is a leak. Read the duration column, not just the peak.
  3. Headroom is the real metric. A pool living at 88% is one burst away from refusing connections. Pair this alert with Connection Pool Saturation % and keep steady-state utilisation well below 70%.

Sibling cards

Reconciling against the source

Where to look in ClickHouse’s own tooling:
Check live connection counts against the ceiling in clickhouse-client:
See who is connected and what they are running in system.processes (one row per active query/connection), grouped by client_name or user to find a leak. On ClickHouse Cloud, max_connections is managed per service tier; the same system.metrics query works in the SQL console, and the managed monitoring view shows connection utilisation over time.
Why our number may legitimately differ from a manual check: Cross-connector reconciliation:

Known limitations / FAQs

My query latency looks fine but this card is red. How can both be true? Easily, and it is the most important thing to understand about pool saturation. When the pool is full, ClickHouse refuses new connections before any query runs. Those refused clients never produce a query, so they never appear in latency or query-error metrics. The queries that did get in run normally. So latency stays green while a portion of your clients are locked out entirely. This card is the only place the lockout is visible. Why does it need a full minute above 90%? I want to catch every spike. Connection counts are inherently spiky: every client connect and disconnect moves the gauge, and a healthy server touches high utilisation briefly all the time. Firing on every momentary spike would bury you in noise. The one-minute sustain gate means the pool was genuinely starved of headroom, not just briefly busy. If you need a finer alert threshold, it is configurable in the Alert Rules tab. Should I just raise max_connections to make the alerts stop? Only as a stopgap. Raising the ceiling adds headroom and will silence storm-driven alerts, but it does nothing for a connection leak: a leaking client will eventually exhaust any ceiling, just more slowly. Diagnose first. If system.processes shows one client holding hundreds of idle connections, fix the client’s pooling or set an idle timeout. If it is genuine concurrent demand, then raising the ceiling (and the underlying instance size) is the right call. What is the difference between this and Connection Pool Saturation %? Connection Pool Saturation % is the live gauge: where utilisation sits right now. This card is the incident log: the list of times utilisation crossed 90% and stayed there. Use the gauge for current state and this card for history and root-cause timing. Does this count connections from all protocols? Yes. The detector sums the native TCP protocol plus HTTP, and the MySQL and PostgreSQL wire-protocol gauges if those interfaces are enabled. They all draw from the same max_connections ceiling, so counting only one protocol would understate true saturation. On ClickHouse Cloud I do not set max_connections myself. Does this still apply? Yes. ClickHouse Cloud sets max_connections per service tier, and you can still saturate it with too many concurrent clients or a leak. The card reads the live limit and live connection counts the same way, and the same diagnosis (find the offending client in system.processes, fix pooling, or scale the service) applies.

Tracked live in Vortex IQ Nerve Centre

Connection Pool at >90% Saturation is one of hundreds of KPI pulses Vortex IQ tracks across ClickHouse and 70+ other ecommerce connectors. Nerve Centre runs the detection layer; Vortex Mind investigates the cause when something moves; Ask Viq lets you interrogate any number in plain English. Start for free or book a demo to see this metric running on your own data.