← Teardowns

How Is PostHog Built? The Open-Source Analytics Stack, Deconstructed

A technical teardown of PostHog's architecture — ClickHouse, Kafka, Django, and the open-core moat that makes it more than just a Mixpanel clone.

What PostHog actually is, underneath the marketing

PostHog markets itself as 'the open-source alternative to Mixpanel, Amplitude, and Google Analytics,' but that undersells what's actually running under the hood. It's not a single product — it's a suite: product analytics, session replay, feature flags, A/B testing, surveys, and a CDP-lite data pipeline, all bolted onto one event schema. The pitch is 'one platform instead of eight vendors,' and architecturally that's true — everything ultimately writes to the same events table and gets sliced by the same query engine.

That single-events-table decision is the most important architectural choice in the whole product. Every pageview, click, custom event, feature flag evaluation, and session recording frame gets normalized into one massive append-only stream. Once you understand that, the rest of the system — how it's built, how it scales, why it chose the tools it chose — makes a lot more sense.

The core stack: Django, Kafka, ClickHouse

The application layer is a fairly boring, fairly good Django monolith (Python) serving the web app and REST API, with a Node/TypeScript layer for some newer services and a Rust component for the ingestion hot path (they rewrote part of ingestion in Rust for latency and cost reasons). Nothing exotic — this is the part any competent team could reproduce in a few months.

The part that actually matters is the data pipeline. Events land via HTTP capture endpoints, get pushed onto Kafka, and get consumed into ClickHouse — a columnar OLAP database built for exactly this workload: billions of narrow rows, ad-hoc aggregation queries, funnels, retention curves. ClickHouse is the real engineering bet PostHog made early, and it's the same bet companies like Snowflake customers, Sentry, and Cloudflare Analytics have made for similar reasons: row-store Postgres/MySQL falls over past a few hundred million events; ClickHouse doesn't.

Postgres is still there, holding the boring relational stuff — users, orgs, feature flag definitions, dashboards, permissions. Redis handles caching and queues. So the real stack is: Django for CRUD and auth, Kafka for durable ingestion buffering, ClickHouse for the actual analytics queries, Postgres for metadata. That's a pattern you'll see in almost every serious analytics product built after 2018.

Why this is genuinely hard to clone well

Anyone can spin up a Next.js dashboard that draws line charts from a Postgres query — that's a weekend project, and it's exactly the kind of thing an AI coding tool will happily generate for you. What you can't one-shot is a system that ingests events reliably at scale, survives traffic spikes without dropping data, deduplicates retries, backfills late-arriving events, and still returns a 30-day retention query in under two seconds against a billion-row table.

The hard parts are invisible in a demo: schema migrations on a live ClickHouse cluster with petabytes of data, sharding strategy, materialized views for the common query shapes (funnels, trends, lifecycle), and query planners that translate a UI-built funnel into efficient SQL. PostHog has spent years optimizing person-property joins and merging identity graphs (the 'person' concept — merging anonymous and identified users) which sounds trivial until you've had to do it at scale without corrupting historical data.

This is the crux of the technical-cloneability question: the CRUD shell — dashboards, flag toggles, project settings — is trivially rebuildable by prompting an AI tool. The ingestion and query engine underneath it is not a prompt-sized problem. It's a multi-year systems engineering investment, and it's the part that actually breaks when you try to shortcut it.

Feature flags and session replay are separate hard problems, not features

It's worth noting PostHog didn't build one hard thing — it built three. Feature flags need to evaluate in single-digit milliseconds at the edge, with local evaluation SDKs and bootstrap payloads so client apps don't block on a network call. Session replay means capturing DOM mutations client-side (a fork/extension of the rrweb library), compressing them, storing large blobs cheaply (usually object storage, not the OLAP database), and reassembling a scrubbable video-like timeline on playback.

Each of these is a legitimate standalone SaaS business elsewhere — LaunchDarkly for flags, FullStory/Hotjar for replay. PostHog bundling all three under one identity graph is a genuine product decision with real engineering cost, not just marketing bundling. That's a meaningful moat signal: the value isn't just 'analytics,' it's the fact that a session replay is linked to the same person ID as the funnel drop-off and the flag variant they saw, without you stitching that together yourself.

The open-core business model: where the real moat is

PostHog is open source (MIT license for the core), which means the code is not the moat — anyone can `git clone` it today. So where's the actual business defensibility? Three places: hosting complexity, the open-core paywall, and distribution.

First, self-hosting PostHog at scale is genuinely painful — running Kafka and ClickHouse clusters reliably is a real ops burden most teams don't want, so most users pay for PostHog Cloud rather than self-host, even though they legally could run it for free. That's the same dynamic that makes GitLab, Elastic, and MongoDB Atlas real businesses despite open code: the moat isn't the source, it's 'we run this better than you want to.'

Second, some features (like advanced permissioning, certain enterprise SSO options, and some scale-tier pricing) sit behind a commercial license, not the MIT core — classic open-core. Third, and most underrated: PostHog's moat is genuinely in distribution and trust compounding — a huge library of integration SDKs (every major language and framework), a large plugin/app ecosystem, and years of SEO-driven content and community goodwill that a fork starts from zero on. None of that is copyable by forking a repo or prompting a clone.

What an AI tool can and can't rebuild here

If you're evaluating 'could I just prompt my way to a PostHog competitor,' be honest about which layer you're rebuilding. A dashboard UI with charts, a flags admin panel, a basic event capture endpoint writing to Postgres — yes, an AI coding tool will get you a demo-quality clone in an afternoon. That's the technical-cloneability score tanking to 'low effort, low risk' territory.

What it won't get you is the part that makes PostHog worth $100M+ in revenue: a query engine that stays fast at billion-row scale, an ingestion pipeline that doesn't lose events during a traffic spike, an identity-merge system that doesn't quietly corrupt your historical data, and years of integrations that make switching costs real for existing customers. The moat isn't the chart library. It's the boring infrastructure nobody wants to operate, plus the compounding SDK/ecosystem lock-in that took years to build and can't be prompted into existence overnight.

The takeaway for builders evaluating analytics tools like this

If you're sizing up PostHog itself, or a competitor, or thinking about building your own analytics layer, separate the two axes cleanly. Technical cloneability: high on the surface UI, low on the ingestion/query core — this is not a weekend AI-generated project once you need real scale. Business moat: low from source-code secrecy (it's open source, there's nothing to hide), high from operational complexity, open-core monetization, and ecosystem lock-in.

That combination — clonable surface, hard-to-clone infrastructure, moat built on ops and distribution rather than secrecy — is actually the healthiest pattern in modern SaaS. It's the same shape as Supabase, Sentry, and GitLab. If you're building something similar, plan your moat around the parts nobody wants to self-host, not around hiding your React components.

Want the same teardown for any site?

Analyze a site →