> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt # What you actually get when you pay for an event Canonical URL: https://posthog.com/docs/billing/what-you-pay-for-per-event > **Cloud region:** This page uses US Cloud hosts. For an EU Cloud project, use `https://eu.posthog.com` instead of `https://app.posthog.com` (app host for links). ## On this page - [The price](#the-price) - [What happens to one event](#what-happens-to-one-event) - [If you build it yourself](#if-you-build-it-yourself) - [Costs that arrive later](#costs-that-arrive-later) - [Your own ledger](#your-own-ledger) - [When building is the right call](#when-building-is-the-right-call) - [How to lower your PostHog bill](#how-to-lower-your-posthog-bill) When you pay for an event in PostHog, you pay for more than a row in a database. The price covers the work to collect that event, keep it safe, make it useful, store it for many years, query it as often as you like, and send it to other tools. It also buys peace of mind: the pipeline is built so your data arrives complete and correct, and when something breaks, our engineers get paged, not yours. This page explains each of those jobs, so you know what the price includes. It's also useful if you're thinking about building your own pipeline, for example on ClickHouse. AI agents make the first version much faster to build than it used to be, so that's a fair option to consider. This page helps you compare the two like with like. You don't need to be an engineer to follow it. It helps, but every section starts in plain English and ends with the technical detail so it can help users at all levels. > **No bill yet?** Every PostHog product has a free tier, and they're big enough that 97% of users never pay us a penny. If you're inside the free tier, your events cost nothing. ## The price An event is one thing that happens in your product: someone views a page, clicks a button, signs up, or pays you. [Product Analytics](https://posthog.com/product-analytics.md) bills per event. The first 1 million events each month are free, and the price per event drops as you send more. Below are the live rates for [anonymous events](https://posthog.com/docs/data/anonymous-vs-identified-events.md), which don't carry a person profile. 1,000,000events/month $0 1M10M50M #### Allocation #### Price #### Your selection #### Subtotal ##### First 1 million events ##### **$0.0000000**/event 1,000,000 $0 ##### 1-2 million ##### **$0.0000500**/event 0 $0 ##### 2-15 million ##### **$0.0000343**/event 0 $0 ##### 15-50 million ##### **$0.0000295**/event 0 $0 ##### 50-100 million ##### **$0.0000218**/event 0 $0 ##### 100-250 million ##### **$0.0000150**/event 0 $0 ##### 250 million+ ##### **$0.0000090**/event 0 $0 Identified events add a person profile charge on top, because person processing is [the most expensive step in our pipeline](https://posthog.com/blog/analytics-pricing.md#why-are-anonymous-events-so-much-cheaper). The [pricing page](https://posthog.com/pricing.md) has the full tables for both. Those are the only line items for events. We don't charge to store them, to query them in PostHog, or per seat, so you can run as much analysis as you like with as many colleagues as you like. ## What happens to one event Every analytics setup, bought or built, has the same job. - You have to get data in from your product, and often from other tools too. - You have to keep it safe for as long as anyone might need it, and nobody knows when that'll be. - You have to keep it available for when you want to use it, or send it off wherever you want it to go. That sounds like three jobs. In practice it's six, and each one has its own ways it can go wrong. ### Step 1: Getting it in Say you ship a mobile app. Someone opens it on a train, taps through a few screens, loses signal, and closes it. Those taps still need to reach you once the phone is back online, in the right order and with the right time on them. Meanwhile your website has a different problem: some of your visitors run ad blockers that strip out tracking scripts. Finally, your backend records the events that matter most, like signups and payments, straight from your servers. It's rarely just your product, either. Sooner or later someone wants Stripe payments or HubSpot deals next to product usage, so they can see which features your paying customers actually use. So you need to pull in data from those places too, maintain the pipeline, and handle the associated costs. **How it works at PostHog:** [Our SDKs](https://posthog.com/docs/libraries.md) batch, compress, and retry. The capture service decompresses the payload, validates it, and corrects the timestamp using the time your client says it sent the batch, so a phone that was offline for an hour still lands its events in the right minute. It also adds a UUID if the SDK didn't. If capture can't write to the queue, it returns an error and the SDK tries again, so a short outage on our side doesn't lose your data. Finally, a [reverse proxy](https://posthog.com/docs/advanced/proxy.md) lets you send events from your own domain, past ad blockers. For data from other tools, [sources](https://posthog.com/docs/data-pipelines/sources.md) sync [Stripe](https://posthog.com/docs/data-pipelines/sources/stripe.md), HubSpot, Postgres, S3, and more on a schedule, so you can query them next to your events with SQL. Synced rows have their own free tier and bill per row, separately from events. Without it, events from a phone with the wrong clock land on the wrong day, retries count twice, and ad blockers quietly create a blind spot in your data. ### Step 2: Not losing it Data, like taxes, has a habit of arriving all at once. You hit the front page of Hacker News, a spam bot finds your signup form, or a buggy release fires the same event in a loop. Meanwhile, the database at the end of the line needs a restart now and then for upgrades. None of that should lose you data, but any of them could. **How it works at PostHog:** Every event goes into [Kafka](https://posthog.com/docs/how-posthog-works/ingestion-pipeline.md) before anything else touches it, and capture doesn't reply to your SDK until Kafka has acknowledged the write on every in-sync replica. The queue absorbs launch-day spikes and bots, and waits out database outages. Events from the same user stay in order. If a single ID sends more than about 5,000 events a minute, it moves to an overflow lane so it can't slow anyone else down. Nothing gets dropped, but while that ID is in the overflow lane, its events can process out of order and skip person profile creation and updates. You'll get an [ingestion warning](https://posthog.com/docs/data/ingestion-warnings.md) when it happens. If an ingestion worker crashes halfway through a batch, Kafka redelivers it. Anything we can't process goes to a dead letter queue instead of disappearing. Without it, a traffic spike or a database restart can mean you lose your precious data for good. ### Step 3: Making it mean something Raw events are messy. Your iOS app sends `Signed Up`, your web app sends `signup_completed`, and last week's release misspelled a property name. Someone reads your blog on their phone at lunch and signs up on their laptop that evening, and as far as the raw data knows, that's two strangers. Before anyone can trust a chart, the data needs checking and joining up. **How it works at PostHog:** Ingestion validates each event, drops anything older than a limit you set, and runs your [transformations](https://posthog.com/docs/data-pipelines/transformations.md). It adds country and city from GeoIP, gives [cookieless](https://posthog.com/tutorials/cookieless-tracking.md) events a daily-rotating hash instead of a cookie, and attaches UTM and referrer data to the [session](https://posthog.com/docs/data/sessions.md). Every event and property name goes into a catalog, which is how the UI, SQL autocomplete, and [PostHog AI](https://posthog.com/docs/posthog-ai.md) know what exists. If something's wrong with an event, an [ingestion warning](https://posthog.com/docs/data/ingestion-warnings.md) tells you which one. When two names mean the same thing, you can combine them into one [action](https://posthog.com/docs/data/actions.md) or rename one with a transformation. Identified events also go through [identity resolution](https://posthog.com/docs/product-analytics/identity-resolution.md). We create the person, merge their anonymous history when they identify, and update their properties in order. That's what the person profile charge pays for, and it's the hardest part to build yourself. Until something merges the phone and the laptop, every funnel that crosses signup is wrong. Without it, one platform renames a property, one metric quietly splits in two, and nobody notices until your next shareholder meeting. ### Step 4: Storing it for years Simply put: you don't know which questions you'll need to ask next year. Your board wants to see how this year's signups compare with your first cohort. A new PM wants to know whether the redesign two years ago actually worked. You can only answer those sorts of questions if the data from back then is still there and still fast to query. **How it works at PostHog:** Events land in a sharded, replicated ClickHouse cluster, with properties compressed using ZSTD. Hot data (that which you use regularly) sits on local NVMe and [moves to cheaper tiers](https://posthog.com/handbook/engineering/clickhouse/clusters.md#storage-tiers) as it ages. Every week we look at slow queries and materialize the columns that would make them fast. We're also [rebuilding the storage format](https://posthog.com/blog/changing-event-storage.md) so each property is stored once, with its real type, which makes common queries up to 2x faster. GDPR deletions run as batched jobs, because deleting anything from ClickHouse means rewriting whole partitions. Paid plans [keep events for many years](https://posthog.com/docs/data/events-retention.md) and free plans for one. You can set a shorter window if you need it, however. Without all this, a database that keeps only one copy of your data can lose it when a disk fails, and queries get slower as the data grows – a problem that's small when you're handling a few thousand events for your hobby project, but colossal when you're handling millions and billions of events for your business. ### Step 5: Querying it as often as you like Data is only worth keeping if people actually use it. Your PM builds a funnel for the new checkout. Your CEO opens the same dashboard every Monday morning. An engineer writes SQL to chase a bug, and someone in customer success asks PostHog AI which accounts stopped using a feature last week. They're all reading the same events at the same time, and none of them should have to wait for the others. (Well, maybe the PM.) **How it works at PostHog:** Funnels, retention, paths, lifecycle, [dashboards](https://posthog.com/docs/product-analytics/dashboards.md), [SQL](https://posthog.com/docs/data-warehouse/sql.md), and [PostHog AI](https://posthog.com/docs/posthog-ai.md) all run on the same events, and the compute for those queries is in the event price. We run guard rails so one query can't take a cluster down. A query gets 60 seconds by default and 10 minutes in the background, and each organization has a concurrency limit. Inside those limits, we don't meter queries. ### Step 6: Getting it out Sometimes the data needs to go somewhere else entirely. Your data team wants it in Snowflake next to everything else the company tracks. Your sales team wants a Slack message when a big account signs up, or a HubSpot contact updated when someone upgrades. And if you ever leave PostHog, you want every event to come with you. **How it works at PostHog:** [Batch exports](https://posthog.com/docs/data-pipelines/batch-exports.md) can send events to S3, Snowflake, BigQuery, Postgres, Redshift, Databricks, or Azure as JSON or Parquet, on a schedule you set. The first 1 million rows you export each month are free. After that, exports bill per row under [Data Pipelines pricing](https://posthog.com/pricing.md), not the event price. [Destinations](https://posthog.com/docs/data-pipelines/destinations.md) send events to tools like [Slack](https://posthog.com/docs/data-pipelines/destinations/slack.md), [HubSpot](https://posthog.com/docs/data-pipelines/destinations/hubspot.md), and Customer.io as they happen. They have their own free tier and bill separately from events too. The [query API](https://posthog.com/docs/api/query.md) returns anything SQL can express. If you leave, your data leaves with you. Without it, every tool that wants your data needs its own export job, and each one needs its own upkeep. ## If you build it yourself Every one of those jobs still exists when you run the pipeline yourself. This table shows what each one looks like on both sides. The second column is what we run for you, the third is what you'd run instead, and the last is when the job needs time from your team. It assumes your build runs in production for the long term, and that someone on your team owns it. | Job | What PostHog runs | What you run instead | When it needs your team | | --- | --- | --- | --- | | Getting it in | SDKs for web, iOS, Android, React Native, Flutter, and server SDKs in Node, Python, Go, Java, Ruby, PHP, .NET, and more. A public capture endpoint. Sources that sync Stripe, HubSpot, and databases. | An SDK for every platform you ship on. An endpoint on the public internet. A sync job for every other tool your team wants data from. | When a mobile release changes how events are sent | | Not losing it | Kafka with replication, overflow lanes, a dead letter queue, and replay after a crash | A queue in front of the database, or direct inserts with their own retry logic | When traffic spikes or the database restarts | | Making it mean something | Validation, GeoIP, cookieless hashing, session attribution, a definitions catalog, and warnings | A transform step for every rule, plus a catalog of event and property names | When one platform renames a property | | Knowing who did it | Person profiles, anonymous-to-identified merges, and property updates in order | An identity table, merge logic that copes with two devices identifying at once, and backfills when it gets it wrong | When one customer shows up as two | | Storing it | Sharding, replication, tiering, compression, materialized columns, backups, and GDPR deletes | ClickHouse operations, upgrades validated against your real queries, and backups with tested restores | When an upgrade changes a query result | | Querying it | Insights, SQL, AI, caching, and per-organization limits | A dashboard or BI tool, plus limits so one query can't slow down everyone else's | When one large query slows down the cluster | | Getting it out | Batch exports, real-time destinations, and the query API | An export job or a webhook for every tool that wants the data | When an export job stops | ## Costs that arrive later A build estimate from an agent usually covers the first version of the system: the servers, the storage, and the setup. The costs below arrive later, so estimates often leave them out, whether a person or an agent writes them. ### Storage for years, not months Storage looks cheap in month one, because there's only one month of it. Paid plans keep events for many years, so a fair comparison costs the same window. Your storage bill grows every month: in month 12 you're paying to store 12 months of events, and in month 48 you're paying for 48. The ledger below works out what that adds up to at your volume, your cloud's price per GB-month, and at least two replicas. ### Compute for as long as you keep the data Every event gets read over and over. Each dashboard refresh, funnel, cohort recalculation, and SQL query reads it again, and all of that is in the price. Asking [PostHog AI](https://posthog.com/docs/posthog-ai.md) spends [AI credits](https://posthog.com/docs/posthog-ai/pricing.md) on top, but the queries it runs are covered. Remember the CEO's Monday morning dashboard? Now picture the whole company opening theirs at the same time. A cluster you run has to be big enough for that moment. For the rest of the week it mostly sits idle, and it bills by the hour the whole time. ### Scaling you didn't plan for Traffic doesn't grow in a straight line. A launch, a bot, an SDK stuck in a retry loop, or an acquisition can multiply your event volume in a day. Our pipeline absorbs that with Kafka, overflow lanes, and clusters sized for our whole customer base. A cluster you run needs room for those days too, or a plan for when it runs out. ### Time you don't spend on your product Every hour someone spends upgrading ClickHouse or fixing an SDK is an hour not spent on the thing your customers pay you for. The ledger counts those hours at a loaded rate. At an early-stage company, the bigger cost can be a feature that ships later because an engineer was busy with the pipeline. ### The features you'll be asked for next Your first build gives you an events table and a dashboard. A week later, someone asks for a [funnel](https://posthog.com/docs/product-analytics/funnels.md). Then retention, then [cohorts](https://posthog.com/docs/data/cohorts.md), then a way to target a feature flag at one of those cohorts. Every request is reasonable, and every one is another system to build and maintain. This adds a lot of work and scope over time. You can trust us on that. In PostHog, the same events already power [feature flag targeting](https://posthog.com/docs/feature-flags.md), [experiment metrics](https://posthog.com/docs/experiments.md), and the filters in [Session Replay](https://posthog.com/docs/session-replay.md). You pay for an event once, and every product can use it. An event store you build talks to nothing until you write the connection yourself. Our post on [building your own feature flags](https://posthog.com/blog/build-or-buy-feature-flags.md) covers the same trade-off. ### Trust Data is only useful if people believe it. A wrong number costs more than the time it takes to fix, because of the decisions people made with it first. You want to be able to put the numbers in front of a board or an investor without an asterisk. We have [SOC 2](https://posthog.com/docs/privacy/soc2.md), [HIPAA](https://posthog.com/docs/privacy/hipaa-compliance.md), and GDPR controls, and a public [status page](https://posthog.com/status.md). When [we lost Logs data in February 2026](https://posthog.com/handbook/company/post-mortems/2026-02-20-posthog-us-logs-data-loss.md), we published what happened and what we changed. If you build your own, those controls and that reporting become your team's job too. ## Your own ledger This is where you do the math. You'll want an engineer for the technical rows, like bytes per event and compute nodes, but anyone can fill in the rest. Fill this in with your numbers. If an agent is helping with your estimate, ask it to fill this in too and say where each number came from. | Input | Your number | Notes | | --- | --- | --- | | Events per month | | Your [billing page](https://app.posthog.com/organization/billing) shows it | | Compressed bytes per event | | Measure it on a sample of your real events in ClickHouse | | Replicas | | At least 2, or a disk failure is data loss | | Months retained | | How far back you need to query. Paid plans keep [many years](https://posthog.com/docs/data/events-retention.md) | | Storage price per GB-month | | Your cloud's list price for the tier you use | | Compute nodes × hourly price | | Ingestion and query nodes, 730 hours a month | | Queue | | Managed Kafka or equivalent | | Engineer hours per month | | Upgrades, schema changes, backups, SDK maintenance | | On-call | | Who, and what it costs them | In plain English, work out how much data you'll store by a given month and what that costs. Add the servers and the people, then divide by the number of events you send. As a formula: ``` GB stored at month N = events × bytes × replicas × min(N, months retained) ÷ 1,000,000,000 storage at month N = GB stored × price per GB-month monthly total = storage + compute + queue + (engineer hours × loaded rate) + on-call your cost per event = monthly total ÷ events per month ``` Compare the last line to [a PostHog bill](https://posthog.com/pricing.md) at the same volume. Take the monthly total from the [pricing calculator](https://posthog.com/pricing.md), with any add-ons you need, and divide it by your monthly events. The free million and the falling tiers mean that average comes out lower than the rates at the top of this page. Run it for month 1, then again for month 36. If an agent is doing the math, point it at our [pricing guide for agents](https://posthog.com/pricing/agent-estimates.md) for the PostHog side. The ledger only counts the costs you can put a price on. It leaves out trust, correct data, time away from your product, and the features you'll be asked to build next. Those are real costs too, so weigh them when you compare the two totals. ## When building is the right call Building your own pipeline is the better choice for some teams. These are the cases where we'd build it too. **You sell analytics infrastructure.** The pipeline is your product, so the engineering time is the business, not overhead. **You already run ClickHouse for something else**, and a data team treats it like a product, with on-call, upgrades, and tested backups. Adding an events table to a cluster you already operate is a very different decision from standing one up. **Your data doesn't fit an events table**, like wide logs, sensor-rate time series, or rows you need to update in place. Our pipeline is built for append-only events, so a different tool may suit you better. If you're not sure which side you're on, fill in the ledger. It gives you a better answer than any general rule. ## How to lower your PostHog bill If you want to keep using PostHog but pay less, these changes help most. - [Capture fewer events](https://posthog.com/docs/product-analytics/cutting-costs.md) in total. Autocapture noise and an `identify()` call on every page are the two we see most. - Send [anonymous events](https://posthog.com/docs/data/anonymous-vs-identified-events.md) where you don't need person data. Marketing site traffic and backend events rarely do. - Set a [billing limit](https://posthog.com/docs/billing/limits-alerts.md) so you know the most you'll pay in a month. If you'd like help with your setup, [talk to us](https://posthog.com/talk-to-a-human.md).