How Google Ad Manager counts impressions

Hello readers! It’s been a while. Today I’ll write about how Google Ad Manager, perhaps the most widely used ad server in the world, technically counts impressions. This topic is slightly off the usual adtech-madness / security / fraud I usually write about, but I think this information can be useful for both adops people and adtech developers out there who read my blog (yes, I do see all the JIRA URLs in the referrers).

First, let’s define two different terms:

  • Served impression: An impression counted when ad is sent, or “served” to a publisher by Ad Manager. The ad creative may or may not be rendered, downloaded in the user’s device, or viewed by the user.
  • Downloaded impression: An impression counted only after the initiation of ad retrieval by the publisher. The ad creative is downloaded in the user’s device and has begun to load. A separate viewability measurement will determine if the user has viewed the creative.

As documented by Google, since October 2017, Ad Manager counts downloaded impressions rather than counting the previously used served impressions.

Downloaded impressions are counted in Ad Manager’s report metric “Total impressions”, as defined in this documentation: “Total impressions from the Google Ad Manager server, AdSense, Ad Exchange, and yield group partners.” 

Now, let’s take a look on the mechanism that enables the served and downloaded impressions counting:

  • Served impressions: counted when ad response is generated by Ad Manager, following an ad request sent from a client (GPT, Mobile SDK, etc), minus empty responses. A typical ad request is an HTTP GET request of the following structure:×90%7C728x90%2C970x90%7C728x90&prev_scp=pos%3Dheader%26loc%3Datf%7Cpos%3Dbottom%26loc%3Dbtf%26hb_pb_appnexus%3D0.07%26hb_adid_appnexus%3D15d03fa1555417%26hb_bidder_appnexus%3Dappnexus%26hb_pb%3D0.07%26hb_adid%3D15d03fa1555417%26hb_bidder%3Dappnexus&eri=1&cust_params=url%3D%25&cookie_enabled=1&bc=31&abxe=1&lmt=1568307941&dt=1568307941545&dlt=1568307939347&idt=1736&frm=20&biw=1286&bih=150&oid=3&adxs=158%2C63&adys=20%2C1281&adks=3320811415%2C3303837207&ucis=1%7C2&ifi=1&u_tz=180&u_his=2&u_h=768&u_w=1366&u_ah=744&u_aw=1301&u_cd=24&u_nplug=2&u_nmime=2&u_sd=1&flash=0&×3369%7C1160x130&msz=1286×130%7C1160x90&ga_vid=1107594786.1568307942&ga_sid=1568307942&ga_hid=1496006620&fws=4%2C4&ohw=1286%2C1286

Which contains URL parameters with data about the user, device, publisher, page view, ad unit, key value targeting (in this case, including competing header bidding bid from appnexus) and more. Ad manager then runs ad selection process using this data, and increments the served impressions count, unless no appropriate ad to be served is found for the ad request. 

  • Downloaded impressions: A typical ad response is contained within the HTTP response body from Ad Manager, and looks like this:


        “/123456789/Adunit“: [“html”, 0, 0, null, 0, 90, 728, 0, 0, null, null, null, 1, [

                [“ID=77g96419f2b322c6:T=1568489951:S=ALMI_NZ7qGoFC9bbi5KjU33fgAMgJ48XZw”, 16313278841, “/”, “”]





            [452672344], null, null, null, null, null, null, null, 0, null, null, null, null, null, null, “CiYIsOaKPOgB4sms_IIEggIMoMW2YZjGtmHw1b5h0QJdRAkCBGXItQ”, “CNi3iq7iy-QCFQqxewodrpcMlw”, null, null, null, null, null, null, null, null, [“011908231648370”], null, null, null, null, null, “1”



    <!doctype html>… <!– Ad HTML in here –>

    As you can see, it contains:

    • The ad unit which this ad response targets (i.e., the ad request made on behalf of this ad unit)
    • Data about the ad type, size (728×90 in this case), and whether the ad response is empty
      • in this case 0, means false. Otherwise the parameters described below this line would be null), and the impression would not be counted, even as served impression.
    • Additional response information such as line item, advertiser, creative and unique impression IDs.
    • The actual ad HTML

    After the ad response is received by the requesting client, it renders the impressions by writing the actual ad HTML into the appropriate ad slot. The very first lines of standard Ad Manager creative boilerplate (i.e., HTML/JS code that’s automatically added into every creative served by Ad Manager) looks like this:

    <!doctype html>



          var inDapIF=true,inGptIF=true;


       <body leftMargin=“0” topMargin=“0” marginwidth=“0” marginheight=“0”>

          window.dicnf = {};

    data-jc=“42”>(function(){window.viewReq=[];function b(a){var c=new Image;c.src=a.replace(“&”,“&”);viewReq.push(c)}function d(a){fetch(a,{keepalive:!0,credentials:“include”,redirect:“follow”,method:“get”,mode:“no-cors”}).catch(function(){b(a)})}{window.fetch?d(a):b(a)};}).call(this);

    As you can see, the last two scripts that appear in this excerpt are:

    • Defining a function named vu that invokes a GET request to a given URL
    • Invokes the vu function with a URL specific for this ad impression

This scripts are executed synchronously (since they are parser inserted inline scripts), which means that before anything else, the browser will fire the view HTTP request and once it hits Ad Manager, it will be counted as Downloaded impression. 

I hope you find this information useful!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s