Clickhouse sdk patterns
Production-ready patterns for @clickhouse/client — streaming inserts, typed queries, error handling, and connection management. Use when building robust ClickHouse integrations, implementing streaming inserts or low-memory streaming reads, or establishing team coding standards. Trigger with "clickhouse SDK patterns", "clickhouse client patterns", "clickhouse best practices", "clickhouse streaming insert".From its SKILL.md
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill clickhouse-sdk-patternsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.5 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
ClickHouse SDK Patterns
Overview
Production patterns for @clickhouse/client — typed queries, streaming inserts,
error handling, and connection lifecycle management. Start from the typed query
helper below, then drill into references/implementation.md for the streaming,
batching, and lifecycle patterns.
Prerequisites
@clickhouse/clientinstalled and authenticated (seeclickhouse-install-auth)- Node.js 18+ with a
CLICKHOUSE_HOST/CLICKHOUSE_USER/CLICKHOUSE_PASSWORDenv set - Familiarity with async/await and Node.js streams (backpressure,
drain,Readable)
Instructions
Apply the pattern that fits your workload. Steps 2–7 live in references/implementation.md with full, copy-pasteable code; the core typed-query skeleton stays here.
- Typed query helper — the foundation every other pattern builds on. Define
a generic
query<T>wrapper that returns parsed rows (skeleton below). - Streaming insert (backpressure-safe) — stream large inserts through a
Readableinstead of buffering in memory; honordrain. - Batch insert with retry — chunk rows (default 10k) with exponential-backoff
retries, returning
{ inserted, errors }. - Streaming SELECT (low memory) — consume large result sets as an
AsyncGeneratorso you never load the full set into RAM. - Error handling — distinguish server-side
ClickHouseError(code + message) from network/client errors and normalize into a structured result. - Connection lifecycle — flush pending inserts on
SIGTERMviaclient.close(); expose aping()-based health check. - Per-query settings — override
max_threads,max_memory_usage,max_execution_time, andmax_result_rowsfor heavy queries.
Skeleton: Typed Query Helper
import { createClient } from '@clickhouse/client';
const client = createClient({
url: process.env.CLICKHOUSE_HOST!,
username: process.env.CLICKHOUSE_USER ?? 'default',
password: process.env.CLICKHOUSE_PASSWORD ?? '',
});
// Generic typed query — returns parsed JSON rows
async function query<T>(sql: string, params?: Record<string, unknown>): Promise<T[]> {
const rs = await client.query({
query: sql,
query_params: params,
format: 'JSONEachRow',
});
return rs.json<T>();
}
Note on parameterized queries: ClickHouse uses {name:Type} syntax for
parameters, not $1 or ?. Always use typed parameters to prevent SQL injection.
Output
Applying these patterns produces:
- A single reusable
clientinstance plus a genericquery<T>helper that returns typed, parsed rows. - Streaming insert/read paths that keep memory flat regardless of dataset size.
- A batch-insert result object
{ inserted: number; errors: Error[] }you can act on programmatically. - Normalized error results (
CH-<code>: <message>for server-side failures) rather than raw thrown exceptions. - Graceful shutdown that flushes pending inserts before the process exits.
Error Handling
Map common ClickHouse server error codes to a corrective action:
| Error Code | Meaning | Action |
|---|---|---|
SYNTAX_ERROR (62) | Bad SQL | Fix query syntax |
UNKNOWN_TABLE (60) | Table doesn't exist | Check table name, database |
TOO_MANY_SIMULTANEOUS_QUERIES (202) | Connection overload | Reduce concurrency or pool |
MEMORY_LIMIT_EXCEEDED (241) | Query uses too much RAM | Add filters, use streaming |
TIMEOUT_EXCEEDED (159) | Query too slow | Optimize ORDER BY, add indexes |
Full safeQuery wrapper (server-vs-client error discrimination) is in
references/implementation.md under Pattern 5.
Examples
Worked, runnable usage of each helper is in references/examples.md. Quick look — a typed aggregation query with named parameters:
interface EventCount {
event_type: string;
cnt: string; // ClickHouse JSON returns numbers as strings
}
const rows = await query<EventCount>(
'SELECT event_type, count() AS cnt FROM events WHERE user_id = {user_id:UInt64} GROUP BY event_type',
{ user_id: 42 }
);
See references/examples.md for streaming reads and structured error-result usage.
Resources
- references/implementation.md — full code for patterns 2–7 + format table
- references/examples.md — worked, runnable usage examples
- Node.js Client Docs
- Client Examples (GitHub)
- Query Settings Reference
Next Steps
Apply these patterns in clickhouse-core-workflow-a for real data modeling, then
tune query cost and concurrency with clickhouse-cost-tuning and
clickhouse-performance-tuning.
What ships with it: 2 files
6.1 KB alongside SKILL.md
references/
- examples.md1.6 KB
- implementation.md4.5 KB