How to scale and optimize marketing spend with SKAdNetwork

This article is partially adapted from my workshop, How to Build and Scale successful apps without the IDFA. The workshop is being presented through the end of August 2020.

Apple de-stabilized the mobile ecosystem in June, when it announced the effective deprecation of the IDFA — the advertising identifier on iOS, and the keystone of all mobile advertising infrastructure — at WWDC 2020. Background on this decision and its impact on mobile advertising can be found in this article.

I have dedicated a considerable amount of time to explaining why the IDFA changes were likely instigated by Apple (with respect to its position in the ecosystem, as well as the positions of companies that sit adjacent to Apple within the ecosystem, such as Facebook), but in this article, I’ll provide an overview of how I think marketers can adapt to these changes in order to achieve optimal mobile advertising efficiency. The overarching strategy I present in this article is predicated on three core components:

  • Highest Value Conversion Value (HVCV) selection;
  • LTV imputation and ROAS estimation;
  • Campaign optimization and budget balancing.

Highest Value Conversion Value (HVCV) selection in SKAdNetwork

A conversion value parameter was added to the SKAdNetwork postback in the version 2.0 that was revealed at WWDC 2020 (for more background on the version 1.0 of SKAdNetwork, see this article that I wrote in 2018 when SKAdNetwork was introduced by Apple: Will Apple redefine mobile advertising with SKAdNetwork?). The conversion value parameter allows app developers to send a 6-bit value back to advertising networks with the attribution of an install. A conversion value corresponds to whatever the app developer wants to map it to, but a postback can only include one 6-bit value: the highest recorded by the app within the constraints of timer logic. The timer logic is convoluted: before continuing on below, read a full background of the logic in this QuantMar thread.

Utilizing the conversion value optimally will be a core part of performance marketing strategy going forward with iOS14: the conversion value is the only information the network will receive to help it optimize campaigns against in-app behavior, and so the conversion value needs to be used such that it carries maximum “signal,” or imputed value, with respect to how the underlying user will eventually monetize.

This is a big topic, but as an overview, I think conversion value strategy navigates a trade-off between two competing constraints:

  1. When the conversion value is triggered;
  2. What the conversion value represents.

The timing of the postback is critical for performance optimizations, for two reasons. First, the SKAdNetwork postback doesn’t include a date parameter, meaning the advertising network won’t be able to cohort postbacks because it won’t know when, relative to the postback being received, the attributed user actually clicked on an ad. And second, the longer the network has to wait to receive the postback, the longer the timeline will be over which it optimizes targeting for the campaign.

In practice, this means: creating moments in the app that are designed to correlate with high user LTV, and instrumenting the updateConversionValue() method in the app such that any subsequent conversion value that it is fired against is lower than the previous value so as to avoid resetting the 24-hour conversion value timer. This may also involve designating a time window within the FTUE or first session after which updateConversionValue() is not called in order to minimize the amount of time in which the postback can be fired after install.

It is therefore important that the advertiser design the conversion value triggering in such a way that it fires as soon as reliable information about the user has been collected. This means that, for most advertisers, simply mapping 6-bit conversion values to existing events in the app won’t make sense: these events are currently instrumented to be collected in aggregate and sent to ad networks (read: Facebook and Google) for use in building monetization profiles of users, indexed against their IDFAs. Since only one conversion value can be sent with the postback, advertisers will need to create new synthetic events that are designed to capture imputed LTV or that simply aggregate up as users do things in the app that reflect higher levels of engagement.

LTV imputation and ROAS estimation

Note that all of the above is work that specifically relates to product design and analysis (which events carry the highest imputed LTV): SKAdNetwork is accelerating a trend that I have written extensively about in which advertising strategy has seeped deep into the product as event-optimized, automated campaign management dominated mobile advertising. The irony with SKAdNetwork is that, while the precision targeting of these campaigns is massively impaired without the IDFA, all of the signal that an ad network is ever going to receive from a given user is now concentrated in just one conversion value (versus in the current paradigm, where the ad network receives many signals and is able to draw a more complete picture of the user).

Thus, architecting these events for maximum predictive power becomes even more important with SKAdNetwork because the app only has one opportunity to communicate value to the ad network supplying a user. The analytical evaluation of these events within the very restrictive segmentation constraints that are now placed on app developers — because, unlike now via MMP postbacks, the app will not receive any source context about the user in the few seconds / minutes after install — becomes one of the primary mechanisms for optimizing advertising campaigns.

There are a number of ways that a developer might impute an LTV to some moment or user state in an app. The first is aggregating up average values based on conditional probabilities with respect to combinations of “events” completed by the user in the app (as per the image above). An example might be: what’s the average monetization level of a user for a shoe-buying app at the point of adding a pair of shoes to the cart, given that they have viewed 10 pairs of shoes prior to doing that?

Note that this differs from the “event” paradigm that most developers currently use to send explicit in-app actions (such as “level complete”) back to ad networks. In this new reality, app developers themselves need to calculate imputed LTVs; they can’t rely on ad networks doing it for them. So an “event” in this case is not a notification that the user completed some action — such as adding an item to cart — but rather a user state, based on behavioral history, that lends itself to monetization prediction. Developers shouldn’t simply wrap their existing event transmission system with updateConversionValue() and hope for the best; rather, they should be measuring these user states on the basis of potential monetization and mapping those states to predicted LTVs.

