# От интуиции к данным: PostHog + Metabase с помощью AI за один выходной

> Self-hosted аналитика продукта (PostHog) и BI-дашборды (Metabase) через Docker. AI-промпты для генерации дашбордов, интеграция, production-чеклист.
> Author: Roman Belov · Published: 2026-07-11 · Source: https://futurecraft.pro/ru/blog/posthog-metabase-setup/

Решения принимаются на ощущениях, когда пользовательское поведение никто не трекает систематически. PostHog (product analytics, open-source) и Metabase (BI-дашборды, open-source) закрывают этот разрыв — оба разворачиваются self-hosted за один выходной. AI ускоряет самую нудную часть: настройку дашбордов и SQL-запросов.

В этом руководстве: Docker-конфигурация, интеграция PostHog с Metabase, промпты для генерации дашбордов через LLM, production-паттерны.

## Зачем два инструмента вместо одного

PostHog и Metabase решают разные задачи. Использовать только один из них — значит видеть половину картины.

**PostHog** — product analytics. Трекинг событий, воронки, retention, feature flags, session replay. Отвечает на вопрос: «что пользователи делают в продукте».

**Metabase** — business intelligence. SQL-запросы к любой базе данных, визуализации, дашборды. Отвечает на вопрос: «как бизнес-метрики связаны с продуктовыми данными».

```
┌───────────────────────────────────────────────────┐
│                 Data Stack                         │
├─────────────────────┬─────────────────────────────┤
│     PostHog         │        Metabase              │
├─────────────────────┼─────────────────────────────┤
│ Event tracking      │ SQL на любой БД              │
│ Funnels             │ Cross-database joins         │
│ Retention           │ Scheduled reports            │
│ Feature flags       │ Embeddable dashboards        │
│ Session replay      │ Non-technical access         │
└─────────────────────┴─────────────────────────────┘
```

PostHog хранит данные в ClickHouse. Metabase подключается к ClickHouse напрямую и строит произвольные SQL-запросы поверх event-данных PostHog. Получается полный стек: сбор данных, продуктовая аналитика и бизнес-аналитика.

## Docker setup: PostHog

Минимальные требования: 4 vCPU, 16 ГБ RAM, 30+ ГБ дискового пространства, Docker, docker compose. PostHog использует ClickHouse, Kafka, PostgreSQL и Redis.

```yaml
# docker-compose.posthog.yml
version: '3.8'

services:
  posthog:
    image: posthog/posthog:latest
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgres://posthog:posthog@postgres:5432/posthog
      REDIS_URL: redis://redis:6379/
      CLICKHOUSE_HOST: clickhouse
      CLICKHOUSE_DATABASE: posthog
      CLICKHOUSE_SECURE: "false"
      SECRET_KEY: your-secret-key-change-me
      SITE_URL: http://localhost:8000
    depends_on:
      - postgres
      - redis
      - clickhouse

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: posthog
      POSTGRES_PASSWORD: posthog
      POSTGRES_DB: posthog
    volumes:
      - posthog_postgres:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    volumes:
      - posthog_redis:/data

  clickhouse:
    image: clickhouse/clickhouse-server:24.3
    volumes:
      - posthog_clickhouse:/var/lib/clickhouse
    ulimits:
      nofile:
        soft: 262144
        hard: 262144

volumes:
  posthog_postgres:
  posthog_redis:
  posthog_clickhouse:
```

Однако для production рекомендуется использовать официальный Helm chart или docker compose из репозитория PostHog. Конфигурация выше показывает ключевые компоненты. Реальный self-hosted setup:

```bash
git clone https://github.com/PostHog/posthog.git
cd posthog
docker compose -f docker-compose.hobby.yml up -d
```

PostHog поставляет `docker-compose.hobby.yml` — файл для self-hosted с правильными настройками ClickHouse, Kafka и всех зависимостей. Через 2-3 минуты UI доступен на `localhost:8000`. Создайте аккаунт, организацию и проект.

### Настройка трекинга событий

PostHog предоставляет JavaScript-сниппет для веб-приложений:

