Predictive LTV for SKAN: Day-0 Signals into pLTV Buckets

The short version: to run predictive LTV under SKAN, you train a model on first-session signals, produce one pLTV number per install, then bin that number into a handful of tiers and encode the tier into the conversion value you register before the timer expires. The conversion value is a tiny integer. Your pLTV model is the thing that decides what that integer means. Everything hard about this lives in the gap between a continuous revenue prediction and the six bits Apple lets you send home.

I came to attribution from the fraud side, so my instinct is to distrust any number that looks too clean. A conversion value that just counts events is clean and nearly useless. It tells you a user did three things. It doesn't tell you whether those three things are worth two cents or two dollars. pLTV is the honest version of that integer, and Liftoff has argued for years that passing back predicted LTV beats any single short-term metric, because it's the one signal that actually correlates with the money you'll book.

What you're actually modeling against

Before any feature engineering, get honest about the container. SKAN gives you a 6-bit fine conversion value, so 0 through 63, plus a separate coarse value that can only be low, medium, or high. That coarse value exists because of crowd anonymity.

Here's the part people gloss over. Apple decides how much of your postback survives based on install volume, not on your model quality. SKAN 4 replaced the old fixed privacy threshold with four crowd-anonymity tiers, 0 through 3. At the top tier you get the fine value and a fair amount of source granularity. Drop below the volume bar and you fall back to the coarse value, or to null. Adjust's own numbers put SKAN 3 null rates somewhere around 10 to 15 percent. Call it 1,000 to 1,500 basis points of your postbacks arriving with no signal at all. You cannot model your way out of that. You can only design so the degraded case still says something.

So the real design constraint isn't "how many pLTV tiers can I fit in 6 bits." It's "how do my tiers degrade gracefully when Apple hands me three buckets instead of sixty-four." Any recipe that ignores that is a demo, not a system.

Signal channel Range When you get it What to encode
Fine conversion value 0-63 (6 bits) High crowd-anonymity tier Full pLTV tier + short observation flag
Coarse conversion value low / med / high Lower tiers, thin campaigns Collapsed 3-way pLTV bucket
Null no value Below threshold Nothing — plan for it

The observation window is not day zero

Second thing to make peace with. "Day-0 signals" is marketing shorthand, not a literal timestamp. A single session has almost no predictive power on its own. AppNava's 2025 write-up on player LTV is blunt about it: one session predicts little, while a one-week window pushes model accuracy into the 0.785 to 0.792 range. That's a large jump for seven days of patience.

SKAN lets you have some of that patience. A widely used bit split reserves 2 bits for a roughly 3-day observation period and the remaining 4 bits to slice pLTV into 16 bins, an approach Liftoff and others have promoted since SKAN 3. Aarki's schema guidance frames the same idea across the three SKAN 4 windows: use window one (days 0-2) for the engagement event most correlated with 30-day LTV, then use later windows to confirm and to track realized value.

I read "day-0" as "the earliest window that still beats a coin flip." For most apps that's a 24-to-72-hour feature snapshot, scored right before you lock the value.

The feature list

You want features that are (a) available inside your observation window and (b) causally upstream of spend, not just correlated with it. Correlation-only features are how you end up rewarding bots that mimic engaged users. Keep the list short. A fat feature vector doesn't survive contact with a 6-bit output anyway.

Concrete first-session and first-window features that tend to earn their place:

  • Time-to-first-key-action (seconds from open to the first meaningful event — tutorial complete, first search, first add-to-cart)
  • Session count and total foreground time in the first 24 hours
  • Depth reached: levels cleared, screens visited, catalog items viewed
  • Any early monetization signal: first purchase, trial start, paywall view, currency balance
  • Notification opt-in and, for games, hard-currency spend velocity
  • Acquisition context you already hold client-side: campaign, creative family, install hour, device tier
  • A cheap retention proxy: did they return for a second session inside the window

Notice what's missing. No raw event counts as a headline feature. Counts are the first thing fraud farms inflate. I'd rather have time-to-first-action, which is annoying to fake convincingly, than a count of taps that any script can manufacture.

Label, model, and why gradient boosting

Your label is realized revenue over your true horizon, whether that's 30, 60, or 90 days, measured on historical cohorts where you already know the outcome. Train on users old enough to have a known LTV. Score new users with the same feature snapshot you'll have on day 0-ish. That symmetry is the whole game. If a feature won't exist at scoring time, it can't be in training.

For the model itself, boring wins. Gradient-boosted trees (LightGBM, XGBoost) are robust on exactly the data revenue gives you: skewed, zero-inflated, a long tail of whales dragging the mean around. AppNava's team reached for LightGBM for that reason, and it's the default I'd defend in a review. Revenue distributions break naive linear models. A tree ensemble shrugs.