As in the example above, this might be accomplished by mapping LTV levels to specific 6-bit conversion values and using an online service to estimate LTV in real time as the user progresses through the app. But this is hard. Very few developers have the requisite domain knowledge to build such a service in a way that produces reliable predictions — this type of expertise sits far outside of the standard boundaries for product development. But it’s possible to potentially bucket users into LTV ranges in real time, and to update those estimates within some conversion value window so as to send the most reliable, most recent LTV range estimate within some amount of time after install.

Another approach, as above, is to simply map 6-bit conversion values to various actions that can be taken by users in the app and to base LTV estimates on those actions ex posto facto (eg. when looking at the aggregated counts of the conversion values as reported by ad networks). This approach is simpler to implement but it lacks the contextual insight of real-time estimates, which is important because postbacks can’t be cohorted, and LTV estimates based on specific actions may change significantly over time.

Campaign optimization and budget balancing

In understanding how campaigns can be optimized in the SKAdNetwork environment, it’s helpful to enumerate the data to which ad networks will be exposed across SKAdNetwork postbacks and their own auction mechanics:

  1. Cost: ad networks will know how much any campaign has spent via CPM prices and total impressions served;
  2. Impression and click counts: ad networks will know when impressions have been filled and when ads have been clicked;
  3. Installs: ad networks will receive install notifications via SKAdNetwork postbacks and can aggregate install counts by campaign ID;
  4. Conversion values: ad networks will receive per-install conversion values via SKAdNetwork postbacks and can aggregate conversion value counts by campaign ID.

Through access to this data, ad networks will be able to natively optimize campaigns against click and install costs and on the basis of click-through and install rates. Networks will also be able to optimize campaigns against the incidence of various conversion values, but without any further context (eg. a mapping of conversion values to in-app engagement and monetization events), they won’t be able to optimize against ROAS or LTV.

But advertisers will: with their own imputed LTVs attached to various in-app states, or with their predicted real-time LTV range assignments, advertisers will be able to “roll up” conversion value counts at the campaign level into lifetime value revenue estimates and measure ROAS accordingly (against cumulative campaign cost).

There are two limitations to this measurement approach, however:

  1. Since campaign data isn’t cohorted (as discussed previously), the “new” data being aggregated at the campaign level each day won’t necessarily correspond to daily performance changes. The initial 24-hour conversion value timer can theoretically be reset 64 times; if conversion values aren’t carefully engineered to be sent quickly after the first app open, then postbacks will be received on a rolling basis in a way that doesn’t allow performance to be measured in real time by day (eg. I receive 10 postbacks today, and each of them belongs to a user that installed the app on a different date);
  2. SKAdNetwork only makes 100 campaign IDs available to each network for each advertised app. This means that campaigns will need to be targeted fairly broadly, since the ability to target very many combinations of eg. geography, interest targets, device targets, and ad creatives will be constrained by the 100 available campaign IDs.

As a result of this, much of the targeting and optimization work that is currently “outsourced” to large ad platforms like Google UAC and Facebook will need to be internalized: through automated, dynamic campaign performance testing and through app personalization. Both of these topics go beyond the scope of this article, but they are covered in How to Build and Scale successful apps without the IDFA.

Putting it all together

One approach to measurement I’ve seen championed in the weeks since WWDC has been that of probabilistic attribution: using behavioral profiles to attempt to associate (“tag”) users with the channel or campaign most likely to have sourced them.

I think this will be difficult to do competently. First: any model being trained now, while ad platforms have unfettered access to IDFA and can target on that basis, is instantly rendered irrelevant when iOS14 is rolled out. The results of any tests of probabilistic attribution being run now, in an environment that looks vastly different than that which will exist once the IDFA has been deprecated, are not reflective of post-IDFA performance. Additionally, I believe there will be significant selection bias present with opt-in traffic, so I don’t think training models on opt-in traffic will yield real predictive power for opt-out traffic. And without the ability to update model priors with successful prediction results, the models will simply privilege the channels that currently produce the most, highest-value traffic for advertisers.

My sense is that the best strategic path forward for mobile performance advertisers is to lean into the SKAdNetwork framework and to fundamentally shift their advertising approach away from user- and device-centric targeting to campaign-level optimization. Doing this well means establishing an acute product focus on delivering conversion values to ad networks that are predictive of user LTV. Swimming against the current by trying to bolt very complex and difficult-to-validate models onto existing advertising infrastructure feels like a long-term mistake.

The strategies outlined above are, naturally, limited by a lack of information about many aspects of SKAdNetwork: how it evolves over time (I published some suggestions recently), what Apple allows with respect to fingerprinting and other PII pairing (I’m not very optimistic about this), and what new ad tech emerges to help advertisers efficiently deploy marketing budget. But leaning into the SKAdNetwork framework is a relatively low-risk bet: Apple appears to be championing SKAdNetwork as the central measurement tool for iOS, and advertisers should understand how to build infrastructure and strategy around it.

Photo by Benjamin Voros on Unsplash