PostHog to Convex: How to Move Your Data

Move PostHog data into Convex with Airbyte. Why this powers app features rather than analytics, Convex table naming rules, and PostHog's shared rate limits.

Summarize with AI:

Moving PostHog into Convex is an unusual pairing, and worth being clear about up front. This is not analytics. Convex is an application backend, so the reason to put product usage data there is to power something users actually see: an in-app usage dashboard, a feature that adapts to how someone has been using the product, an onboarding flow that knows what they have already done.

The hand-rolled version calls the PostHog API from a Convex action and caches the result. It works for one metric and falls over when you want ten, because PostHog's rate limits are shared across your whole organisation and your app is now competing with your own analytics team. This guide covers the managed path: replicating PostHog into Convex tables with Airbyte on a schedule.

PostHog to Convex at a glance:

CapabilitySupportedWhat it means for this pipeline
DirectionInto Convex onlyStreaming export from Convex via Airbyte is not supported
PostHog incrementalEvents onlySix other streams are re-read in full on every sync
PostHog rate limitsOrganisation-wideShared with every other tool and script on the account
Convex table namesRestrictedLetters, digits and underscores, and no leading underscore
Sync modePrefer incrementalPerformance suffers with large, frequent full refresh syncs

Why move data from PostHog to Convex?

One situation accounts for nearly all of these pipelines, and it is worth naming precisely because it is not the usual one.

You are building a product feature that needs to know what the user has done. A usage summary shown to customers on their billing page, a checklist that ticks itself off as people complete actions, an admin view your support team uses, a nudge that fires when someone has not used a feature they are paying for. All of these need product analytics inside the application, reactively, not inside a BI tool.

If instead you want to analyse product usage alongside revenue and support data, this is the wrong destination and a warehouse is the right one. Convex is an application backend, and putting analytical workloads on it will be both awkward and expensive compared with the alternative.

What do you need before you start?

Two of these can stop the project before it starts:

A Convex deployment and a deploy key. You supply the deployment URL and a deploy key generated from the Convex dashboard settings. Point this at a production deployment rather than a development one, since the connector will be creating and writing tables.

Awareness that this is a beta integration. Convex describes its Airbyte integration as a beta feature. It is maintained by the Convex team rather than being a community contribution, which is reassuring, but treat it as something to validate on a non-critical table before it sits under a customer-facing feature.

A PostHog personal API key. Plus a start date. If you self-host PostHog, change the base URL from the default to your instance. The PostHog source documentation covers every field.

Stream names that Convex will accept. Convex table names can contain only letters, digits and underscores, and may not begin with an underscore. Check your stream names against that before the first sync rather than debugging a failure afterwards.

One direction worth confirming: Airbyte moves data into Convex, and streaming export out of Convex through Airbyte is not supported. If you also need Convex data elsewhere, that is a separate problem with a separate tool.

How do you build a PostHog to Convex pipeline in Airbyte?

Step 1: Decide what your feature actually needs

This step is not optional here. Because the destination is an application backend rather than a warehouse, syncing everything PostHog knows is actively harmful: it costs API budget, it bloats your Convex deployment, and none of it is queried. Write down the specific streams your feature reads. Usually that is persons and a bounded window of events, not the full catalogue.

Step 2: Configure the PostHog source

Click Sources in the left navigation, then New Source, and select PostHog, following adding a source. Supply the personal API key, a start date, and the base URL if you self-host. Set the events time step deliberately, since it controls how many days of events each request covers and is the main lever on whether a backfill completes.

Step 3: Configure the Convex destination

Click Destinations, then New Destination, and select Convex, following adding a destination. Supply the deployment URL and deploy key. Each stream becomes a table, each record becomes a document, and Convex assigns its own identifier and creation time fields during the sync. Full behaviour is in the Convex destination docs.

Step 4: Use incremental sync modes

Click Connections, then New connection, and select your streams and a sync mode for each. The Convex destination supports full refresh overwrite and append, incremental append and incremental dedup, and it explicitly warns that performance suffers with large, frequent full refresh syncs. Prefer incremental wherever the stream supports it, and especially on large tables.

One behaviour to note on incremental dedup: Convex does not keep a history table the way some warehouse destinations do. It stores a deduped snapshot instead. That is usually what an application wants, since your feature reads current state, but it does mean the history is not sitting there if someone later asks for it.

Why does PostHog rate limiting affect your whole organisation?

Because PostHog applies its limits across the organisation rather than per API key. The analytics endpoints are capped at 240 requests per minute and 1,200 per hour, and every tool, script and personal key on the account draws from the same budget.

That matters more here than on a warehouse pipeline, because a customer-facing feature failing to update is more visible than a dashboard being an hour stale. Before scheduling frequent syncs, find out what else talks to PostHog, and agree a share of the budget with whoever owns it. Alerting on sync failures matters too, since a stalled pipeline now shows up as a stale number in your product.

PostHog's own documentation recommends batch exports for large or regular event exports, and that recommendation stands here. If the volume you need is genuinely large, a hybrid is sensible: batch exports feeding a warehouse for analysis, and this connector moving the narrow slice your application reads.

Which PostHog streams are worth syncing here?

Only events is incremental. Projects, annotations, cohorts, feature flags, insights and persons are re-read in full on every sync. For most of those that is fine, because they are configuration objects numbering in the hundreds rather than the millions.

Persons is the exception and, awkwardly, often the stream an application feature most wants. On a consumer product with a large identified user base it is genuinely large, and it is re-read every time. If your sync is slow and you have already tuned the events time step, this is the next thing to look at, and splitting it into its own connection on a slower schedule is a legitimate fix.

Cohorts and feature flags are small, cheap and often exactly what an adaptive UI needs, so they are usually a better fit for this pipeline than raw events. Consider whether your feature can read a cohort membership rather than recomputing something from an event stream, because the former is a much lighter pipeline.

Frequently asked questions

Can Airbyte move data out of Convex as well as into it?

No. Airbyte supports streaming import into Convex. Streaming export from Convex through Airbyte is not supported, so moving Convex data elsewhere needs a different tool.

Why did my sync fail on a table name?

Convex table names can contain only letters, digits and underscores, and cannot start with an underscore. Check your stream names against that rule.

Does incremental dedup keep a history in Convex?

No. Unlike some warehouse destinations, Convex stores a deduped snapshot rather than a history table. Current state is preserved, previous versions are not.

Does my sync compete with other PostHog integrations?

Yes. PostHog applies rate limits across the whole organisation rather than per API key, so other tools and scripts share the same budget as your sync.

Can I do this without writing code?

Yes. The setup above is entirely UI-driven, from creating the source through to scheduling the connection. If you would rather manage pipelines as infrastructure, the same source, destination and connection can be provisioned from configuration files instead.

Get your PostHog data into Convex

Sync the narrow slice your feature reads rather than everything PostHog knows, prefer incremental modes, check your stream names against Convex's table naming rules, and agree your share of the PostHog rate limit before choosing a schedule. Because this data now sits behind something users see, alerting on sync failures matters more than it would for a warehouse.

Airbyte's connector catalog includes 600+ pre-built connectors, so the same PostHog source can feed a warehouse for analysis alongside this one. For that pairing, see PostHog to BigQuery, and for another product analytics source and its own export constraints, Mixpanel to ClickHouse.

Start syncing now →

Integrate with 600+ apps using Airbyte

Move data from 600+ sources into warehouses, lakes, and beyond. Set up pipelines in minutes with pre-built connectors and the Connector Builder.