One caution from the fraud desk. Whatever you train, log-transform the revenue label or model it in two stages (will they pay, then how much). A single regression on raw dollars will chase a handful of whales and misrank the middle of your distribution, and the middle is where most of your budget decisions actually land.

Collapsing a continuous prediction into tiers

Now the part the schema guides skip. Your model emits a continuous pLTV. SKAN wants a small integer. The bridge is quantiles, not fixed dollar cutoffs.

Do not hardcode "tier 5 = $50+." Dollar thresholds drift the moment your monetization or your mix changes, and then your conversion schema silently means something different than it did last quarter. Instead, bucket by percentile of your historical pLTV distribution. Six tiers on quantile boundaries stay stable even as absolute values move.

Here's a six-tier layout that fits comfortably in the fine value and folds cleanly to coarse:

pLTV tier Percentile band Fine value slot Coarse fold
T0: no predicted value bottom 40% 0 low
T1: marginal 40-70% 1 low
T2: modest 70-85% 2 medium
T3: good 85-94% 3 medium
T4: high 94-99% 4 high
T5: whale candidate top 1% 5 high

Six tiers, six fine values, with the observation-window bits packed alongside. And critically, each tier already declares its coarse fallback. When Apple drops you to the coarse value, T0 and T1 both read as "low," T4 and T5 both read as "high," and your bidding logic loses resolution without losing direction. That green-yellow-red mapping, scale on high, hold on medium, pause on low, is the same logic Aarki recommends for the first SKAN window, and it survives the anonymity downgrade.

If you want the deeper argument for why percentile bucketing beats fixed thresholds across a whole metric tree, this breakdown of activation and value metrics makes the case better than I can in a sidebar.

Wiring it into the postback path

Prediction happens on your side. Encoding happens through the SDK. The sequence, on-device:

  1. User installs, opens, and generates events through your observation window.
  2. Your model scores them (on-device if it's small, or via a fast server call keyed on the install).
  3. You map the pLTV to a tier, pack the tier plus window bits into the conversion value, and call updatePostbackConversionValue.
  4. SKAN's timer eventually fires and the (possibly degraded) value comes home.

Two operational truths. First, retrain on a schedule, quarterly at least, faster if you ship monetization changes, because a pLTV model trained on last year's economy will confidently misprice this year's users. Second, monitor your null and coarse rates as first-class metrics, not footnotes. If a campaign is running 1,500 basis points of nulls, the fix is media volume and campaign structure, never a fancier model.

For teams building this end to end rather than bolting it onto a spreadsheet, an analytics platform that already computes a predicted-LTV output can feed the exact same tier boundaries; Kixo, for instance, exposes predictive LTV alongside its product and attribution data, so the pLTV powering your SKAN schema can share one definition with the rest of your dashboards. If you want the full plumbing view of how a privacy-first stack routes signal from SDK to postback, the metric-tree reference and our own privacy-first attribution reference architecture both go a layer deeper than this recipe.

Backtest the schema, not just the model

One more habit from the fraud desk before you ship. Validate the encoded tier, not the raw prediction. It's easy to celebrate a model with a great AUC and then quietly lose most of that lift in the six-bit squeeze. So run the whole pipeline on a held-out historical cohort: score them with day-0 features, assign the tier, fold to coarse, and then check whether your six tiers still rank-order realized 30-day revenue in the right direction. If T5 doesn't outearn T4, and T4 doesn't outearn T2, your bucket boundaries are wrong even if the underlying model is fine. I've seen a perfectly good regression get ruined by lazy cutoffs, and the postbacks won't tell you, because by then it's aggregate.

Also backtest the degraded path on purpose. Force every tier down to its coarse fold and confirm the three-way signal still separates your best cohorts from your worst. That's the version Apple hands you on thin campaigns, and it's the version that has to keep your bidder pointed the right way.

What this recipe will and won't buy you

It'll give you a conversion schema that means something economically, degrades in a predictable direction under crowd anonymity, and stays stable as your revenue distribution shifts. That's most of the value.

It won't give you user-level truth. SKAN never will. You're sending a compressed, delayed, occasionally-null estimate into a black box and getting an aggregate back. Treat the pLTV tier as a bidding signal, not a ledger.

The teams that do this well aren't the ones with the fanciest model. They're the ones who designed the six bits first and fit the model to the container, instead of building a beautiful regression and then wondering why three-quarters of the resolution evaporated on the way to Apple. Build for the coarse value. Enjoy the fine value when you're lucky enough to earn it.