```html
<script>
  !function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],
  e.init=function(i,s,a){function g(t,e){var o=e.split(".");
  2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e]
  .concat(Array.prototype.slice.call(arguments,0)))}}
  (p=t.createElement("script")).type="text/javascript",
  p.async=!0,p.src=s.api_host+"/static/array.js",
  (r=t.getElementsByTagName("script")[0]).parentNode
  .insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:
  a="posthog",u.people=u.people||[],u.toString=function(t)
  {var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},
  u.people.toString=function(){return u.toString(1)+".people (stub)"},
  o="capture identify alias people.set people.set_once set_config"
  .split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},
  e.__SV=1)}(document,window.posthog||[]);
  posthog.init('YOUR_PROJECT_API_KEY', {
    api_host: 'http://localhost:8000'
  });
</script>
```

Для серверных приложений — Python SDK:

```bash
pip install posthog
```

```python
from posthog import Posthog

posthog = Posthog(
    project_api_key='YOUR_PROJECT_API_KEY',
    host='http://localhost:8000'
)

# Трекинг события
posthog.capture(
    distinct_id='user-123',
    event='purchase_completed',
    properties={
        'amount': 49.99,
        'currency': 'USD',
        'plan': 'pro',
        'source': 'pricing_page'
    }
)
```

Автозахват (autocapture) PostHog собирает клики, pageview, формы без дополнительного кода. Но кастомные события дают точность. Правило: autocapture для начала, кастомные события для ключевых конверсий.

## Docker setup: Metabase

Metabase проще в развёртывании. Один контейнер + БД для метаданных:

```yaml
# docker-compose.metabase.yml
version: '3.8'

services:
  metabase:
    image: metabase/metabase:latest
    ports:
      - "3000:3000"
    environment:
      MB_DB_TYPE: postgres
      MB_DB_DBNAME: metabase
      MB_DB_PORT: 5432
      MB_DB_USER: metabase
      MB_DB_PASS: metabase
      MB_DB_HOST: metabase-db
    depends_on:
      - metabase-db

  metabase-db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: metabase
      POSTGRES_PASSWORD: metabase
      POSTGRES_DB: metabase
    volumes:
      - metabase_data:/var/lib/postgresql/data

volumes:
  metabase_data:
```

```bash
docker compose -f docker-compose.metabase.yml up -d
```

Через минуту Metabase доступен на `localhost:3000`. Пройдите начальную настройку: язык, аккаунт администратора, подключение к базе данных.

### Единый docker compose

В production удобнее объединить оба инструмента в один стек. Ключевая часть: общая Docker-сеть, чтобы Metabase мог обращаться к ClickHouse PostHog.

```yaml
# docker-compose.analytics.yml
version: '3.8'

services:
  # === PostHog stack ===
  posthog:
    image: posthog/posthog:latest
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgres://posthog:posthog@posthog-db:5432/posthog
      REDIS_URL: redis://redis:6379/
      CLICKHOUSE_HOST: clickhouse
      SECRET_KEY: ${POSTHOG_SECRET_KEY}
      SITE_URL: ${POSTHOG_SITE_URL:-http://localhost:8000}
    networks:
      - analytics

  posthog-db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: posthog
      POSTGRES_PASSWORD: posthog
      POSTGRES_DB: posthog
    volumes:
      - posthog_pg:/var/lib/postgresql/data
    networks:
      - analytics

  redis:
    image: redis:7-alpine
    networks:
      - analytics

  clickhouse:
    image: clickhouse/clickhouse-server:24.3
    volumes:
      - clickhouse_data:/var/lib/clickhouse
    ports:
      - "8123:8123"  # HTTP-интерфейс для Metabase
    networks:
      - analytics

  # === Metabase ===
  metabase:
    image: metabase/metabase:latest
    ports:
      - "3000:3000"
    environment:
      MB_DB_TYPE: postgres
      MB_DB_DBNAME: metabase
      MB_DB_PORT: 5432
      MB_DB_USER: metabase
      MB_DB_PASS: metabase
      MB_DB_HOST: metabase-db
    depends_on:
      - metabase-db
      - clickhouse
    networks:
      - analytics

  metabase-db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: metabase
      POSTGRES_PASSWORD: metabase
      POSTGRES_DB: metabase
    volumes:
      - metabase_pg:/var/lib/postgresql/data
    networks:
      - analytics

networks:
  analytics:
    driver: bridge

volumes:
  posthog_pg:
  clickhouse_data:
  metabase_pg:
```

```bash
docker compose -f docker-compose.analytics.yml up -d
```

Результат: PostHog на `localhost:8000`, Metabase на `localhost:3000`, ClickHouse доступен внутри сети по имени `clickhouse`.

