Appsflyer to ClickHouse: How to Move Your Data

Move AppsFlyer into ClickHouse with Airbyte. Why one install total spans three streams, which cursor each family needs, and what the connector leaves out.

Summarize with AI:

Moving AppsFlyer into ClickHouse puts mobile attribution somewhere you can slice it across long periods without waiting. AppsFlyer answers where installs came from and knows nothing about what those users went on to spend, which is the question that actually decides a marketing budget.

This guide covers the managed path with Airbyte. Two things shape the build: a single total usually requires unioning three separate streams, and different stream families need different cursors, which is easy to get wrong and slow to notice.

Appsflyer to ClickHouse at a glance:

CapabilitySupportedWhat it means for this pipeline
Raw data history90 daysAn older start date is capped silently rather than failing
Raw streamsSplit three waysNon-organic, organic and retargeting arrive separately
Not includedFour report typesReinstalls, ad revenue, postbacks and Protect360 fraud
CursorsDiffer by familyInstall time, event time or date depending on the stream
API tokenAdmin onlyReissued if the account admin changes, breaking your config

Why move data from Appsflyer to ClickHouse?

Two situations account for most of these pipelines.

The first is return on ad spend properly calculated. Attribution tells you a channel produced installs, and whether those installs were worth buying needs revenue, retention and support cost, none of which AppsFlyer holds. Joining them means aggregating across millions of install and event rows, which is precisely what a column store is for.

The second is interactive exploration across cohorts and campaigns, where waiting for a dashboard to load changes how often people ask questions. If your team would rather not think about merge behaviour and cursor selection at all, a managed warehouse asks less of you, and AppsFlyer to BigQuery covers that route.

What do you need before you start?

Four things, and the first decides whether the project is viable at all:

Confirmation of what your subscription includes. Raw data reports are a premium AppsFlyer capability rather than something every account has, and aggregate reports are a separate permission. Check before scoping, since this determines which streams return anything at all. The AppsFlyer source documentation lists every field and stream.

An API token, which only an account admin can create. It is tied to that admin, and AppsFlyer issues a new one if the account admin changes, at which point your configuration stops working. Worth knowing before it happens during somebody's notice period.

Your app identifier and project timezone. One source covers one app, and the identifier differs by platform. The timezone setting defaults to UTC and should match your app settings, or every daily figure shifts.

A ClickHouse database and a cursor plan per stream family. These are not uniform, and picking one cursor for everything is the mistake this connector invites.

If your database restricts inbound traffic by IP, add the Airbyte Cloud IP addresses to the allow list before you begin.

How do you build an Appsflyer to ClickHouse pipeline in Airbyte?

Step 1: Check what the connector does not cover

Four report types are outside this connector entirely: reinstall raw data, ad revenue raw data, postbacks and Protect360 fraud. If your analysis depends on ad revenue or fraud signals, that is a separate route and better discovered now than after the pipeline is live. Combine this with confirming your subscription covers raw data, and the rest of the build becomes configuration rather than investigation.

Step 2: Configure the AppsFlyer source

Click Sources in the left navigation, then New Source, and select AppsFlyer, following adding a source. Supply the API token, app identifier, start date and timezone. Setting a start date earlier than ninety days ago is silently capped rather than rejected, so do not assume a long backfill succeeded because nothing complained.

Step 3: Configure the ClickHouse destination

Click Destinations, then New Destination, and select ClickHouse, following adding a destination. Supply the host, port, database and credentials. Records land in typed columns over the native protocol, which is what makes aggregating install and event volumes quick, and the types settled at table creation are the ones you keep.

Step 4: Create the connection and set cursors per stream

Click Connections, then New connection, select your streams and a sync mode. All streams support full refresh and incremental, and the cursor is not the same across them, which the next sections cover. Given that raw history only reaches ninety days, keep the schedule tight and alert on failure.

Treat the resulting tables as an archive rather than a mirror, because anything older than ninety days exists in ClickHouse and nowhere else.

Why does one total need three streams?

Because the raw data reports are split by traffic type. Installs, in-app events and uninstall events each arrive in three variants covering non-organic, organic and retargeting traffic, which is eight raw streams in total. A question as simple as how many installs happened last week therefore spans three tables rather than one.

That split is genuinely useful, since paid and organic installs should rarely be added together without thinking about it, and retargeting is a different thing again. It becomes a problem when somebody unions them carelessly and double counts a user who appears in more than one, or unions only two and quietly understates the total while the query looks perfectly reasonable.

So build the union once, as a view, with a column naming the traffic type, and have everybody query that rather than the underlying tables. Ten aggregate report streams also exist alongside the raw ones, and mixing raw and aggregate in the same analysis is another way to arrive at two different answers for the same question. Decide which family each report draws from and write it down.

Why does each stream family need a different cursor?

Because they describe different kinds of thing. Install streams track when an install happened and use install time. Event streams track in-app activity and use event time. Aggregate reports are summaries of a period and use the date. Applying one habit across all of them produces incremental syncs that either miss records or re-read far more than they need to.

This matters more in ClickHouse than it would elsewhere, because a poor cursor choice compounds with how the destination deduplicates. Records arriving repeatedly are resolved during background merges rather than on write, so a cursor that causes unnecessary re-reads fills the table with versions waiting to be collapsed, and a count taken before a merge runs will be higher than the same count taken after.

Use the timestamp appropriate to each family rather than anything string-shaped, since string cursors compare awkwardly and degrade as tables grow. Then apply FINAL wherever a figure is reported to somebody, particularly install counts and spend, and reserve it for those queries rather than using it everywhere, because it costs speed that an exploratory dashboard does not need to spend.

Frequently asked questions

Can I backfill more than ninety days?

Not through this connector. AppsFlyer serves raw data reports for the most recent ninety days, and an older start date is capped silently rather than raising an error.

Why is my install total lower than the dashboard's?

Check whether you are unioning all three traffic variants, since non-organic, organic and retargeting arrive as separate streams. Then check the timezone setting, which shifts daily boundaries.

Can I get ad revenue or fraud data?

No. Reinstall raw data, ad revenue raw data, postbacks and Protect360 fraud are all outside this connector, so those need a separate export route.

Our sync stopped after a staff change.

The token is tied to the account admin who created it, and AppsFlyer issues a new one when that admin changes. Update the connector configuration with the reissued token.

Can I do this without writing code?

The pipeline, yes. The union view across traffic types and the views applying FINAL are modest SQL, and without them people will reach different totals for the same question.

Get your Appsflyer data into ClickHouse

Confirm your subscription covers raw data and note the four report types this connector does not carry, because both are cheaper to learn now. Set the timezone to match your app. Build one union view across the three traffic variants so nobody double counts or under-counts. Give each stream family its proper cursor, apply FINAL where figures are reported, and remember that beyond ninety days your tables are the only copy.

Airbyte's connector catalog includes 600+ pre-built connectors, so attribution data can sit beside the revenue that justifies it. For the same source into a lakehouse, see AppsFlyer to Databricks, and for a comparable product analytics source into the same destination, Amplitude to ClickHouse.

Start syncing now →

Integrate with 700+ apps using Airbyte

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