Why we rebuilt our data warehouse on DuckDB over ClickHouseУ первой версии data warehouse в PostHog была скромная, но понятная задача: дать компании пожить подольше без найма дата-инженера.
И какое то время, она с этим отлично справлялась — для стартапа человек на 20, где CEO сам пишет SQL по вечерам, это было именно то, что нужно.
С ростом компании появились первые проблемы.
PostHog становится главным инструментом для понимания бизнеса, а потом штат перерастает 30-50 человек, вопросы усложняются, и появляется первый дата-инженер. Он смотрит на то, что умеет PostHog, разводит руками — и начинает потихоньку выгружать данные во внешний warehouse.
Дальше по накатанной: PostHog превращается в трубу, через которую данные просто проходят транзитом, а реальный анализ бизнеса переезжает куда-то ещё.
Так почему дата-инженерам было некомфортно на платформе?Первая боль — мультитенантность. PostHog крутится на общем кластере ClickHouse, и это отлично работает, пока запросы прилетают из браузера и возвращаются за пару минут.
Но у data warehouse совсем другая логика — модельный запрос может спокойно крутиться часами или сутками.
На общем кластере это просто не потянуть: ноды и так периодически перезапускаются, а бесконечный поток тяжёлых запросов рано или поздно положит всё приложение.
Вторая — сам ClickHouse как query engine. Для аналитики по событиям он бесподобен, когда схема и запросы заточены под его сильные стороны.
Но как general-purpose warehouse — не очень.
Нет cost-based query optimizer, поэтому приходится вручную подгонять SQL под схему, хотя дата-инженеры хотят писать декларативный SQL и не думать об этом. Поддержка
S3/Iceberg/Deltalake долго была сырой — по факту работали с голым Parquet, без удобств каталогизации.
А ещё результаты запросов иногда менялись между релизами ClickHouse — свои тесты это ловят, но невозможно протестировать все возможные формы клиентских данных.
Третья — data tooling. Хотелось использовать dbt, следовать нормальным практикам моделирования данных — но открыть прямой доступ к кластеру ClickHouse означало бы усугубить проблему мультитенантности.
А ещё свой query language HogQL особо никто, кроме PostHog, не поддерживает.
Решили пересобрать всё на DuckDBКаждая организация теперь получает свой собственный, полностью изолированный инстанс DuckDB — никакого шеринга с другими клиентами.
Инстансы засыпают, когда простаивают, и просыпаются сами, как только прилетает запрос.
Подключаться можно через Postgres Wire protocol — то есть буквально через psql, любой BI-инструмент или MCP (привет, Claude), и всё просто работает.
Отдельная находка — DuckHog, расширение DuckDB, которое позволяет забрать кусок данных к себе локально, поработать с ним через pandas, polars или сам DuckDB, а потом записать результат обратно.
Для агентов, которые быстро итерируют по данным, это гораздо приятнее, чем гонять каждый запрос через кластер.
А под капотом всё держится на DuckLake, которая разводит storage и compute — данные лежат себе в S3 независимо от того, что их запрашивает, так что PostHog не привязан к DuckDB навечно.
Самое приятное — всё это уже готово из коробки.
События PostHog и так зеркалируются в S3 по организациям, поэтому при запуске warehouse ваши данные уже там.
То же со Stripe, Postgres и другими источниками — подключил, и всё автоматически льётся в общий warehouse.
А теперь про агентовData warehouse — это context layer для AI-агентов.
Если продуктовые данные лежат в PostHog, финансовые — в отдельном warehouse, а данные о пользователях — вообще где-то ещё, любой агент будет работать с рваной картиной мира или тратить токены, чтобы собрать её по кусочкам.
А когда всё в одном месте — агент может не просто сказать
воронка просела, а выдать полную картину: revenue impact, какие когорты затронуты, что у этих пользователей общего, план действий — и заодно уже открытый PR с фиксом.
Вот это и есть тот уровень качества сигнала, который делает агентные воркфлоу реально полезными.
♾️original post♾️@tldr_data