## Подключение Metabase к ClickHouse PostHog

Начиная с Metabase 54 (апрель 2025) поддержка ClickHouse встроена в официальный образ Metabase — отдельный драйвер устанавливать не нужно. Если вы используете более старую версию, скачайте jar из архивного репозитория `ClickHouse/metabase-clickhouse-driver` и подключите его через volume для плагинов. Для любого актуального деплоя переходите сразу к настройке подключения.

### Конфигурация подключения

В Metabase UI: Admin → Database → Add database:

| Параметр | Значение |
|----------|----------|
| Database type | ClickHouse |
| Host | clickhouse (имя сервиса в Docker) |
| Port | 8123 |
| Database name | posthog |
| Username | default |
| Password | (пусто, если не задан) |

После подключения Metabase просканирует таблицы. Основные таблицы PostHog в ClickHouse:

- `events` — все события (центральная таблица)
- `persons` — пользователи
- `person_distinct_id2` — маппинг distinct_id → person_id
- `session_replay_events` — данные session replay

## AI-промпты для генерации дашбордов

Самая трудоёмкая часть настройки аналитики: SQL-запросы и визуализации. AI ускоряет этот процесс в 5-10 раз. Ниже — промпты, проверенные на реальных проектах.

### Промпт 1: Обзорный дашборд продукта

```
Ты — senior data analyst. Я подключил Metabase к ClickHouse PostHog.

Таблица events содержит колонки:
- uuid (String)
- event (String) — название события
- properties (String) — JSON с произвольными свойствами
- timestamp (DateTime64)
- distinct_id (String) — идентификатор пользователя
- created_at (DateTime64)

Создай SQL-запросы для следующих карточек дашборда:

1. DAU/WAU/MAU за последние 30 дней (линейный график)
2. Top-10 событий за последние 7 дней (bar chart)
3. Retention Day 1 / Day 7 / Day 30 (таблица)
4. Конверсионная воронка signup → activation → purchase (funnel)
5. Среднее количество событий на пользователя в день (линейный график)

Формат: чистый SQL для ClickHouse. Каждый запрос с комментарием.
Используй JSONExtractString/JSONExtractFloat для работы с properties.
```

### Промпт 2: Revenue-дашборд

```
Контекст: ClickHouse PostHog, таблица events.
Кастомные события: purchase_completed (properties: amount, currency, plan),
subscription_started, subscription_cancelled, trial_started.

Создай SQL-запросы для revenue-дашборда:
1. MRR за последние 12 месяцев
2. ARPU (average revenue per user) помесячно
3. Churn rate помесячно
4. Revenue по планам (breakdown по plan из properties)
5. LTV когорт (по месяцу первой покупки)

ClickHouse-синтаксис. Оптимизированные запросы.
```

### Промпт 3: Генерация event taxonomy

```
Я запускаю SaaS-продукт: [описание продукта].
Основные фичи: [список фич].

Создай event taxonomy для PostHog:
1. Названия событий (snake_case, verb_noun формат)
2. Обязательные properties для каждого события
3. Группировка по категориям (onboarding, core_action, monetization, engagement)
4. Рекомендации по super properties (устанавливаются один раз на пользователя)

Формат: таблица с колонками Event | Category | Properties | Description.
```

### Пример сгенерированного запроса: DAU/WAU/MAU

Первая версия, которую обычно выдаёт AI, выглядит так — и не работает:

```sql
-- НЕ РАБОТАЕТ: distinct_id недоступен после GROUP BY day,
-- а оконная функция поверх уже посчитанного dau не может корректно
-- объединить пересекающиеся множества пользователей за соседние дни
SELECT
    toDate(timestamp) AS day,
    uniqExact(distinct_id) AS dau,
    uniqExact(distinct_id) OVER (
        ORDER BY toDate(timestamp)
        RANGE BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS wau
FROM events
GROUP BY day
```

Проблема в природе WAU/MAU: это не сумма дневных DAU (один и тот же пользователь, активный три дня подряд, не должен учитываться трижды), а честный uniqExact по «сырым» событиям за весь диапазон. Оконная функция над уже свёрнутым `dau` не может это восстановить — нужна агрегация на уровне отдельных пользователей, сохранённая как объединяемое состояние. Рабочий вариант — через комбинаторы `-State`/`-Merge`: считаем uniqExact-состояние по дням один раз, а затем сливаем состояния соседних дней оконной функцией:

