Feature Image

Building the acquisition loop

Spotify runs paid marketing across platforms like Facebook, Google UAC, and TikTok, and efficiency is critical for return on ad spend. Managing campaigns at global scale is too complex for purely manual oversight, so we set out to combine automated creative generation, machine learning, and ad interaction data to better convey Spotify's value, improve performance marketing efficiency, and handle the tens of thousands of ads we run.

Prior to 2019, a few off-platform content marketing tests produced mixed results. A manual test in H1 2019 showed the potential to gain incremental users with content ads, pushing us toward automation. We needed a system that could generate content-based ads, deploy them to digital channels, monitor performance, and adjust on the fly. Off-the-shelf tools covered part of the ground, but lacked scalable creative asset generation and reliable estimation of cost per registration (CPR) per market. We converged on a five-stage loop: Ingest, Rank, Deploy, Learn, Repeat.

Scaling creative generation

Our first focus was content generation, since a single Facebook campaign can demand dozens of aspect ratios and sizes; with styling and cover art, one campaign per language or region can require hundreds of assets. If generation couldn't scale, off-platform work would stall. We started with a Java-based backend service that pulled content from metadata services and layered it into static images using basic templating and our color picker.

That approach served static imagery but forced us into simplistic templates, which motivated us to push toward motion.

Finding the animation route

Static ads are useful when a user's bandwidth is limited, but motion generally improves engagement. Simple animations are feasible with translation routines and Bezier curves, while complex treatments require JSON-based references beyond what hardcoded templates could handle. We also faced right-to-left language issues for Arabic and creative constraints for designers. We evaluated Lottie and Blender, which were already used at Spotify, but Lottie couldn't meet templating needs at scale and Blender wasn't familiar enough for fast, compelling creative work.

Adobe After Effects stood out: teams knew it, and its templating allowed generating the many necessary aspect ratios and sizes with the creative freedom designers wanted. The catch was that After Effects runs as a desktop application, which we couldn't trivially launch in a GCP compute instance.

Adobe offers a command-line helper to trigger the render pipeline, which felt like a breakthrough. Still, it required a host node with After Effects installed and compositing assets available locally to the OS image. It was close, but not quite the right fit.

That led us to nexrender, an open source project that turns aerender into a batchable system. With nexrender we could script file transfers from network locations, request multiple output formats simultaneously, and manage headless aerender nodes to handle large batch jobs efficiently. This combination gave us the automation we needed for creating visuals.

With creative assets handled, the questions became what content to include, where to place it, and how to tailor ads for audiences like Gen Z in the EMEA region. That demanded a way to decide and adapt automatically, which set the stage for the next phase of the system.

Ranking content with data and machine learning

Ranking content against performance data was the core challenge: knowing which artist to feature in which market, paired with the right ad creative template. We built data pipeline components that query ad platform APIs and mobile measurement partner (MMP) APIs for metrics like clicks, impressions, installs, registrations, and subscriptions, layering that with attribution data to produce a solid training set. Our distinguishing factor was combining campaign ad performance with the local popularity of artists per country from Spotify's content catalog, giving the ranking model meaningful signal to work from.

One might ask: why not simply generate every possible combination and let social media and search platforms' targeting algorithms select the best performers? Those algorithms work well when optimizing across a handful of ads, but they aren't designed for the nearly unlimited options we'd be trafficking. That's why we needed a preranking step to shortlist the most promising ad creatives before running them.

The heuristic approach to preranking

To keep the problem tractable, we first focused on choosing a set of artists per campaign to maximize reach, conversion, and cost efficiency. The complication: while we know a lot about our artists — like their popularity — we don't have direct visibility into how they perform inside third-party platforms, which users saw an ad, or how costs shift with market demand and competition.

Since those raw numbers weren't available to us, we turned to the ad platforms themselves for signal. We used each platform's own ad-placement algorithms and rebalancing behavior as a proxy, deriving a quality score for each artist from the share of registrations they generated. Before solving the preranking problem, we had to address two questions:

  1. How do we combine this quality score with other information like artist popularity?
  2. How do we estimate quality scores for artists we haven't yet observed?

Our first heuristic answered these by combining three factors — popularity, share of registrations, and diversity — weighing each equally. We selected eight artists per campaign by popularity, observed their registration shares, then used our artist-similarity knowledge graph to predict quality scores for similar, unobserved artists. We evaluated performance and optimized by balancing popularity with differentiation from remaining artists and ads, giving the heuristic a controlled exploration of a diverse pool.

Moving to a supervised ML model

We next asked whether each factor could contribute differently rather than equally in predicting artist quality. This became a supervised ML problem: features of each artist predict share of registrations, with popularity now just one feature among many. This allowed us to include features the heuristic never considered, such as campaign metadata — market, ad creative dimension, operating system, template theme and variation, and so on.

