Skip to content
Back to skills

Clickhouse Reference Architecture

ASecurity

Production reference architecture for ClickHouse-backed applications — project layout, data flow, multi-tenant patterns, and operational topology. Use when designing a new ClickHouse system, reviewing an existing analytics architecture, or establishing standards for ClickHouse integrations. Trigger with "clickhouse architecture", "clickhouse project structure", "clickhouse design", "clickhouse multi-tenant", "clickhouse reference".

  • 2,719 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 21, 2026
ai-agentstypescriptsqlnodedockerdebuggingapidatabasesecurity

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add jeremylongshore/claude-code-plugins-plus --skill clickhouse-reference-architecture --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Clickhouse Reference Architecture?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Clickhouse Reference Architecture
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeremylongshore-clickhouse-reference-architecture-92282c9d/badge)](https://www.skillsdirectory.com/skills/jeremylongshore-clickhouse-reference-architecture-92282c9d)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: clickhouse-reference-architecture
description: |
  Production reference architecture for ClickHouse-backed applications —
  project layout, data flow, multi-tenant patterns, and operational topology.
  Use when designing a new ClickHouse system, reviewing an existing analytics
  architecture, or establishing standards for ClickHouse integrations.
  Trigger with "clickhouse architecture", "clickhouse project structure",
  "clickhouse design", "clickhouse multi-tenant", "clickhouse reference".
allowed-tools: Read, Grep
version: 1.7.0
license: MIT
author: Jeremy Longshore <jeremy@intentsolutions.io>
tags:
- saas
- database
- analytics
- clickhouse
- olap
compatibility: Designed for Claude Code
---
# ClickHouse Reference Architecture

## Overview

Production-grade architecture for ClickHouse analytics platforms covering project
layout, data flow, multi-tenancy, and operational patterns. Work through the five
steps below to get the high-level shape, then drill into the linked reference files
for the full DDL, client code, and tenancy trade-offs.

## Prerequisites

- Understanding of ClickHouse fundamentals — table engines, `ORDER BY` sort keys,
  and partitioning.
- A TypeScript/Node.js project (the client examples use `@clickhouse/client`).
- When reviewing an existing codebase, `Grep` for `createClient(` to locate the
  current client module and `Read` the SQL files under `clickhouse/schemas/`.

## Instructions

### Step 1: Project Structure

Keep SQL DDL as the source of truth under `clickhouse/schemas/`, named query
functions under `clickhouse/queries/`, and ingestion/API/jobs in sibling modules.

```
my-analytics-platform/
├── src/
│   ├── clickhouse/
│   │   ├── client.ts           # Singleton client with health checks
│   │   ├── schemas/            # SQL DDL files (source of truth)
│   │   │   ├── 001-events.sql
│   │   │   ├── 002-users.sql
│   │   │   └── 003-materialized-views.sql
│   │   ├── queries/            # Named query functions
│   │   └── migrations/         # Schema migrations (runner.ts + *.sql)
│   ├── ingestion/              # webhook-receiver, kafka-consumer, buffer
│   ├── api/                    # routes.ts, middleware.ts (auth, rate limit)
│   └── jobs/                   # daily-rollup.ts, cleanup.ts (TTL enforcement)
├── tests/                      # unit/ + integration/
├── docker-compose.yml          # Local ClickHouse
├── init-db/                    # Docker init scripts
└── config/                     # development / staging / production .env
```

### Step 2: Data Flow Architecture

Data moves in one direction: sources → a batching ingestion layer → ClickHouse
(raw MergeTree → materialized views → aggregate tables) → an API that reads only
the aggregate tables → dashboards.

```
Data Sources (Webhooks, API, Kafka, S3)
        │
Ingestion Layer (Buffer + batch, 10K+ rows/insert)
        │
ClickHouse Server
   Raw Event Tables (MergeTree, append-only)
        │  auto-aggregate on INSERT
   Materialized Views (hourly, daily, tenant-level)
        │
   Aggregate Tables (AggregatingMergeTree)
        │
API Layer (queries aggregate tables, never raw events)
        │
Dashboards / Client Apps
```

### Step 3: Schema Design (3-Layer Pattern)

Three layers — raw append-only events, hourly aggregation, and a daily rollup for
dashboards — with materialized views auto-populating each aggregate on INSERT.
The essential raw-table skeleton:

```sql
CREATE TABLE analytics.events_raw (
    event_id    UUID DEFAULT generateUUIDv4(),
    tenant_id   UInt32,
    event_type  LowCardinality(String),
    user_id     UInt64,
    properties  String CODEC(ZSTD(3)),
    created_at  DateTime64(3) DEFAULT now64(3)
)
ENGINE = MergeTree()
ORDER BY (tenant_id, event_type, toDate(created_at), user_id)
PARTITION BY toYYYYMM(created_at)
TTL created_at + INTERVAL 90 DAY;
```

Full three-layer DDL, materialized views, and the rationale: see
[references/schema-design.md](references/schema-design.md).

### Step 4: Multi-Tenant Patterns

Choose an isolation strategy. Default to Approach A (shared table, `tenant_id`
first in `ORDER BY`) — it scales to 10K+ tenants:

```sql
ORDER BY (tenant_id, event_type, created_at)
SELECT count() FROM events_raw WHERE tenant_id = 42;  -- scans only tenant 42
```

Database-per-tenant (strict isolation) and row-level security (RBAC) alternatives
with trade-offs: see [references/multi-tenant-patterns.md](references/multi-tenant-patterns.md).

### Step 5: Client Module

Use a singleton `@clickhouse/client` instance and parameterized queries that read
from the aggregate tables. Full client + query-function code:
[references/client-module.md](references/client-module.md).

## Architecture Decision Records

| Decision | Choice | Why |
|----------|--------|-----|
| Engine | MergeTree (raw) + AggregatingMergeTree (rollups) | Best for append + pre-agg |
| Multi-tenant | Shared table + tenant_id in ORDER BY | Scales to 10K+ tenants |
| Ingestion | Buffer + batch INSERT | Avoids "too many parts" |
| Aggregation | Materialized views (not cron) | Real-time, zero-lag |
| Format | JSONEachRow | Client support, debugging |
| Compression | ZSTD(3) for strings, Delta for ints | 10-20x compression |

## Output

Applying this skill produces a concrete architecture plan for a ClickHouse system:

- A **project directory layout** (Step 1) with DDL as the source of truth.
- A **3-layer schema** — raw MergeTree table, hourly and daily
  `AggregatingMergeTree` tables, each fed by a materialized view.
- A chosen **multi-tenant isolation strategy** (shared table / database-per-tenant /
  row policy) with the reasoning recorded.
- A **singleton client module** plus named, parameterized query functions that read
  only from aggregate tables.
- A filled-in **Architecture Decision Record** table capturing engine, tenancy,
  ingestion, aggregation, format, and compression choices.

## Error Handling

| Issue | Cause | Solution |
|-------|-------|----------|
| Cross-tenant data leak | Missing WHERE tenant_id | Use row policies or middleware |
| Stale dashboard data | MV not created | Verify MV exists and is attached |
| Schema drift | Manual DDL changes | Use migration runner |
| Slow dashboard queries | Querying raw table | Query aggregate tables instead |

## Examples

**Design a new multi-tenant analytics platform.** Start from the Step 1 layout and
the Step 3 raw-table skeleton, then open [references/schema-design.md](references/schema-design.md)
for the full three-layer DDL and [references/multi-tenant-patterns.md](references/multi-tenant-patterns.md)
to pick an isolation strategy.

**Query a tenant dashboard from Node.js.** Read from the daily rollup, not the raw
table — the pattern the client module in
[references/client-module.md](references/client-module.md) implements:

```sql
SELECT date, sum(total) AS events, uniqMerge(users) AS unique_users
FROM analytics.events_daily
WHERE tenant_id = {tid:UInt32} AND date >= today() - {days:UInt32}
GROUP BY date ORDER BY date;
```

**Review an existing ClickHouse integration.** `Grep` for `createClient(` and any
raw-table `SELECT`s in the API layer; flag queries hitting `events_raw` instead of
an aggregate table against the Error Handling table above.

## Resources

- [ClickHouse Architecture](https://clickhouse.com/docs/development/architecture)
- [SharedMergeTree (Cloud)](https://clickhouse.com/docs/cloud/reference/shared-merge-tree)
- [Materialized Views](https://clickhouse.com/blog/using-materialized-views-in-clickhouse)
- [references/schema-design.md](references/schema-design.md) — full 3-layer DDL
- [references/multi-tenant-patterns.md](references/multi-tenant-patterns.md) — tenancy trade-offs
- [references/client-module.md](references/client-module.md) — client + query code

## Next Steps

For multi-environment configuration, layer on the `clickhouse-multi-env-setup`
skill, which covers per-environment `.env` files, staging/production connection
settings, and migration promotion between environments.

Files in this skill

  • SKILL.md8 KB
  • references/client-module.md2.1 KB
  • references/multi-tenant-patterns.md1.6 KB
  • references/schema-design.md2.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.