```sql
-- DAU / WAU / MAU за последние 30 дней
-- Берём 59 дней сырых данных (30 отображаемых + 29-дневный запас для MAU),
-- чтобы окно было полным даже для самого раннего отображаемого дня.
WITH daily AS (
    SELECT
        toDate(timestamp) AS day,
        uniqExactState(distinct_id) AS dau_state
    FROM events
    WHERE timestamp >= now() - INTERVAL 59 DAY
      AND event != '$feature_flag_called'
    GROUP BY day
)
SELECT
    day,
    uniqExactMerge(dau_state) AS dau,
    uniqExactMerge(dau_state) OVER (
        ORDER BY day
        RANGE BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS wau,
    uniqExactMerge(dau_state) OVER (
        ORDER BY day
        RANGE BETWEEN 29 PRECEDING AND CURRENT ROW
    ) AS mau
FROM daily
WHERE day >= today() - 30
ORDER BY day
```

`uniqExactState` сохраняет по каждому дню полное множество distinct_id как объединяемый объект, а не просто число. `uniqExactMerge` в оконной функции объединяет эти множества по дням в пределах `RANGE BETWEEN ... PRECEDING`, что даёт корректный дедуплицированный подсчёт, а не сумму с двойным учётом. Важно: AI-генерация требует валидации. ClickHouse window functions имеют нюансы, и именно так выглядит типичная ошибка первого прохода — проверяйте каждый запрос на небольшом наборе данных перед добавлением на дашборд.

## Metabase API: автоматизация создания дашбордов

Ручное создание карточек в UI — нормально для 5-10 визуализаций. Для 20+ карточек Metabase API экономит часы.

### Создание карточки через API

```bash
# Получаем database_id
curl -s http://localhost:3000/api/database \
  -H "X-Metabase-Session: $SESSION_TOKEN" | jq '.[].id'

# Создаём карточку (вопрос)
curl -X POST http://localhost:3000/api/card \
  -H "Content-Type: application/json" \
  -H "X-Metabase-Session: $SESSION_TOKEN" \
  -d '{
    "name": "DAU / WAU / MAU",
    "dataset_query": {
      "type": "native",
      "native": {
        "query": "SELECT toDate(timestamp) AS day, uniqExact(distinct_id) AS dau FROM events WHERE timestamp >= now() - INTERVAL 30 DAY GROUP BY day ORDER BY day"
      },
      "database": 2
    },
    "display": "line",
    "visualization_settings": {
      "graph.x_axis.title_text": "Date",
      "graph.y_axis.title_text": "Users"
    }
  }'
```

### Промпт для AI: batch-создание через API

```
У меня есть Metabase API (localhost:3000) с ClickHouse database_id=2.
Session token: $SESSION_TOKEN.

Сгенерируй bash-скрипт, который через Metabase REST API:
1. Создаёт dashboard "Product Overview"
2. Создаёт 6 карточек (cards) с SQL-запросами к PostHog ClickHouse
3. Добавляет все карточки на dashboard с layout (2 колонки)

Карточки:
- DAU (line chart)
- Top Events (bar chart)
- Signup Funnel (funnel)
- Retention Table (table)
- Events per User (line chart)
- Active Users by Country (map)

Используй curl + jq. Каждый шаг с проверкой ответа.
```

AI сгенерирует готовый скрипт. Результат: полностью настроенный дашборд за 10 минут вместо 2 часов ручной работы.

## PostHog Feature Flags + Metabase: замкнутый цикл

Feature flags PostHog позволяют включать фичи для процента пользователей. Metabase показывает влияние на метрики. Вместе получается data-driven feature rollout.

### Настройка feature flag

В PostHog UI: Feature Flags → New Feature Flag:

```
Key: new-pricing-page
Rollout: 50% пользователей
Filters: country = US (опционально)
```

PostHog автоматически трекает событие `$feature_flag_called` с properties `$feature_flag` и `$feature_flag_response`.

### SQL-запрос в Metabase: A/B сравнение

