Skill 05 · Clickhouse Js Node Coding
Subchapter 5.9
reference/ping.mdMarkdown5 KBView on GitHub
Applies to: all versions.
ping()returns a discriminated unionPingResult = { success: true } | { success: false, error: Error }— it does not throw on connection failures.
When answering “how do I health-check / readiness-probe ClickHouse?”:
await client.ping() (or ping({ select: true })) and branch on
result.success directly — do not wrap in try/catch as the only
check, and do not substitute query('SELECT 1').client.ping({ select: true }) so credentials and the query layer are
validated, not just the socket.client.ping() hits /ping (TCP/HTTP
reachability only — does not validate credentials or query processing);
client.ping({ select: true }) issues a lightweight SELECT 1 (validates
auth and query path). Name both and say which to use for liveness vs
readiness.request_timeout on the client used for probes so
they fail fast instead of hanging on the default timeout — pick a value
comparable to the probe interval (e.g., 1500–2000 ms for a
2-second-interval probe).import { createClient } from "@clickhouse/client";
const client = createClient({
url: process.env.CLICKHOUSE_URL,
password: process.env.CLICKHOUSE_PASSWORD,
});
const pingResult = await client.ping();
if (pingResult.success) {
console.info("ClickHouse is reachable");
} else {
console.error("Ping failed:", pingResult.error);
}
await client.close();Use ping() to:
/healthz / readiness endpoint.ping() does not throw — it resolves with
{ success: false, error: Error }, so you can branch without try/catch:
import type { PingResult } from "@clickhouse/client";
import { createClient } from "@clickhouse/client";
const client = createClient({
url: "http://localhost:8100", // non-existing host
request_timeout: 50, // keep failure fast
});
const pingResult = await client.ping();
if (hasConnectionRefusedError(pingResult)) {
console.info("Connection refused, as expected");
} else {
console.error("Ping expected ECONNREFUSED, got:", pingResult);
}
await client.close();
function hasConnectionRefusedError(
pingResult: PingResult,
): pingResult is PingResult & { error: { code: "ECONNREFUSED" } } {
return (
!pingResult.success &&
"code" in pingResult.error &&
pingResult.error.code === "ECONNREFUSED"
);
}app.get("/healthz", async (_req, res) => {
const r = await client.ping();
if (r.success) {
res.status(200).json({ ok: true });
} else {
res.status(503).json({ ok: false, error: String(r.error) });
}
});The default ping() hits ClickHouse’s /ping HTTP endpoint — it verifies
network connectivity but does not check credentials or query processing.
A server that is reachable but has a bad password (or a broken query
pipeline) will still return { success: true } from a plain ping().
Pass { select: true } to run a lightweight SELECT 1 instead:
const r = await client.ping({ select: true });
// success only if the server is reachable AND auth is correct AND it can run queriesclient.ping() | client.ping({ select: true }) | |
|---|---|---|
| Endpoint | /ping (HTTP) | SELECT 1 query |
| Checks auth | No | Yes |
| Checks query processing | No | Yes |
| Overhead | Minimal | Slightly higher |
When to use which:
ping() is fine.ping({ select: true })
so the probe fails if credentials are wrong or the query layer is broken.ping() is enough.ping() in try/catch as your only check. It resolves on
failure; the success boolean is the source of truth.request_timeout if you want pings to fail fast (the example
above uses 50 ms). The default is high enough to be unsuitable for
liveness probes.ping() does not check credentials. If auth is part of what you
want to verify, use ping({ select: true }).