The heuristic let us get up and running quickly, but the ML solution combined the covariates into a more powerful algorithm that netted 9% more monthly active users (MAUs) over the heuristic during its lifetime of operation.

We implemented the model using the XGBoost library (via the Spotify Kubeflow managed service), which uses gradient boosting internally. Each day, the model trained on historical data over a lookback window and predicted two primary target variables.

For Spotify free-tier ads the targets were:

  • reg_percentage: the percentage of Spotify user registrations the ranked artist contributes to
  • relative_cpr_ratio: the ratio of the ranked artist's share of a campaign's overall cost per registration (CPR)

For Spotify premium-tier ads:

  • sub_percentage: the percentage of Spotify premium user subscriptions the ranked artist contributes to
  • relative_cps_ratio: the ratio of the ranked artist's share of a campaign's overall cost per subscription (CPS)

We chose relative rather than absolute metrics intentionally: raw numbers like registration counts and unit costs are subject to external market forces — ad supply and demand, competitor activity — that are difficult to model reliably.

We validated the model against the heuristic by running an A/B test in two regions over three weeks, with the heuristic as control and the ML model as treatment. The results were decisive: the ML model achieved a 4% and 14% cheaper CPR in the two regions respectively, largely because ads generated from the ML rankings had an 11% to 12% higher CTR, a product of the richer training data with more features.

Given these results, we productionized the ML model to handle content ranking across all active campaign regions. Here's the end-to-end architecture of what we put into production:

A high-level view of the automated marketing loop.

Asset Rendering Moves Offline

Our first major hurdle was the shift from Java templates to After Effects for asset generation. What used to happen inline during an API call now required asynchronous rendering, which brought its own operational burden: scaling render workers up and down to match the volume of assets being produced at any given moment.

The lesson here is about architectural humility. Systems get designed around the assumptions you hold at the time, and those assumptions will eventually be tested. When new requirements arrive, the best path is to fold them into the design as nonintrusively as possible, moving incrementally rather than forcing a rewrite. Modular components make this easier, but no amount of foresight will let you predict every pressure point.

External API Dependencies

Our ML content ranking model depends on daily ingestion of ad performance metrics from platform APIs. When those APIs falter, the whole ranking flow is at risk. We saw this firsthand during a couple of Facebook API outages that stalled model training and left us without fresh content rankings until the marketing API recovered.

That experience drove home the need for a fallback. Our workaround was simple: keep using the previous day's artist rankings when the latest day's ad performance data is unavailable. It's not perfect — the model can't react to recent shifts — but it keeps the system running when an external dependency goes dark.

IDFA and Industry Shifts

Apple's IDFA changes, effective from iOS 14.5 onward, rewrote the rules on what ad-tech companies can collect and use. For us, it meant we could no longer assume we'd get user-level or log-level ad performance data for campaign optimization. Fortunately, our model trains on aggregated data over a lookback window, so the impact was muted.

But we didn't just hope for the best. As soon as IDFA was announced, we ran offline analyses to check whether the model's output would degrade. It didn't. The broader takeaway: when industry-wide changes loom, build a way to assess your system's resilience and have alternative approaches ready before you need them.

Migrating Attribution Partners

Spotify's move from Adjust to Branch for deep linking and attribution — detailed in a separate engineering post — meant touching every data pipeline and the ML model itself. All ad metrics had to be sourced from Branch instead, and the system needed recalibration to keep rankings sound.

The migration was managed deliberately. We verified that Branch-sourced attribution data didn't hurt model performance, wrote detailed technical specs for the work, and confirmed with stakeholders that metrics were flowing correctly before cutting over. The model's performance held steady throughout. The design principle that carried us: keep the system adaptable enough to swap external dependencies without sacrificing output quality.

Diversity in Rankings

Encoding artist diversity into a supervised learning algorithm turned out to be harder than expected. Naive approaches failed, which is no surprise — this is the classic slate recommendation problem, and it's genuinely difficult. It's also a rich area for future work.

The broader lesson is about iteration in ML. You can't wait for your platform and its surrounding systems to stabilize before building algorithms — backends, pipelines, processes, and even industry policies like IDFA are all moving targets. Meanwhile, the most impactful systems have to stay responsive to data. Sometimes that means a quiet heuristic with few moving parts; other times it calls for the full orchestra of cross-platform tech, like artist embedding vectors. Supporting that range of complexity is where real progress comes from.

Building End to End

What started as a simple hypothesis — that engineering and content could make Spotify's Performance Marketing more efficient — grew into an end-to-end automated system that generates content ads and optimizes them continuously. It took close collaboration between Engineering and Marketing to pull off, and we're proud of the result: fully automating the Performance Marketing cycle is something only a handful of tech companies have achieved globally.