• Product
  • Pricing
  • Docs
  • Using PostHog
  • Community
  • Company
  • Login
  • Home
  • CEO diaries
    • After the HN launch
    • Remote companies can be too asynchronous
    • The time before YC
    • Winning from the back - late mover advantage
    • Optimize for not breaking up with your co-founder
    • Cancer and revenue - the latest board meeting
    • "How come your website is so nice?"
    • Things I learned last year
    • Our new objective: Nail Self Serve
    • How we found our Ideal Customer Profile
    • Tell me about features, not benefits
    • The magic of a Hacker News Pre-Mortem
    • How to run a transparent startup
    • How we justified quitting our jobs and financing PostHog early on
    • How we made something people want
    • Moving to San Francisco
    • Pivot to PostHog
    • Counterintuitive lessons about our pricing
    • I used to think you don't need product people. I was wrong.
    • How we raised $3M for an open source project
    • A story about pivots
    • The YC Interview
    • Raising money is less stressful than bootstrapping
    • What motivates me as a CEO
    • The really important job interview questions engineers should ask (but don't)
    • Writing for developers
    • Reflecting on YC, 2 years on
  • Company & culture
    • How we do meetings at PostHog
  • Comparisons
    • PostHog vs Matomo
    • PostHog vs Amplitude
    • Why I ditched Google Analytics and Mixpanel for PostHog
  • Engineering
    • Enabling zero downtime data migrations for self-hosted users
    • Automating a software company with GitHub Actions
    • How to speed up ClickHouse queries using materialized columns
    • In-depth: ClickHouse vs PostgreSQL
    • Setting up super fast Cypress tests on GitHub Actions
    • How I learned to love feedback loops (and make better products)
    • Frontend filters & backend SQL - A chat with Eric Duong, Sam Winslow, James Greenhill, and Buddy Williams
    • PostHog Joins Hacktoberfest 2020
    • How PostHog built an app server (from MVP to billions of events)
    • How we’re making PostHog deployments easier
    • Solving the mystery of PostHog’s missing session recordings
    • I used to think you don't need product people. I was wrong.
    • The secrets of PostHog query performance
    • Benchmarking the impact of session recording on performance
    • The state of plugins on PostHog
    • We ship whenever
  • General
    • Setting up super fast Cypress tests on GitHub Actions
    • How we designed the PostHog mascot
    • Why you may not need a sales team
    • A story about pivots
  • Guides
    • Introduction to self-service analytics
    • Building an AARRR pirate funnel (how and why)
    • 5 essential tips for Customer Success teams on PostHog
    • 5 analytics ideas for marketing teams using PostHog
    • Automating a software company with GitHub Actions
    • The most useful B2B SaaS product metrics
    • The 7 best GDPR-compliant analytics tools
    • The best HIPAA-compliant A/B testing tools
    • The 5 best free and open-source A/B testing tools
    • The 4 best HIPAA-compliant analytics tools
    • The best open-source analytics and data tools
    • Open source (and self-hosted) alternatives to Hotjar & FullStory
    • The two ways to estimate your monthly event usage
    • How to speed up ClickHouse queries using materialized columns
    • In-depth: ClickHouse vs PostgreSQL
    • Google is about to make it a lot harder to track website and app users without third-party cookies
    • Setting up super fast Cypress tests on GitHub Actions
    • 5 essential PostHog apps for new users
    • 5 events all teams should track with PostHog
    • What launching Experimentation taught us about running effective A/B tests
    • How to get the first 10 paying customers for your devtool company (and other customer acquisition tips)
    • The best GA4 alternatives for apps and websites
    • How to harness the awesome power of growth loops
    • What is user segmentation?
    • How to measure product engagement
    • How to achieve B2B product market fit
    • How to work out what your users really need
    • How we do hiring & HR at PostHog
    • How we turned ClickHouse into our event mansion
    • An introduction to customer retention
    • Is Google Analytics HIPAA compliant?
    • Finding your North Star metric and why it matters
    • How we monetized our open source devtool
    • Building an open source data stack
    • How to plan a killer company offsite in just 8 weeks
    • Permissions and projects in PostHog, explained
    • How (and why) our marketing team uses PostHog
    • PostHog vs Matomo
    • PostHog vs Amplitude
    • Product engineer vs software engineer: what's the difference?
    • Don’t bother securing your trademarks in the beginning
    • How to seed, grow, and scale Developer Relations (and how we're doing it at PostHog)
    • The ops toolkit for early-stage startups
    • How (and why) to track your website with PostHog
    • 22 ways PostHog makes it easier to build great products
    • What is a product engineer (and why they're awesome)
    • A simple guide to personal data and PII
    • An introduction to product analytics and how it works
    • What is SSO and why you should enable it for PostHog
    • The 3 critical reasons companies choose self-hosted analytics
  • HogMail
    • HogMail #14
    • HogMail #15
    • HogMail #16
    • HogMail #17: The personal traits that can't be taught
    • HogMail #18: What can SaaS learn from the New York Times?
  • Inside PostHog
    • PostHog raises $15 million Series B for open source product analytics
    • A non-coders thoughts on ‘Everybody Codes’ - Part Two
    • A non-coder's thoughts on an 'Everybody Codes' culture
    • After the HN launch
    • Remote companies can be too asynchronous
    • The time before YC
    • How PostHog uses Wren to offset carbon emissions during offsites
    • Winning from the back - late mover advantage
    • Optimize for not breaking up with your co-founder
    • Cancer and revenue - the latest board meeting
    • "How come your website is so nice?"
    • Things I learned last year
    • Our new objective: Nail Self Serve
    • How we found our Ideal Customer Profile
    • How we do customer support at our open source devtool company
    • The importance of dogfooding - Why product managers should use their product as much as their users
    • How we designed the PostHog mascot
    • Using Gatsby and Puppeteer to create dynamic Open Graph images
    • Creating an employee-friendly startup share option scheme
    • Tell me about features, not benefits
    • How I learned to love feedback loops (and make better products)
    • The magic of a Hacker News Pre-Mortem
    • HostHogs - free drinks, free pizza and frequently asked questions
    • How to run a transparent startup
    • How we do hiring & HR at PostHog
    • How PostHog built an app server (from MVP to billions of events)
    • How we turned ClickHouse into our event mansion
    • How we justified quitting our jobs and financing PostHog early on
    • Introducing Phil Leggetter, our new head of Developer Relations
    • Using Google Analytics was deemed 'illegal' in some EU countries. We built a microsite in 48 hours to capitalize on the news.
    • Introducing Joe Martin - Our first Product Marketer
    • How we made something people want
    • How we do meetings at PostHog
    • Solving the mystery of PostHog’s missing session recordings
    • Moving to San Francisco
    • How PostHog's new VP focused the company on nailing funnels in his first week
    • An engineer's guide to picking a cofounder
    • Pivot to PostHog
    • How to plan a killer company offsite in just 8 weeks
    • PostHog raises $12 million in funding led by GV and Y Combinator
    • What we learned about hiring from our first five employees
    • How (and why) our marketing team uses PostHog
    • How we rebranded PostHog in four weeks - a postmortem
    • Counterintuitive lessons about our pricing
    • I used to think you don't need product people. I was wrong.
    • What's the true role of a product team at an engineering-led organization?
    • Building an all-remote company from scratch
    • How we raised $3M for an open source project
    • All the cool things we built at our Rome hackathon
    • Content marketing strategy for devtool companies - How we do it at PostHog
    • How to seed, grow, and scale Developer Relations (and how we're doing it at PostHog)
    • Benchmarking the impact of session recording on performance
    • Speeding up PostHog builds with Depot
    • How to run finance at your startup without hiring a finance person
    • How to choose job titles in your early stage startup
    • Startups, stop treating engineers like a different species
    • The ops toolkit for early-stage startups
    • A story about pivots
    • The YC Interview
    • Why we ditched ‘talk to sales’ for transparent pricing
    • Raising money is less stressful than bootstrapping
    • What motivates me as a CEO
    • The really important job interview questions engineers should ask (but don't)
    • Why I ditched Google Analytics and Mixpanel for PostHog
    • Why infrastructure is a competitive advantage for us
    • Why we raised a $15m Series B ahead of schedule
    • Writing for developers
    • Reflecting on YC, 2 years on
    • YC adds PostHog to top valued companies for July 2021
  • Launch week
    • Introducing Collaboration for PostHog
    • Introducing Data Management for PostHog
    • What launching Experimentation taught us about running effective A/B tests
    • How we’re making PostHog deployments easier
    • PostHog Launch Week I: A Universe of New Features
    • The secrets of PostHog query performance
  • Open source
    • The Early Days of GitLab - A Chat with Sid Sijbrandij
    • The 5 best free and open-source A/B testing tools
    • The 6 best free and open-source feature flag tools
    • The best open-source analytics and data tools
    • Open source (and self-hosted) alternatives to Hotjar & FullStory
    • How we do customer support at our open source devtool company
    • How I learned to love feedback loops (and make better products)
    • PostHog Joins Hacktoberfest 2020
    • Give Back Friday with PostHog
    • Building an open source data science publishing platform - An interview with Datapane CEO, Leo Anthias
    • How we monetized our open source devtool
    • Open source is eating SaaS
    • Building an open source data stack
    • Should open source projects track you?
    • PostHog vs Amplitude
    • How we raised $3M for an open source project
    • Why open-source projects are essential for large businesses
    • Send love to open-source projects on Valentine's Day
    • Speeding up PostHog builds with Depot
    • The 3 critical reasons companies choose self-hosted analytics
  • PostHog Academy
    • What is user segmentation?
    • How to measure product engagement
    • How to achieve B2B product market fit
    • How to work out what your users really need
    • An introduction to customer retention
    • An introduction to product analytics and how it works
  • Privacy
    • The 7 best GDPR-compliant analytics tools
    • The best HIPAA-compliant A/B testing tools
    • The 4 best HIPAA-compliant analytics tools
    • Google is about to make it a lot harder to track website and app users without third-party cookies
    • A new 'Privacy Shield' won't solve big tech's GDPR problem
    • Is Google Analytics HIPAA compliant?
    • A simple guide to personal data and PII
  • Product analytics
    • Introduction to self-service analytics
    • Building an AARRR pirate funnel (how and why)
    • The two ways to estimate your monthly event usage
    • How to harness the awesome power of growth loops
    • What is user segmentation?
    • How to measure product engagement
    • How to achieve B2B product market fit
    • How to work out what your users really need
    • An introduction to customer retention
    • Is autocapture ‘still’ bad?
    • Finding your North Star metric and why it matters
    • How PostHog's new VP focused the company on nailing funnels in his first week
    • What's the true role of a product team at an engineering-led organization?
    • How to turn your engineers into product people
    • 22 ways PostHog makes it easier to build great products
    • An introduction to product analytics and how it works
  • Product updates
    • Why we're giving away 100 times more cloud usage, free
    • Enabling zero downtime data migrations for self-hosted users
    • Introducing the Avo Inspector app
    • We just made PostHog Open Source 1000x more scalable via ClickHouse
    • Introducing Collaboration for PostHog
    • Introducing Data Management for PostHog
    • What launching Experimentation taught us about running effective A/B tests
    • Group Analytics is now available in PostHog
    • You can now reverse ETL into PostHog with Hightouch
    • How we’re making PostHog deployments easier
    • PostHog Launch Week I: A Universe of New Features
    • How we’re improving performance by combining persons and events
    • PostHog teams up with Altinity
    • Introducing PostHog Cloud EU
    • Restack joins the PostHog Marketplace
    • PostHog is now available on Segment!
    • The secrets of PostHog query performance
    • Why we're removing the sessions page
    • Array 1.0.10
    • Array 1.0.11
    • Array 1.0.8
    • Array 1.0.9
    • Array 1.1.0
    • Array 1.11.0
    • Array 1.10.0
    • Array 1.12.0
    • Array 1.13.0
    • Array 1.14.0
    • Array 1.15.0
    • Array 1.16.0
    • Array 1.17.0
    • Array 1.18.0
    • Array 1.2.0
    • Array 1.19.0
    • Array 1.20.0
    • Array 1.22.0
    • Array 1.21.0
    • Array 1.23.0
    • Array 1.24.0
    • Array 1.25.0
    • Array 1.27.0
    • Array 1.28.0
    • Array 1.29.0
    • Array 1.26.0
    • Array 1.3.0
    • Array 1.30.0
    • Array 1.31.0
    • Array 1.32.0
    • Array 1.33.0
    • Array 1.34.0
    • Array 1.35.0: Introducing SAML, world map view and new plugins
    • Array 1.37.0: Cohorts 2.0 and event & property detail pages
    • Array 1.36.0: Introducing AND/OR filtering, timezone support and universal search
    • Array 1.38.0: Exports, subscriptions and session analysis
    • Array 1.39.0: Betas, persons, events and libraries
    • Array 1.4.0
    • Array 1.40.0: Interface improvements and more!
    • Array 1.42.0: Get beta features via our roadmap!
    • Array 1.5.0
    • Array 1.41.0: Improving performance by up to 400%
    • Array 1.6.0
    • Array 1.7.0
    • Array 1.8.0
    • Array 1.9.0
    • Array 1.0.0
    • The state of plugins on PostHog
  • Release notes
    • Introducing the Avo Inspector app
    • How we’re improving performance by combining persons and events
    • Array 1.0.10
    • Array 1.0.11
    • Array 1.0.8
    • Array 1.0.9
    • Array 1.1.0
    • Array 1.11.0
    • Array 1.10.0
    • Array 1.12.0
    • Array 1.13.0
    • Array 1.14.0
    • Array 1.15.0
    • Array 1.16.0
    • Array 1.17.0
    • Array 1.18.0
    • Array 1.2.0
    • Array 1.19.0
    • Array 1.20.0
    • Array 1.22.0
    • Array 1.21.0
    • Array 1.23.0
    • Array 1.24.0
    • Array 1.25.0
    • Array 1.27.0
    • Array 1.28.0
    • Array 1.29.0
    • Array 1.26.0
    • Array 1.3.0
    • Array 1.30.0
    • Array 1.31.0
    • Array 1.32.0
    • Array 1.33.0
    • Array 1.34.0
    • Array 1.35.0: Introducing SAML, world map view and new plugins
    • Array 1.37.0: Cohorts 2.0 and event & property detail pages
    • Array 1.36.0: Introducing AND/OR filtering, timezone support and universal search
    • Array 1.38.0: Exports, subscriptions and session analysis
    • Array 1.39.0: Betas, persons, events and libraries
    • Array 1.4.0
    • Array 1.40.0: Interface improvements and more!
    • Array 1.42.0: Get beta features via our roadmap!
    • Array 1.5.0
    • Array 1.41.0: Improving performance by up to 400%
    • Array 1.6.0
    • Array 1.7.0
    • Array 1.8.0
    • Array 1.9.0
    • Array 1.0.0
  • Startups
    • A non-coder's thoughts on an 'Everybody Codes' culture
    • How we found our Ideal Customer Profile
    • Creating an employee-friendly startup share option scheme
    • How to get the first 10 paying customers for your devtool company (and other customer acquisition tips)
    • How to run a transparent startup
    • Building an open source data science publishing platform - An interview with Datapane CEO, Leo Anthias
    • How we made something people want
    • How we monetized our open source devtool
    • Should open source projects track you?
    • An engineer's guide to picking a cofounder
    • How to plan a killer company offsite in just 8 weeks
    • What we learned about hiring from our first five employees
    • How we rebranded PostHog in four weeks - a postmortem
    • Product engineer vs software engineer: what's the difference?
    • What's the true role of a product team at an engineering-led organization?
    • Why you may not need a sales team
    • Don’t bother securing your trademarks in the beginning
    • Building an all-remote company from scratch
    • All the cool things we built at our Rome hackathon
    • Content marketing strategy for devtool companies - How we do it at PostHog
    • Why open-source projects are essential for large businesses
    • How to run finance at your startup without hiring a finance person
    • How to choose job titles in your early stage startup
    • Startups, stop treating engineers like a different species
    • The ops toolkit for early-stage startups
    • How to turn your engineers into product people
    • Raising money is less stressful than bootstrapping
    • What is a product engineer (and why they're awesome)
    • Writing for developers
    • Reflecting on YC, 2 years on
  • Using PostHog
    • 5 essential tips for Customer Success teams on PostHog
    • 5 analytics ideas for marketing teams using PostHog
    • 5 essential PostHog apps for new users
    • 5 events all teams should track with PostHog
    • Permissions and projects in PostHog, explained
    • How (and why) our marketing team uses PostHog
    • How (and why) to track your website with PostHog
    • What is SSO and why you should enable it for PostHog
  • Home
  • CEO diaries
    • After the HN launch
    • Remote companies can be too asynchronous
    • The time before YC
    • Winning from the back - late mover advantage
    • Optimize for not breaking up with your co-founder
    • Cancer and revenue - the latest board meeting
    • "How come your website is so nice?"
    • Things I learned last year
    • Our new objective: Nail Self Serve
    • How we found our Ideal Customer Profile
    • Tell me about features, not benefits
    • The magic of a Hacker News Pre-Mortem
    • How to run a transparent startup
    • How we justified quitting our jobs and financing PostHog early on
    • How we made something people want
    • Moving to San Francisco
    • Pivot to PostHog
    • Counterintuitive lessons about our pricing
    • I used to think you don't need product people. I was wrong.
    • How we raised $3M for an open source project
    • A story about pivots
    • The YC Interview
    • Raising money is less stressful than bootstrapping
    • What motivates me as a CEO
    • The really important job interview questions engineers should ask (but don't)
    • Writing for developers
    • Reflecting on YC, 2 years on
  • Company & culture
    • How we do meetings at PostHog
  • Comparisons
    • PostHog vs Matomo
    • PostHog vs Amplitude
    • Why I ditched Google Analytics and Mixpanel for PostHog
  • Engineering
    • Enabling zero downtime data migrations for self-hosted users
    • Automating a software company with GitHub Actions
    • How to speed up ClickHouse queries using materialized columns
    • In-depth: ClickHouse vs PostgreSQL
    • Setting up super fast Cypress tests on GitHub Actions
    • How I learned to love feedback loops (and make better products)
    • Frontend filters & backend SQL - A chat with Eric Duong, Sam Winslow, James Greenhill, and Buddy Williams
    • PostHog Joins Hacktoberfest 2020
    • How PostHog built an app server (from MVP to billions of events)
    • How we’re making PostHog deployments easier
    • Solving the mystery of PostHog’s missing session recordings
    • I used to think you don't need product people. I was wrong.
    • The secrets of PostHog query performance
    • Benchmarking the impact of session recording on performance
    • The state of plugins on PostHog
    • We ship whenever
  • General
    • Setting up super fast Cypress tests on GitHub Actions
    • How we designed the PostHog mascot
    • Why you may not need a sales team
    • A story about pivots
  • Guides
    • Introduction to self-service analytics
    • Building an AARRR pirate funnel (how and why)
    • 5 essential tips for Customer Success teams on PostHog
    • 5 analytics ideas for marketing teams using PostHog
    • Automating a software company with GitHub Actions
    • The most useful B2B SaaS product metrics
    • The 7 best GDPR-compliant analytics tools
    • The best HIPAA-compliant A/B testing tools
    • The 5 best free and open-source A/B testing tools
    • The 4 best HIPAA-compliant analytics tools
    • The best open-source analytics and data tools
    • Open source (and self-hosted) alternatives to Hotjar & FullStory
    • The two ways to estimate your monthly event usage
    • How to speed up ClickHouse queries using materialized columns
    • In-depth: ClickHouse vs PostgreSQL
    • Google is about to make it a lot harder to track website and app users without third-party cookies
    • Setting up super fast Cypress tests on GitHub Actions
    • 5 essential PostHog apps for new users
    • 5 events all teams should track with PostHog
    • What launching Experimentation taught us about running effective A/B tests
    • How to get the first 10 paying customers for your devtool company (and other customer acquisition tips)
    • The best GA4 alternatives for apps and websites
    • How to harness the awesome power of growth loops
    • What is user segmentation?
    • How to measure product engagement
    • How to achieve B2B product market fit
    • How to work out what your users really need
    • How we do hiring & HR at PostHog
    • How we turned ClickHouse into our event mansion
    • An introduction to customer retention
    • Is Google Analytics HIPAA compliant?
    • Finding your North Star metric and why it matters
    • How we monetized our open source devtool
    • Building an open source data stack
    • How to plan a killer company offsite in just 8 weeks
    • Permissions and projects in PostHog, explained
    • How (and why) our marketing team uses PostHog
    • PostHog vs Matomo
    • PostHog vs Amplitude
    • Product engineer vs software engineer: what's the difference?
    • Don’t bother securing your trademarks in the beginning
    • How to seed, grow, and scale Developer Relations (and how we're doing it at PostHog)
    • The ops toolkit for early-stage startups
    • How (and why) to track your website with PostHog
    • 22 ways PostHog makes it easier to build great products
    • What is a product engineer (and why they're awesome)
    • A simple guide to personal data and PII
    • An introduction to product analytics and how it works
    • What is SSO and why you should enable it for PostHog
    • The 3 critical reasons companies choose self-hosted analytics
  • HogMail
    • HogMail #14
    • HogMail #15
    • HogMail #16
    • HogMail #17: The personal traits that can't be taught
    • HogMail #18: What can SaaS learn from the New York Times?
  • Inside PostHog
    • PostHog raises $15 million Series B for open source product analytics
    • A non-coders thoughts on ‘Everybody Codes’ - Part Two
    • A non-coder's thoughts on an 'Everybody Codes' culture
    • After the HN launch
    • Remote companies can be too asynchronous
    • The time before YC
    • How PostHog uses Wren to offset carbon emissions during offsites
    • Winning from the back - late mover advantage
    • Optimize for not breaking up with your co-founder
    • Cancer and revenue - the latest board meeting
    • "How come your website is so nice?"
    • Things I learned last year
    • Our new objective: Nail Self Serve
    • How we found our Ideal Customer Profile
    • How we do customer support at our open source devtool company
    • The importance of dogfooding - Why product managers should use their product as much as their users
    • How we designed the PostHog mascot
    • Using Gatsby and Puppeteer to create dynamic Open Graph images
    • Creating an employee-friendly startup share option scheme
    • Tell me about features, not benefits
    • How I learned to love feedback loops (and make better products)
    • The magic of a Hacker News Pre-Mortem
    • HostHogs - free drinks, free pizza and frequently asked questions
    • How to run a transparent startup
    • How we do hiring & HR at PostHog
    • How PostHog built an app server (from MVP to billions of events)
    • How we turned ClickHouse into our event mansion
    • How we justified quitting our jobs and financing PostHog early on
    • Introducing Phil Leggetter, our new head of Developer Relations
    • Using Google Analytics was deemed 'illegal' in some EU countries. We built a microsite in 48 hours to capitalize on the news.
    • Introducing Joe Martin - Our first Product Marketer
    • How we made something people want
    • How we do meetings at PostHog
    • Solving the mystery of PostHog’s missing session recordings
    • Moving to San Francisco
    • How PostHog's new VP focused the company on nailing funnels in his first week
    • An engineer's guide to picking a cofounder
    • Pivot to PostHog
    • How to plan a killer company offsite in just 8 weeks
    • PostHog raises $12 million in funding led by GV and Y Combinator
    • What we learned about hiring from our first five employees
    • How (and why) our marketing team uses PostHog
    • How we rebranded PostHog in four weeks - a postmortem
    • Counterintuitive lessons about our pricing
    • I used to think you don't need product people. I was wrong.
    • What's the true role of a product team at an engineering-led organization?
    • Building an all-remote company from scratch
    • How we raised $3M for an open source project
    • All the cool things we built at our Rome hackathon
    • Content marketing strategy for devtool companies - How we do it at PostHog
    • How to seed, grow, and scale Developer Relations (and how we're doing it at PostHog)
    • Benchmarking the impact of session recording on performance
    • Speeding up PostHog builds with Depot
    • How to run finance at your startup without hiring a finance person
    • How to choose job titles in your early stage startup
    • Startups, stop treating engineers like a different species
    • The ops toolkit for early-stage startups
    • A story about pivots
    • The YC Interview
    • Why we ditched ‘talk to sales’ for transparent pricing
    • Raising money is less stressful than bootstrapping
    • What motivates me as a CEO
    • The really important job interview questions engineers should ask (but don't)
    • Why I ditched Google Analytics and Mixpanel for PostHog
    • Why infrastructure is a competitive advantage for us
    • Why we raised a $15m Series B ahead of schedule
    • Writing for developers
    • Reflecting on YC, 2 years on
    • YC adds PostHog to top valued companies for July 2021
  • Launch week
    • Introducing Collaboration for PostHog
    • Introducing Data Management for PostHog
    • What launching Experimentation taught us about running effective A/B tests
    • How we’re making PostHog deployments easier
    • PostHog Launch Week I: A Universe of New Features
    • The secrets of PostHog query performance
  • Open source
    • The Early Days of GitLab - A Chat with Sid Sijbrandij
    • The 5 best free and open-source A/B testing tools
    • The 6 best free and open-source feature flag tools
    • The best open-source analytics and data tools
    • Open source (and self-hosted) alternatives to Hotjar & FullStory
    • How we do customer support at our open source devtool company
    • How I learned to love feedback loops (and make better products)
    • PostHog Joins Hacktoberfest 2020
    • Give Back Friday with PostHog
    • Building an open source data science publishing platform - An interview with Datapane CEO, Leo Anthias
    • How we monetized our open source devtool
    • Open source is eating SaaS
    • Building an open source data stack
    • Should open source projects track you?
    • PostHog vs Amplitude
    • How we raised $3M for an open source project
    • Why open-source projects are essential for large businesses
    • Send love to open-source projects on Valentine's Day
    • Speeding up PostHog builds with Depot
    • The 3 critical reasons companies choose self-hosted analytics
  • PostHog Academy
    • What is user segmentation?
    • How to measure product engagement
    • How to achieve B2B product market fit
    • How to work out what your users really need
    • An introduction to customer retention
    • An introduction to product analytics and how it works
  • Privacy
    • The 7 best GDPR-compliant analytics tools
    • The best HIPAA-compliant A/B testing tools
    • The 4 best HIPAA-compliant analytics tools
    • Google is about to make it a lot harder to track website and app users without third-party cookies
    • A new 'Privacy Shield' won't solve big tech's GDPR problem
    • Is Google Analytics HIPAA compliant?
    • A simple guide to personal data and PII
  • Product analytics
    • Introduction to self-service analytics
    • Building an AARRR pirate funnel (how and why)
    • The two ways to estimate your monthly event usage
    • How to harness the awesome power of growth loops
    • What is user segmentation?
    • How to measure product engagement
    • How to achieve B2B product market fit
    • How to work out what your users really need
    • An introduction to customer retention
    • Is autocapture ‘still’ bad?
    • Finding your North Star metric and why it matters
    • How PostHog's new VP focused the company on nailing funnels in his first week
    • What's the true role of a product team at an engineering-led organization?
    • How to turn your engineers into product people
    • 22 ways PostHog makes it easier to build great products
    • An introduction to product analytics and how it works
  • Product updates
    • Why we're giving away 100 times more cloud usage, free
    • Enabling zero downtime data migrations for self-hosted users
    • Introducing the Avo Inspector app
    • We just made PostHog Open Source 1000x more scalable via ClickHouse
    • Introducing Collaboration for PostHog
    • Introducing Data Management for PostHog
    • What launching Experimentation taught us about running effective A/B tests
    • Group Analytics is now available in PostHog
    • You can now reverse ETL into PostHog with Hightouch
    • How we’re making PostHog deployments easier
    • PostHog Launch Week I: A Universe of New Features
    • How we’re improving performance by combining persons and events
    • PostHog teams up with Altinity
    • Introducing PostHog Cloud EU
    • Restack joins the PostHog Marketplace
    • PostHog is now available on Segment!
    • The secrets of PostHog query performance
    • Why we're removing the sessions page
    • Array 1.0.10
    • Array 1.0.11
    • Array 1.0.8
    • Array 1.0.9
    • Array 1.1.0
    • Array 1.11.0
    • Array 1.10.0
    • Array 1.12.0
    • Array 1.13.0
    • Array 1.14.0
    • Array 1.15.0
    • Array 1.16.0
    • Array 1.17.0
    • Array 1.18.0
    • Array 1.2.0
    • Array 1.19.0
    • Array 1.20.0
    • Array 1.22.0
    • Array 1.21.0
    • Array 1.23.0
    • Array 1.24.0
    • Array 1.25.0
    • Array 1.27.0
    • Array 1.28.0
    • Array 1.29.0
    • Array 1.26.0
    • Array 1.3.0
    • Array 1.30.0
    • Array 1.31.0
    • Array 1.32.0
    • Array 1.33.0
    • Array 1.34.0
    • Array 1.35.0: Introducing SAML, world map view and new plugins
    • Array 1.37.0: Cohorts 2.0 and event & property detail pages
    • Array 1.36.0: Introducing AND/OR filtering, timezone support and universal search
    • Array 1.38.0: Exports, subscriptions and session analysis
    • Array 1.39.0: Betas, persons, events and libraries
    • Array 1.4.0
    • Array 1.40.0: Interface improvements and more!
    • Array 1.42.0: Get beta features via our roadmap!
    • Array 1.5.0
    • Array 1.41.0: Improving performance by up to 400%
    • Array 1.6.0
    • Array 1.7.0
    • Array 1.8.0
    • Array 1.9.0
    • Array 1.0.0
    • The state of plugins on PostHog
  • Release notes
    • Introducing the Avo Inspector app
    • How we’re improving performance by combining persons and events
    • Array 1.0.10
    • Array 1.0.11
    • Array 1.0.8
    • Array 1.0.9
    • Array 1.1.0
    • Array 1.11.0
    • Array 1.10.0
    • Array 1.12.0
    • Array 1.13.0
    • Array 1.14.0
    • Array 1.15.0
    • Array 1.16.0
    • Array 1.17.0
    • Array 1.18.0
    • Array 1.2.0
    • Array 1.19.0
    • Array 1.20.0
    • Array 1.22.0
    • Array 1.21.0
    • Array 1.23.0
    • Array 1.24.0
    • Array 1.25.0
    • Array 1.27.0
    • Array 1.28.0
    • Array 1.29.0
    • Array 1.26.0
    • Array 1.3.0
    • Array 1.30.0
    • Array 1.31.0
    • Array 1.32.0
    • Array 1.33.0
    • Array 1.34.0
    • Array 1.35.0: Introducing SAML, world map view and new plugins
    • Array 1.37.0: Cohorts 2.0 and event & property detail pages
    • Array 1.36.0: Introducing AND/OR filtering, timezone support and universal search
    • Array 1.38.0: Exports, subscriptions and session analysis
    • Array 1.39.0: Betas, persons, events and libraries
    • Array 1.4.0
    • Array 1.40.0: Interface improvements and more!
    • Array 1.42.0: Get beta features via our roadmap!
    • Array 1.5.0
    • Array 1.41.0: Improving performance by up to 400%
    • Array 1.6.0
    • Array 1.7.0
    • Array 1.8.0
    • Array 1.9.0
    • Array 1.0.0
  • Startups
    • A non-coder's thoughts on an 'Everybody Codes' culture
    • How we found our Ideal Customer Profile
    • Creating an employee-friendly startup share option scheme
    • How to get the first 10 paying customers for your devtool company (and other customer acquisition tips)
    • How to run a transparent startup
    • Building an open source data science publishing platform - An interview with Datapane CEO, Leo Anthias
    • How we made something people want
    • How we monetized our open source devtool
    • Should open source projects track you?
    • An engineer's guide to picking a cofounder
    • How to plan a killer company offsite in just 8 weeks
    • What we learned about hiring from our first five employees
    • How we rebranded PostHog in four weeks - a postmortem
    • Product engineer vs software engineer: what's the difference?
    • What's the true role of a product team at an engineering-led organization?
    • Why you may not need a sales team
    • Don’t bother securing your trademarks in the beginning
    • Building an all-remote company from scratch
    • All the cool things we built at our Rome hackathon
    • Content marketing strategy for devtool companies - How we do it at PostHog
    • Why open-source projects are essential for large businesses
    • How to run finance at your startup without hiring a finance person
    • How to choose job titles in your early stage startup
    • Startups, stop treating engineers like a different species
    • The ops toolkit for early-stage startups
    • How to turn your engineers into product people
    • Raising money is less stressful than bootstrapping
    • What is a product engineer (and why they're awesome)
    • Writing for developers
    • Reflecting on YC, 2 years on
  • Using PostHog
    • 5 essential tips for Customer Success teams on PostHog
    • 5 analytics ideas for marketing teams using PostHog
    • 5 essential PostHog apps for new users
    • 5 events all teams should track with PostHog
    • Permissions and projects in PostHog, explained
    • How (and why) our marketing team uses PostHog
    • How (and why) to track your website with PostHog
    • What is SSO and why you should enable it for PostHog
  • Blog
  • Engineering
  • Product updates

Enabling zero downtime data migrations for self-hosted users

  • Yakko Majuri
    Yakko Majuri

In this world nothing is certain except death, taxes, and database migrations.

As your product evolves, your schemas evolve too, and you need migrations to update them.

However, not all migrations are made equal.

Some are simple, others are complex. Some run quickly, others take a long time.

For example, consider the following three scenarios that we've encountered at PostHog when updating table schemas in ClickHouse (our analytics database):

Note: These scenarios are based on non-replicated tables.

1. Adding a column to a table

This is reasonably simple. We can modify the table in place with an ALTER TABLE statement and add the column we want.

2. Changing the engine of a table

Here things start to get a bit more complicated. ClickHouse does not support changing table engines via ALTER TABLE, so we cannot modify the table in place.

Instead, we need to create a new table with the same schema, except for the engine change, and insert data from the old table into it.

Luckily, ClickHouse provides a nice way to do this. With ATTACH PARTITION, we can "copy the data" from the old table to the new table reasonably quickly, by simply "attaching" the existing partition(s) to the new table. In reality, no data gets "copied", but rather new hard links are created to point to the existing data.

So while we do need to get data from a table to another, this isn't very problematic.

3. Changing the sorting key of a table

This is where things get hairy.

ClickHouse tables using engines in the MergeTree family store data on disk in sorted parts following a "sorting key".

This is defined by the ORDER BY clause at table creation.

Now, say you've done some analysis on the most common queries you run and determined you'd have a massive performance benefit from adding a column to your sorting key.

Well, tough luck - can't do that.

While a MODIFY ORDER BY statement does exist on ClickHouse, the docs specifically note that "you cannot add expressions containing existing columns to the sorting key".

The reason for this is that adding a column to the sorting key would require rewriting all parts on disk, as they should now be sorted differently.

This means that, like in example #2, we need to create a new table and add the old data to it. However, it also means that we cannot use ATTACH PARTITION, as the parts on the new table will be different from those on the old table.

That leaves us with one option: inserting all the data from the old table into the new table...

Row. By. Row.

The problem

Needing to execute migrations like the one above leaves us with a difficult problem at hand: inserting data row by row can take a long time.

The time it will take depends on the size of the table to be migrated, and thus, if we're migrating a large table (say, our events table), this can take weeks.

As a result, we can't pop this in with our other ("normal") migrations which run on every upgrade, as they would prevent the upgrade from happening, and potentially even cause downtime.

But that's not all. We at PostHog have an additional problem: self-hosted users.

If PostHog was a SaaS-only platform (with no self-hosting available), we could have a team dedicated to running this "manually" on our instance, monitoring it, and making sure everything runs smoothly.

However, that's not a viable option for users that run their own PostHog instance. Providing them with a runbook is an option, but it doesn't align with our goal of making PostHog easy to deploy and manage.

We needed something better.

Enter async migrations

Async migrations UI

The solution we came up with for the problem mentioned above is a system for running so-called async migrations.

This system allows us to safely run long data migrations in the background without causing any downtime, as well as provides a full suite of tools for managing and debugging these migrations easily.

When we started building it, we wanted the system to have three key characteristics:

  1. It should be asynchronous, but with guarantees.
  2. It should be safe.
  3. It should be easy to work with, both for developers and users.

Here's how we achieved all three.

1. It should be asynchronous, but with guarantees

As we established earlier, long-running (and potentially unbounded) migrations can't be part of the upgrade path.

Thus, they can't run synchronously during a version upgrade, they must run asynchronously during normal operations.

For this, we settled on a version range approach.

py
class Migration(AsyncMigrationDefinition):
posthog_min_version = "1.45.0"
posthog_max_version = "1.47.9"
# ...

Unlike migrations that immediately become a pre-requisite for upgrading to the version they're included in, async migrations specify a range of versions within which they can be run, and users can run them at any time they like, provided their instance is within the range.

The beauty of this system is that users have flexibility to pick a convenient period to run the migrations (maybe they want to keep a close eye on it, or scale some services temporarily), but we (PostHog developers) can rely on them being completed from a given version onwards.

The guarantees around completion are done via a combination of hard requirements for upgrading to certain versions and good communication through release notes and docs, and they prevent us from having to support multiple code paths depending on the state of the database.

Given our monthly release schedule for minor versions, a migration added in 1.45.0 with an upper bound of 1.48.0 gives users three months to run them before the version it is required in comes out. In addition, it allows us to start working on code that relies on the migration being done after two months, essentially as soon as the last supported version (in this case 1.47.0) is released.

As for how they run, we leveraged a service we already used for asynchronous operations: Celery. We only ever run one async migration task at a time, keep task states temporarily in Redis, and tasks are dispatched with track_started=True and ignore_result=False, so we can keep an eye on them and handle edge cases like the Celery worker dying unexpectedly.

2. It should be safe

Anytime you're messing with user databases there's a risk that things will go bad. Period.

As such, just like with any migration, async migrations still rely on reviewers, tests, and checks to ensure nothing dangerous is shipped, like a migration with DROP TABLE events.

However, it was a top priority for us to make the async migrations system include all the necessary tools for running database operations safely on environments we don't control (self-hosted instances).

To achieve this, we:

  • Made available to developers a wide range of checks that can short circuit the running process, such as a precheck, a periodic healthcheck, service version requirements, and dependencies. To give one specific example, we often use prechecks to ensure the database has enough free disk space to run the migration, given we might temporarily duplicate a table's data, for instance.
  • Built the system with resumability and rollbacks in mind, ensuring migrations can behave in a sane and non-destructive way if services crash, errors are thrown, timeouts occur, etc. Depending on the circumstances, we will either continue running the migration if we've determined it to be safe, or roll the database back to the initial state.

3. It should be easy to work with, both for developers and users

Lastly, async migrations should be easy to launch and manage for users, as well as easy to write and build upon for developers.

To cover the latter part, we implemented the aforementioned guarantees and checks, as well as made the migration definitions closely resemble other migration systems we already have in place.

As for users, we built a fully-fledged UI for instance admins, where they can read about the migration, update settings (like default timeouts and automatic rollbacks), trigger a run, pause or resume a migration, force a rollback, monitor status and progress, as well as get a list of errors.

We also store the ID of the query that is currently running on the database and the ID of the Celery task handling the migration, so more advanced users can go into the services themselves for additional monitoring.

Ultimately, running a migration takes only the click of a button, but all the tools are in place for debugging issues if they come about.

It's also worth noting that we implemented an API for migrations to check if they should even run at all on a given instance. This is particularly useful for preventing useless runs on fresh deploys. A user that deployed PostHog after the migration was introduced shouldn't need to run a migration to get from an old schema to the new schema, given they already have the new schema in place (async migrations should come with corresponding changes to the original schema definitions). In these cases, we auto complete the migration and unblock upgrades without any user input at all.

A closer look

Architecture

Async migrations are triggered from the UI and create a Celery task that handles its execution in a background worker.

Metadata about the migration is stored in Postgres, including things such as status (completed, errored, rolled back, etc), progress, start and finish times, and other useful information.

Async migrations Architecture

Structure

An async migration can contain the following components:

  • description: A description of the migration.
  • operations: A list of operations to run in sequence, each with a designated rollback. An operation can use plain SQL or arbitrary functions, and the operations list can be dynamic based on instance setup. For example, we may generate operations for each partition on a table.
  • posthog_min_version: The minimum version of PostHog required for running the migration.
  • posthog_max_version: The last PostHog version this migration can be run on.
  • is_required: A check that determines if this migration needs to be run on the instance. Usually verifies the current schema of a table to determine if it needs to be migrated.
  • precheck: A check that runs before the migration starts to determine if it is safe to do so. It returns a boolean and a message, so it can surface helpful errors to the user.
  • healthcheck: A check that runs both before the migration starts and at an interval while it is running. If it fails, it will kill the migration. Also returns a message that will be shown to the user.
  • service_version_requirements: A list of requirements for the versions of external services PostHog depends on, such as Kafka and PostgreSQL.
  • progress: A function that specifies an arbitrary progress calculation, returning a percentage between 0 and 100. If not present, we calculate progress based on the number of operations executed so far, although this is often not a good proxy.

What's next?

We currently have three async migrations in the codebase, each destined to make queries in PostHog significantly faster. If you're a user, make sure to run them! For more info, see our dedicated docs.

Going forward, we're excited to make this system even better, polishing our upgrade flow, including more granular controls, and introducing automatic runs under certain circumstances.

Oh, and while we don't spin this out into its own tool for others to use, feel free to check out our codebase if you have a similar problem - don't worry, it's open source 😉.

PostHog is an open source analytics platform you can host yourself. We help you build better products faster, without user data ever leaving your infrastructure.


Ready to find out more?

Try PostHog todaySchedule a demo

Author

  • Yakko Majuri
    Yakko Majuri

Share

Topic(s)

  • Engineering
  • Product updates

Mar 18, 2022

The best of PostHog.
Delivered twice a month.

Jump to:

  • The problem
  • Enter async migrations
  • 1. It should be asynchronous, but with guarantees
  • 2. It should be safe
  • 3. It should be easy to work with, both for developers and users
  • A closer look
  • Architecture
  • Structure
  • What's next?
  • Edit this page
  • Raise an issue
  • Toggle content width
  • Toggle dark mode
  • Product

  • Overview
  • Pricing
  • Product analytics
  • Session recording
  • A/B testing
  • Feature flags
  • Apps
  • Customer stories
  • PostHog vs...
  • Docs

  • Quickstart guide
  • Self-hosting
  • Installing PostHog
  • Building an app
  • API
  • Webhooks
  • How PostHog works
  • Data privacy
  • Using PostHog

  • Product manual
  • Apps manuals
  • Tutorials
  • Community

  • Questions?
  • Product roadmap
  • Contributors
  • Partners
  • Newsletter
  • Merch
  • PostHog FM
  • PostHog on GitHub
  • Handbook

  • Getting started
  • Company
  • Strategy
  • How we work
  • Small teams
  • People & Ops
  • Engineering
  • Product
  • Design
  • Marketing
  • Customer success
  • Company

  • About
  • Team
  • Investors
  • Press
  • Blog
  • FAQ
  • Support
  • Careers
© 2022 PostHog, Inc.
  • Code of conduct
  • Privacy policy
  • Terms