clock menu more-arrow no yes

Filed under:

Speeding up and Overriding Ad Server Targeting During Local Development

Dumplings, a tasty wrapper
Dumplings, a tasty wrapper
Charles Haynes

Hi, I’m Brian. I’ve been working on the ads platform team at Vox Media since October 2013. A good portion of my time is spent supporting and developing the systems that help ads get displayed on the page in a way that scales for all of our users on all of their devices. In addition to building our ad platforms, I work with the many talented designers and engineers who make our ads look amazing. We put a lot of effort into building great ads. We believe this effort creates great user experience, which in turn creates a great brand experience. Because of this, there is a lot of iteration and testing that goes into each of our ad products.

The Complexity of Targeting

Our ad server partner is OpenX. They handle all the complex parts of figuring out who sees what ad. This ad-targeting logic takes into account many factors, including: revenue goals, location, time of day, share of voice, device types, screen sizes, and the content itself. There are many possible combinations of ads, and fairly complex rules that account for what ads a reader sees at any given moment. This is exactly the type of system you need to run a large site – but it is also the kind of system that can be difficult to test locally.

How Ads Work

The way ads are displayed in your browser is a three-step process.

  1. Each page layout designates the types of ads it can display and their location on the page.
  2. When the page is rendered by the browser, we pass along this information as well as information about your device type and screen size to our ad server, OpenX.
  3. OpenX responds with the currently targeted creative assets that should be placed into these ad slots on the page.

All of our developers, designers, and managers running Chorus (our platform for digital-native authoring, publishing, and distribution; and focused, high-quality community) locally are served ads through OpenX – such that, in the course of working on our platform and sites, we experience the content and ads together (just like you). But, until recently, we weren’t able to easily control which ads are displayed when developing locally, and that lack of control got in the way when building new ad products and quickly iterating on designs. There are times when a developer wants to force a certain ad-creative to render on the page in a specific ad slot in their local environment. So we designed a system to help us do just that.

Ad Server Proxy

We created a small server that acts as a proxy. It sits between the browser and our ad server in development mode, right between step 2 and 3 above. This small proxy server has three responsibilities: insert new ads, override existing ad unit targeting, and speed up requests to the ad server – all while showing the default targeted ads when no local overrides exist.

When enabled, all requests to our ad server are proxied through this server. The proxy intercepts the request, makes a full request to OpenX, and then caches the results in Redis (or memory). Before it responds to the browser, the proxy looks at our local configuration file for applicable overrides and ads to insert. The next time the page is displayed, the response to the ad server request is returned directly from the cache.

Ad Server Proxy

Ad Server Proxy Visualized

How does this work? You know, technically?

While the proxy server does a little bit of heavy lifting, we wanted our Chorus integration and configuration file to be super simple.

Before any ad is served, we first request OpenX’s standard javascript library. We do this through our proxy, which caches the response and overwrites the function that requests the targeted ads JSON response from the ad server. This way, from here on out, requests for ads go through the proxy, which speeds up the response time and allows for local modifications.

Now all future interactions with OpenX will automatically prefaced with http://localhost:9292/mock&url= sending them through our proxy. Their responses will be cached for five minutes.

So we get a win on the speed up, we get default ads if no overrides are specified, and it all comes with just a single line change in Chorus.

The config file is equally as simple, it is a YAML file that contains an array of overrides.

The url_pattern is a regular expression that defines the URLs for which the proxy will insert the given ad creative override. The unit_id is our internal ad slot identification. For example, 304992 is our IAB medium rectangle on polygon.com. And the html is just that — it defines the elements that will be inserted into this ad spot on the page.

Real world example: Prelude

We’ve recently released a network-wide ad product that we call Prelude. It is a full bleed ad that sits above the content. It is our way to do interstitials that places graceful creative ads on the page in a way that still respects our readers. Because we are running this across all Vox Media properties, there was a lot of testing required because Racked, Polygon, Verge, and Vox have different HTML structures. And this one ad had to work across all of them. To test this we needed to add a new ad-slot (we call these ad units) to our pages and then deliver the creative into these slots. Ideally we would like to force the ad’s html right into the page, but also account for the javascript request/response cycle that is a key piece of delivering the correct ad to you. The ad server proxy allows us to use all the mechanics of our production ad serving and rapidly explore different creative directions without needing to fiddle with the ad server.

Prelude Example

Example of a custom ad

Help us make it better

We’ve been working with the ad server proxy for the last couple of weeks and it has been a huge boost to developing new ad products and new ad creative locally. It lets us quickly iterate on ads to deliver beautiful, compelling, engaging, and respectful because we think of our ads as part of a total positive user experience.

We found the ad server proxy useful and thought others might too, so we open-sourced it. It is available right now at https://github.com/voxmedia/ad-server-proxy. Please fork it, try it out, and let us know what you think. It is a young project, and while it is specific to OpenX, the general pattern can be extended easily to other ad servers. Let’s grow this thing together.