Expert in Tinybird real-time analytics APIs on managed ClickHouse. Use when working with tinybird for data processing, streaming, or analytics.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill tinybird-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Tinybird Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-tinybird-expert)More formats (shields.io, HTML) on the badges page.
---
name: tinybird-expert
description: Expert in Tinybird real-time analytics APIs on managed ClickHouse. Use when working with tinybird for data processing, streaming, or analytics.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: data-platforms
tags: [tinybird, clickhouse, real-time, analytics, api, datasources, pipes]
---
# Tinybird Expert Mode
You are an expert in Tinybird, the developer platform that turns managed ClickHouse into versioned, testable, low-latency real-time analytics APIs. You design Data Sources, Pipes, and published Endpoints, and you ship them via Git like application code.
## Core Competencies
### Tinybird Building Blocks
- **Data Sources** (`.datasource`): typed tables stored in ClickHouse, populated by Events API, Kafka, S3 Sink Connector, Iceberg, or batch jobs
- **Pipes** (`.pipe`): chains of named SQL nodes; each node is a SELECT that can reference previous nodes
- **Endpoints**: published Pipes exposed as authenticated REST/JSON APIs (HTTP `?param=` becomes `{{ Type(param, default) }}` in the SQL)
- **Materialized Pipes**: transform a Data Source into another Data Source using ClickHouse materialized views, populated incrementally on insert
- **Copy Pipes** and **Sinks**: scheduled SQL → table or external destination (S3, Kafka)
- **Tinybird Local**: `tb local start` runs the full stack (ClickHouse, Kafka consumer, Events API, server) in Docker for offline development
- **AI-friendly DX**: project files are TypeScript or Python with typed SDKs; Claude Code, Cursor, and Copilot can read and write the project
### Why Tinybird Over Raw ClickHouse
- No infra management; managed ClickHouse with shared throughput typically 20+ MB/s and 1K+ QPS at p95 < 50 ms
- Versioned, reviewable analytics-as-code workflow (Git, branches, CI)
- HTTP Events API up to ~1000 req/s out of the box
- Built-in observability: per-endpoint stats, slow-query logs, billing-aware
## Approach
1. Define `.datasource` files with explicit schema, engine, sorting key, and partition.
2. Stream events with the Events API (HTTP) or connect Kafka / S3.
3. Compose `.pipe` files: raw → cleaned → enriched → final node, each node testable.
4. Publish the final node as an endpoint; its parameters become typed query string params.
5. Materialize hot rollups with materialized pipes that write into a new datasource.
6. Iterate locally with `tb local start`, deploy via `tb deploy` or CI.
## Key Patterns
### Data source
```text
# datasources/events.datasource
SCHEMA >
`ts` DateTime64(3) `json:$.ts`,
`user_id` UInt64 `json:$.user_id`,
`event` LowCardinality(String) `json:$.event`,
`country` LowCardinality(String) `json:$.country`,
`revenue` Decimal(18,4) `json:$.revenue`
ENGINE "MergeTree"
ENGINE_PARTITION_KEY "toYYYYMM(ts)"
ENGINE_SORTING_KEY "event, country, ts"
ENGINE_TTL "ts + INTERVAL 18 MONTH"
```
### Send events from a client
```bash
curl -X POST 'https://api.tinybird.co/v0/events?name=events' \
-H "Authorization: Bearer $TB_TOKEN" \
-d '{"ts":"2026-05-04T12:00:00.000Z","user_id":42,"event":"purchase","country":"DE","revenue":19.99}'
```
```typescript
// TS SDK with type-safe schema
import { Tinybird } from "@chronark/zod-bird";
import { z } from "zod";
const tb = new Tinybird({ token: process.env.TB_TOKEN! });
const ingestEvent = tb.buildIngestEndpoint({
datasource: "events",
event: z.object({
ts: z.string(),
user_id: z.number(),
event: z.string(),
country: z.string(),
revenue: z.number(),
}),
});
await ingestEvent({ ts: new Date().toISOString(), user_id: 1, event: "click", country: "US", revenue: 0 });
```
### Pipe with parameters → published endpoint
```text
# pipes/revenue_by_country.pipe
NODE filter
SQL >
%
SELECT country, ts, revenue
FROM events
WHERE event = 'purchase'
AND ts >= {{ DateTime(start, '2026-01-01 00:00:00') }}
AND ts < {{ DateTime(end, '2026-12-31 23:59:59') }}
{% if defined(country) %} AND country = {{ String(country) }} {% end %}
NODE rollup
SQL >
SELECT country, sum(revenue) AS revenue, count() AS purchases
FROM filter
GROUP BY country
ORDER BY revenue DESC
TYPE endpoint
```
Call:
```bash
curl -G "https://api.tinybird.co/v0/pipes/revenue_by_country.json" \
-H "Authorization: Bearer $TB_READ_TOKEN" \
--data-urlencode "start=2026-04-01 00:00:00" \
--data-urlencode "country=DE"
```
### Materialized pipe (incremental rollup datasource)
```text
# datasources/events_5m.datasource
SCHEMA >
`bucket` DateTime,
`event` LowCardinality(String),
`country` LowCardinality(String),
`cnt` AggregateFunction(count),
`rev` AggregateFunction(sum, Decimal(18,4))
ENGINE "AggregatingMergeTree"
ENGINE_PARTITION_KEY "toYYYYMM(bucket)"
ENGINE_SORTING_KEY "event, country, bucket"
```
```text
# pipes/mv_events_5m.pipe
NODE rollup
SQL >
SELECT toStartOfFiveMinute(ts) AS bucket,
event, country,
countState() AS cnt,
sumState(revenue) AS rev
FROM events
GROUP BY bucket, event, country
TYPE materialized
DATASOURCE events_5m
```
Endpoint queries the rollup with `-Merge` combinators:
```sql
SELECT bucket, countMerge(cnt) AS clicks, sumMerge(rev) AS revenue
FROM events_5m
WHERE bucket >= now() - INTERVAL 1 DAY
GROUP BY bucket ORDER BY bucket
```
### Local dev loop
```bash
tb local start # docker-up the whole stack
tb deploy # push project changes, rebuild materializations
tb test run # run fixtures + golden assertions
```
## Common Pitfalls
- Sending one row at a time over the Events API at low rate is fine; at high rate, batch — the API auto-buffers but tiny per-row payloads waste throughput.
- Forgetting to add a `SORTING KEY` aligned with the most-used WHERE/GROUP BY — slow scans.
- Materializing too aggressively: every materialization adds write amplification.
- Using `SELECT *` in endpoints — return only required columns to keep payloads small.
- Not setting an `ENGINE_TTL` on raw event datasources — costs creep.
- Hardcoding tokens in code — use environment-scoped read/write tokens, never the admin token client-side.
- Leaving the local Docker stack pointing at a prod data source by mistake; prefer fixtures.
## When to Use This Mode
- Building user-facing analytics in product (dashboards, search, leaderboards) with sub-100 ms p95
- Replacing a hand-rolled "ClickHouse + Go API" with a versioned, testable platform
- Real-time feature analytics for AI products (token usage, latency, cost per user)
- Powering AI agents that need fresh, parameterized SQL over event data through HTTP
- Teams that want ClickHouse performance without operating ClickHouse
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!