```sql
-- Сравнение конверсии между вариантами feature flag
WITH flag_users AS (
    SELECT
        distinct_id,
        JSONExtractString(properties, '$feature_flag_response') AS variant
    FROM events
    WHERE event = '$feature_flag_called'
      AND JSONExtractString(properties, '$feature_flag') = 'new-pricing-page'
      AND timestamp >= now() - INTERVAL 7 DAY
    GROUP BY distinct_id, variant
),
purchases AS (
    SELECT distinct_id
    FROM events
    WHERE event = 'purchase_completed'
      AND timestamp >= now() - INTERVAL 7 DAY
    GROUP BY distinct_id
)
SELECT
    f.variant,
    count(DISTINCT f.distinct_id) AS users,
    count(DISTINCT p.distinct_id) AS purchasers,
    round(count(DISTINCT p.distinct_id) / count(DISTINCT f.distinct_id) * 100, 2) AS conversion_rate
FROM flag_users f
LEFT JOIN purchases p ON f.distinct_id = p.distinct_id
GROUP BY f.variant
ORDER BY f.variant
```

Этот запрос показывает конверсию в покупку для каждого варианта feature flag. Добавьте на дашборд — и у команды всегда актуальные данные по A/B тестам.

## Production-конфигурация: что нужно сделать перед выкаткой

### Безопасность

**Секреты через переменные окружения.** Никаких захардкоженных паролей в docker compose:

```bash
# .env
POSTHOG_SECRET_KEY=generated-64-char-secret
CLICKHOUSE_PASSWORD=strong-password
METABASE_DB_PASS=another-strong-password
```

**Reverse proxy с HTTPS.** Caddy или nginx перед PostHog и Metabase:

```
# Caddyfile
analytics.yourdomain.com {
    reverse_proxy posthog:8000
}

bi.yourdomain.com {
    reverse_proxy metabase:3000
}
```

**Ограничение доступа к ClickHouse.** Порт 8123 не должен быть доступен извне. Только внутренняя Docker-сеть:

```yaml
clickhouse:
  image: clickhouse/clickhouse-server:24.3
  # НЕ пробрасываем порт наружу в production
  # ports:
  #   - "8123:8123"
  networks:
    - analytics
```

### Бэкапы

Три компонента требуют бэкапов:

1. **PostgreSQL (PostHog)** — метаданные, пользователи, настройки
2. **ClickHouse** — данные событий (самый большой объём)
3. **PostgreSQL (Metabase)** — дашборды, вопросы, настройки

```bash
#!/bin/bash
# backup.sh — запускать через cron ежедневно
DATE=$(date +%Y%m%d)
BACKUP_DIR=/backups/analytics

# PostHog PostgreSQL
docker exec posthog-db pg_dump -U posthog posthog | gzip > $BACKUP_DIR/posthog_pg_$DATE.sql.gz

# Metabase PostgreSQL
docker exec metabase-db pg_dump -U metabase metabase | gzip > $BACKUP_DIR/metabase_pg_$DATE.sql.gz

# ClickHouse — встроенный механизм бэкапов
docker exec clickhouse clickhouse-backup create "backup_$DATE"
```

### Мониторинг

PostHog и Metabase предоставляют health-эндпоинты:

```bash
# PostHog
curl -f http://localhost:8000/_health || echo "PostHog down"

# Metabase
curl -f http://localhost:3000/api/health || echo "Metabase down"

# ClickHouse
curl -f http://localhost:8123/ping || echo "ClickHouse down"
```

Добавьте в любую систему мониторинга: UptimeRobot, Grafana, простой cron с уведомлением в Telegram.

## Частые проблемы и решения

**ClickHouse OOM при больших запросах.** Ограничьте память для отдельных запросов:

```sql
SET max_memory_usage = 2000000000;  -- 2 ГБ на запрос
```

В настройках пользователя ClickHouse для Metabase:

```xml
<profiles>
  <metabase>
    <max_memory_usage>2000000000</max_memory_usage>
    <max_execution_time>60</max_execution_time>
  </metabase>
</profiles>
```

**Metabase таймаут на тяжёлых запросах.** Увеличьте таймаут через переменную окружения:

```yaml
metabase:
  environment:
    MB_DB_CONNECTION_TIMEOUT_MS: 60000
    MB_DB_QUERY_TIMEOUT_MINUTES: 30
```

**PostHog events не появляются.** Проверьте: API-ключ верный, `api_host` указывает на правильный адрес, событие не отфильтровано. PostHog UI → Activity → Live Events показывает поток событий в реальном времени.

