dawiddutoit/custom-claude/clickhouse-materialized-views
Claude Code and agent skill by dawiddutoit/custom-claude
- community
Checking that the SKILL.md file is still in the repository.
Guides for implementing real-time data aggregation and transformation pipelines using ClickHouse materialized views. Use when building real-time dashboards, streaming analytics, metrics aggregation, event processing, or continuous data transformation. Covers incremental aggregation, State/Merge functions, chaining views, schema evolution, and troubleshooting streaming pipelines.
Install
npx vskill@latest install dawiddutoit/custom-claude/clickhouse-materialized-viewsSKILL.md
Table of Contents
- Step 1: Choose Your Aggregation Pattern
- Step 2: Select the Right Destination Engine
- Step 3: Design Your Aggregation Query
- Step 4: Implement State/Merge Functions
- Step 5: Chain Views for Multi-Level Aggregation
- Step 6: Handle Schema Evolution
- Step 7: Monitor Performance
- Step 8: Backfill Historical Data
ClickHouse Materialized Views Skill
Purpose
Materialized views in ClickHouse are incremental triggers that automatically transform and aggregate incoming data in real-time. Unlike traditional databases, ClickHouse views process only new data as it arrives, enabling efficient streaming analytics, real-time dashboards, and continuous aggregation without scheduled batch jobs.
When to Use This Skill
Use when asked to:
- Build real-time data aggregation pipelines ("create real-time metrics")
- Implement streaming analytics or continuous aggregation
- Create pre-aggregated tables for fast dashboard queries
- Set up automatic data transformation as events arrive
- Chain multi-level aggregations (hourly → daily → monthly)
Do NOT use when:
- Data is batch-processed infrequently (use scheduled jobs instead)
- Aggregation logic changes often (materialized views are harder to modify)
- Source data is small and queries are already fast
Quick Start
Create a simple real-time aggregation pipeline:
Instructions
Step 1: Choose Your Aggregation Pattern
Materialized views support three main patterns depending on your use case:
Incremental Views (Most Common)
- Process only new data as it arrives
- Best for streaming event data and continuous updates
- Use with
SummingMergeTreefor automatic deduplication
Refreshable Views
- Recalculate entire view on a schedule (e.g., hourly)
- Best for complex queries that need full recalculation
- Syntax:
CREATE MATERIALIZED VIEW ... REFRESH EVERY 1 HOUR AS ...
Populate-Based Views
- Backfill existing data when view is created
- Warning: Can be expensive on large tables
- Syntax:
CREATE MATERIALIZED VIEW ... POPULATE AS ...
See examples/aggregation-patterns.md for complete pattern examples.
Step 2: Select the Right Destination Engine
The destination table engine determines how your aggregated data behaves:
SummingMergeTree (Simple Aggregates)
- Use when aggregating with COUNT, SUM, AVG
- Automatically sums columns during background merges
- No duplicate rows in final results
- Example: Hourly sales totals, daily revenue
AggregatingMergeTree (Complex Aggregates)
- Use with State/Merge functions for uniq, quantile, topK
- Stores intermediate aggregation states
- Combine with
uniqState(),quantileState(),topKState()in views - Query with
uniqMerge(),quantileMerge(),topKMerge()functions - Example: Unique user counts, percentile calculations
ReplacingMergeTree (Deduplication)
- Use when you need to replace/update existing rows
- Maintains version column to determine latest record
- Example: User profile updates, entity state snapshots
MergeTree (Raw Events)
- Use when storing raw events without aggregation
- No automatic deduplication
- Example: Event audit trail, raw clickstream data
See references/engine-comparison.md for detailed comparison.
Step 3: Design Your Aggregation Query
Follow these principles:
GROUP BY Cardinality
- Keep cardinality moderate (not millions of unique combinations)
- Example: Good =
GROUP BY date, product_id| Bad =GROUP BY user_id, timestamp
ORDER BY for Query Patterns
- Design ORDER BY for your most common query filters
- If queries filter by date first:
ORDER BY (date, product_id) - If queries filter by product first:
ORDER BY (product_id, date)
Include Necessary Columns
- Include columns needed for post-aggregation filtering
- Store raw values alongside aggregates when needed for flexibility
- Example: Store
timestampandrevenuealong with hourly aggregates
Use Conditional Aggregation
- Use
countIf(),sumIf(),avgIf()for event filtering - Filter within the aggregation rather than in views
- Example:
countIf(event_type = 'purchase') as purchase_count
See examples/aggregation-patterns.md for SQL patterns.
Step 4: Implement State/Merge Functions for Complex Aggregates
When using AggregatingMergeTree, use special State/Merge function pairs:
In Materialized View (State Functions)
In Queries (Merge Functions)
Common function pairs:
uniq()↔uniqState()/uniqMerge()sum()↔sumState()/sumMerge()avg()↔avgState()/avgMerge()quantile(0.95)()↔quantileState(0.95)()/quantileMerge(0.95)()topK(10)()↔topKState(10)()/topKMerge(10)()
See references/state-merge-reference.md for all function pairs.
Step 5: Chain Views for Multi-Level Aggregation
Build hierarchical aggregations to reduce redundant computation:
Benefits:
- Reduces redundant computation (don't re-process raw events for daily stats)
- Each level optimized for different query patterns
- Easier to debug and modify intermediate aggregations
Step 6: Handle Schema Evolution and Versioning
When modifying aggregation logic:
Avoid ALTER TABLE on materialized view destinations when possible (can cause data loss).
Step 7: Monitor and Optimize View Performance
Check View Execution Performance
Common Performance Issues and Solutions
- High memory usage: Reduce GROUP BY cardinality or add WHERE filters
- Slow execution: Simplify aggregation logic or chain views instead of complex single view
- Data lag: Increase
kafka_max_block_sizeif consuming from Kafka
See references/troubleshooting.md for debugging guide.
Step 8: Backfill Historical Data
When adding new views to existing data:
Option 1: Direct Insert (Safest)
Option 2: Use POPULATE (for empty tables)
⚠️ Avoid POPULATE on large source tables (can be very slow).
Examples & Patterns
The following patterns are common use cases for materialized views:
Real-Time Dashboard Metrics
Pre-aggregate metrics to enable instant dashboard queries:
User Segmentation
Automatically segment users based on behavior:
Multi-Destination Routing
Route data to multiple aggregations:
Complete Examples
For comprehensive, production-ready examples covering real-world scenarios, see the examples/ directory:
- Real-time dashboards and metrics aggregation
- User segmentation and cohort analysis
- Funnel analysis and conversion tracking
- Time-series downsampling and rollups
- Kafka streaming pipelines with end-to-end examples
Requirements
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/clickhouse-materialized-views/SKILL.md
Popularity
- Repository stars
- 1
- 7-day trend score
- 3
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 12 Apr 2026, 6 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/dawiddutoit/custom-claude/clickhouse-materialized-views)