---
title: "Tinybird Best Practices for AI Agents"
excerpt: "Turn any AI coding agent into a Tinybird expert. 20 rules covering schema design, endpoints, materialized views, testing, and deployment."
authors: "Rafa Moreno, Gonzalo Gomez"
categories: "AI x Data"
createdOn: "2026-01-27 00:00:00"
publishedOn: "2026-01-27 00:00:00"
updatedOn: "2026-01-27 00:00:00"
status: "published"
---

[Tinybird Code](https://www.tinybird.co/docs/forward/tinybird-code) is our AI-powered CLI that understands how to build Tinybird projects. Now we're sharing that knowledge with every AI coding agent.

We've packaged [tinybird-best-practices](https://github.com/tinybirdco/tinybird-agent-skills) as a structured skill that works with any [Agent Skills](https://agentskills.io/) compatible agent: Amp, Claude Code, Codex, Cursor, Gemini CLI, OpenCode, Windsurf, and more.

Install the skill and your agent automatically loads the relevant rules when it detects Tinybird files:

```bash
npx skills add tinybirdco/tinybird-agent-skills
```

![Tinybird Agent Skills](tinybird-agent-skills.jpg)

The skill covers the full Tinybird development lifecycle, from schema design and query optimization to testing and deployment. 20 rules that turn your agent into a Tinybird expert.

## What's included

| Category | What it covers | Rule files |
| -------- | -------------- | ---------- |
| **Project structure** | File organization, CLI commands, local development | [project-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/project-files.md), [cli-commands.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/cli-commands.md), [local-development.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/local-development.md) |
| **Datasources** | Schema definitions, JSON paths, column types, ENGINE selection | [datasource-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/datasource-files.md), [connection-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/connection-files.md) |
| **Pipes & Endpoints** | Node structure, TYPE values, SQL templating, parameters | [pipe-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/pipe-files.md), [endpoint-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/endpoint-files.md), [sql.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/sql.md) |
| **Materialized Views** | State/Merge modifiers, AggregatingMergeTree, backfilling | [materialized-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/materialized-files.md) |
| **Copy Pipes & Sinks** | Snapshots, scheduling, deduplication, exports | [copy-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/copy-files.md), [sink-files.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/sink-files.md), [deduplication-patterns.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/deduplication-patterns.md) |
| **Data operations** | Appending, replacing, mock data generation | [append-data.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/append-data.md), [data-operations.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/data-operations.md), [mock-data.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/mock-data.md) |
| **Optimization** | Sorting keys, read_bytes reduction, query tuning | [endpoint-optimization.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/endpoint-optimization.md) |
| **Testing & Deploy** | Fixtures, build vs deploy, secrets, tokens | [tests.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/tests.md), [build-deploy.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/build-deploy.md), [secrets.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/secrets.md), [tokens.md](https://github.com/tinybirdco/tinybird-agent-skills/blob/main/skills/tinybird-best-practices/rules/tokens.md) |

## Examples

Each rule includes code examples. Here's a sample across different categories.

### Defining a datasource schema

The agent uses JSON paths and sorting keys that match your query patterns:

```tinybird
SCHEMA >
    `user_id` String `json:$.user_id`,
    `event_type` LowCardinality(String) `json:$.event_type`,
    `timestamp` DateTime64(3) `json:$.timestamp`,
    `properties` String `json:$.properties`

ENGINE "MergeTree"
ENGINE_SORTING_KEY "user_id, timestamp"
```

Not `column_name Type`, but `column_name Type json:$.path`. The backticks, JSON paths, and sorting key order are all handled correctly.

### Building an endpoint

The agent structures pipes with nodes and uses proper parameter syntax:

```tinybird
DESCRIPTION >
    Get events for a user within a date range

NODE filtered_events
SQL >
    %
    SELECT user_id, event_type, timestamp
    FROM events
    WHERE user_id = {{ String(user_id) }}
      AND timestamp >= {{ DateTime(start_date) }}
      AND timestamp < {{ DateTime(end_date) }}

NODE endpoint
SQL >
    SELECT event_type, count() as total
    FROM filtered_events
    GROUP BY event_type
    ORDER BY total DESC

TYPE ENDPOINT
```

The `%` enables templating. Parameters use `{{ Type(name) }}` syntax. Filters come early. The agent won't write CTEs, it uses nodes.

### Creating a materialized view

The agent uses State modifiers and pairs them with the correct target schema:

```tinybird
DESCRIPTION >
    Daily event counts by user

NODE daily_counts
SQL >
    SELECT
        toStartOfDay(timestamp) as day,
        user_id,
        countState() as event_count
    FROM events
    GROUP BY day, user_id

TYPE MATERIALIZED
DATASOURCE daily_events_mv
```

`countState()`, not `count()`. The target datasource uses `AggregateFunction(count, UInt64)`. The agent knows this pairing.

## Before and after: agent output

Here's what changes when the skill is installed.

**Prompt:** "Create a datasource for tracking page views with user_id and timestamp"

**Without skill:**

```tinybird
SCHEMA >
    user_id String,
    timestamp DateTime,
    page_url String

ENGINE "MergeTree"
ENGINE_SORTING_KEY "timestamp"
```

**With skill:**

```tinybird
SCHEMA >
    `user_id` String `json:$.user_id`,
    `timestamp` DateTime64(3) `json:$.timestamp`,
    `page_url` String `json:$.page_url`

ENGINE "MergeTree"
ENGINE_SORTING_KEY "user_id, timestamp"
```

The skill-aware agent:

- Uses JSON paths for schema (required for Events API ingestion)
- Puts `user_id` first in the sorting key (queries filter by user, not by time range)
- Uses `DateTime64(3)` for millisecond precision

The sorting key change alone can reduce `read_bytes` by 10x or more. Instead of scanning every row in a time range, ClickHouse{% sup %}®{% /sup %} skips directly to the user's data.

### Nodes instead of CTEs, filtering before JOINs

**Without skill:**

```sql
WITH filtered AS (
    SELECT * FROM orders
    JOIN customers ON orders.customer_id = customers.id
    WHERE customers.country = 'US'
)
SELECT product_id, sum(amount) FROM filtered GROUP BY product_id
```

**With skill:**

```tinybird
NODE us_customers
SQL >
    SELECT id FROM customers WHERE country = {{ String(country, 'US') }}

NODE filtered_orders
SQL >
    SELECT product_id, amount
    FROM orders
    WHERE customer_id IN (SELECT id FROM us_customers)

NODE endpoint
SQL >
    SELECT product_id, sum(amount) as total
    FROM filtered_orders
    GROUP BY product_id

TYPE ENDPOINT
```

The agent uses nodes instead of CTEs, filters before joining, and adds parameters for flexibility.

### LowCardinality for repeated strings

**Without skill:**

```tinybird
SCHEMA >
    `status` String `json:$.status`,
    `country` String `json:$.country`,
    `event_type` String `json:$.event_type`
```

**With skill:**

```tinybird
SCHEMA >
    `status` LowCardinality(String) `json:$.status`,
    `country` LowCardinality(String) `json:$.country`,
    `event_type` LowCardinality(String) `json:$.event_type`
```

For columns with fewer than 10K unique values, LowCardinality provides ~10x compression and faster filtering.

### Project structure

**Without skill:**

```text
my-project/
  events.datasource
  get_events.pipe
  daily_stats.pipe
  events.ndjson
```

**With skill:**

```text
my-project/
  datasources/
    events.datasource
  endpoints/
    get_events.pipe
  materializations/
    daily_stats.pipe
  fixtures/
    events.ndjson
```

The agent follows Tinybird conventions: datasources, endpoints, materializations, copies, and fixtures each have their own directory.

## Where these rules come from

Real performance work on production codebases. The same patterns used by [customers processing billions of rows](https://www.tinybird.co/customer-stories) at companies like Vercel and Canva. Schema decisions that cut query latency from seconds to milliseconds. Sorting key choices that skip most of the data. Materialized view patterns that don't break silently.

Every rule exists because someone hit the problem in production.

### You're still in control

The skill provides guidance, not magic. The agent explains *why* it makes choices, and you can override anything.

```bash
$ This endpoint is slow, help me optimize it

Looking at your endpoint, I see a few issues:

1. Sorting key mismatch. Your queries filter by customer_id, but the
   sorting key is (timestamp, customer_id). This forces a full partition
   scan for every request. I'll swap the order to (customer_id, timestamp)
   so ClickHouse can skip irrelevant data.

2. Query-time deduplication on a large table. You're using FINAL on a
   500M row table. At this scale, Copy Pipes with periodic snapshots
   will perform better. I'll create an hourly snapshot and point your
   endpoint at that.

Want me to make these changes?
```

The agent tells you what's wrong and why the fix works. If you disagree, tell it. The rules are context, not commands.

## What about Tinybird's other AI tools?

Tinybird offers several AI tools, each for a different workflow:

| Tool | What it does |
| ---- | ------------ |
| [Tinybird Code](https://www.tinybird.co/docs/forward/tinybird-code) | AI-powered CLI. Run `tb` and describe what you want. |
| [Agent Skills](https://github.com/tinybirdco/tinybird-agent-skills) | The same knowledge, packaged for any agent. |
| [MCP Server](https://www.tinybird.co/docs/forward/analytics-agents) | Every workspace is a remote MCP server. Connect LLMs directly to your endpoints. |
| [Explorations](https://www.tinybird.co/docs/forward/work-with-data/explorations) | Conversational UI to explore your data without writing SQL. |

**Tinybird Code** is the AI ClickHouse expert. It knows how to build real-time projects with Tinybird, but it runs in the Tinybird CLI.

**Agent Skills** bring that expertise to your current agent and workflow. Whether you're in Claude Code, Cursor, Windsurf, or another tool, the skills teach your agent how Tinybird projects work.

## How to use

Install the skill in your agent:

```bash
npx skills add tinybirdco/tinybird-agent-skills
```

The skill is just markdown files, no runtime dependencies, no performance impact. Your agent loads the relevant rules based on context. Editing a `.datasource` file? It gets datasource and schema rules. Optimizing an endpoint? It gets SQL and optimization rules.

**Try these prompts:**

- "Create a datasource for user events with deduplication"
- "This endpoint is slow, why?"
- "Set up a materialized view for daily aggregations"
- "Add a Copy Pipe to snapshot this table hourly"

**Questions?** Join the [Tinybird Slack community](https://www.tinybird.co/docs/community).

**Found a new pattern?** Open a PR on the [GitHub repo](https://github.com/tinybirdco/tinybird-agent-skills). Just submit your rule and we'll review it.