**Metabase не видит новые таблицы ClickHouse.** Admin → Databases → Sync database schema. Автоматическая синхронизация происходит раз в час.

## Итоговая архитектура

```
┌─────────────────────────────────────────────────────────┐
│                      Users / App                         │
│                          │                               │
│                    posthog-js SDK                         │
│                          │                               │
│                    ┌─────▼─────┐                         │
│                    │  PostHog  │ :8000                    │
│                    │   (App)   │                          │
│                    └─────┬─────┘                         │
│                          │                               │
│              ┌───────────▼───────────┐                   │
│              │     ClickHouse        │                   │
│              │  (events storage)     │                   │
│              └───────────┬───────────┘                   │
│                          │                               │
│                    ┌─────▼─────┐                         │
│                    │ Metabase  │ :3000                    │
│                    │   (BI)    │                          │
│                    └───────────┘                         │
└─────────────────────────────────────────────────────────┘
```

Данные текут в одном направлении: приложение → PostHog → ClickHouse → Metabase. PostHog отвечает за продуктовую аналитику (воронки, retention, feature flags). Metabase строит произвольные SQL-отчёты поверх тех же данных.

## Что дальше

Три направления развития стека после базовой настройки:

**Алерты.** Metabase поддерживает email- и Slack-уведомления при достижении пороговых значений. Настройте алерт на падение DAU ниже N или на аномальный рост ошибок.

**Embeddable dashboards.** Metabase позволяет встраивать дашборды в ваше приложение через iframe с JWT-аутентификацией. Клиенты видят свою аналитику прямо в продукте.

**dbt + data modeling.** По мере роста объёма данных сырые SQL-запросы к events становятся медленными. dbt создаёт промежуточные модели (materialized views) в ClickHouse. Metabase работает с готовыми моделями вместо сырых данных.

Подробнее о мониторинге LLM-компонентов в аналитическом стеке: [LLM Observability с Langfuse](/ru/blog/llm-observability-langfuse/).

Self-hosted аналитика требует начальных вложений в настройку. Зато данные остаются у вас, нет лимитов на объём, и стоимость не растёт с количеством событий. PostHog + Metabase покрывают большую часть аналитических задач стартапа на стадии от MVP до Series A.

---

*Нужна помощь с настройкой аналитики? Я помогаю стартапам внедрять AI-решения и строить продукты — [belov.works](https://belov.works).*

## FAQ

**Как управлять schema migrations в ClickHouse после обновления PostHog?**

PostHog прогоняет собственные миграции при обновлении, но Metabase не подхватывает изменения типов колонок или переименований автоматически. После каждого обновления PostHog запускайте ручную синхронизацию схемы в Metabase (Admin → Databases → Sync database schema) и проверяйте сохранённые вопросы, работающие с таблицами `events` и `persons`. Надёжнее строить вопросы в Metabase поверх ClickHouse-представлений (views), а не сырых таблиц — это добавляет уровень абстракции, при котором переименование колонки в базовой таблице требует изменения только view, а не каждого отдельного запроса.

**Каков практический предел производительности ClickHouse для стартапа без выделенного data engineer?**

При объёме до 500 миллионов событий правильно написанные запросы к таблице `events` с фильтром `WHERE timestamp >=` будут возвращать результаты за секунды без дополнительной настройки. После этого порога основным узким местом становится отсутствие materialized views для частых агрегаций. Настройки таймаута (`MB_DB_QUERY_TIMEOUT_MINUTES`) дают дополнительное время, но реальное решение при росте объёма — создание materialized views в ClickHouse для retention, DAU/WAU/MAU и воронок. AI-модель может сгенерировать определения этих views по SQL-запросам, уже присутствующим в ваших дашбордах.

**Может ли Metabase одновременно работать с ClickHouse PostHog и отдельной PostgreSQL базой данных?**

Да. Metabase поддерживает несколько подключений к базам данных; каждое отображается как отдельный источник данных в конструкторе вопросов. Это удобно, когда PostHog трекает поведенческие события, а транзакционные данные (заказы, подписки, обращения в поддержку) хранятся в отдельном Postgres. Кросс-базовые джоины внутри одного вопроса Metabase невозможны, но можно создать дашборд, объединяющий карточки из обоих источников, или использовать встроенный PostgreSQL-движок ClickHouse для прямых запросов к Postgres-таблицам из ClickHouse SQL.
