title |
---|
Calculations |
import ConventionalModelDefaults from "/snippets/defaults_conventional_model.mdx"; import PowerModelDefaults from "/snippets/defaults_power_model.mdx"; import VideoPlayerDefaults from "/snippets/defaults_video_player.mdx"; import ConsumerDeviceDefaults from "/snippets/defaults_consumer_device.mdx"; import DeviceSizeDefaults from "/snippets/defaults_device_size.mdx"; import MediaSizeDefaults from "/snippets/defaults_media_size.mdx"; import TimeInViewDefaults from "/snippets/defaults_time_in_view.mdx"; import AdPlatformDefaults from "/snippets/defaults_ad_platform.mdx"; import NetworkTrafficDefaults from "/snippets/defaults_network_traffic.mdx"; import ChannelMappingDefaults from "/snippets/defaults_channel_mapping.mdx";
Channel | Description |
---|---|
web |
Website that is not primarily social or CTV |
app |
Mobile app that is not primarily social or CTV |
social |
A social platform (Snapchat, Facebook, etc) |
ctv-bvod |
A TV-like streaming platform |
streaming-video |
Website or app with online video content |
audio |
Audio content (podcasts, streaming music) |
dooh |
Digital out of home - billboards, transit, etc |
Device type | Description |
---|---|
phone |
A phone |
tablet |
A tablet |
pc |
A pc with a monitor or a laptop |
tv |
A TV |
smart-speaker |
A smart speaker - Amazon Echo or equivalent |
Network type | Description |
---|---|
mobile |
A mobile network (3G/4G/5G) |
fixed |
A fixed network (broadband) |
Field | Description |
---|---|
size_bytes |
Size of the javascript/html for a video player if present |
buffering_seconds |
Video player buffering - if player preloads content, leave blank |
download_trigger |
What starts the content download - impression, view (ie lazy load), play |
Field | Description |
---|---|
rendered_width_pixels |
Width of the creative when rendered. Leave blank for responsive (will assume screen width) |
rendered_height_pixels |
Height of the creative when rendered. Leave blank for responsive (will assume screen height) |
image_sizes |
Array of image dimensions (eg ["300x250", "70x70"] ) |
audio_duration_seconds |
Audio duration (if applicable) |
video_duration_seconds |
Video duration (if applicable) |
video_player |
Video player used to render video (if applicable) |
other_assets_bytes |
Metadata, text, html, etc |
ad_platforms |
Ad serving, verification, and measurement ad platforms wrapping or embedded in the ad format |
300x250 programmatic banner
image_sizes = ['300x250']
rendered_width_pixels = 300,
rendered_height_pixels = 250
30 second audio inserted into a podcast
audio_duration_seconds = 30
15 second outstream video
video_duration_seconds = 15;
video_player = 'default',
rendered_width_pixels = 500,
rendered_height_pixels = 400
Native product carousel
image_sizes = ['400x400','400x400','400x400'],
other_assets_bytes = 7321,
rendered_height_pixels = 600,
rendered_width_pixels = 450
Field | Description |
---|---|
channels |
The channel(s) of this property |
average_seconds_per_session_excluding_ads |
The average length of a session on this property excluding ads (eg 44 min of a 60 min TV show) |
average_imps_per_session |
The average number of impressions per session |
average_data_kb_per_session_excluding_ads |
The average number of KB transferred during a session excluding ads |
video_bitrate_kbps |
The average bitrate for a CTV-BVOD property (e.g. 4200 kbps) |
ad_funded_percentage |
0-100 The percentage of content funded by advertising (eg 50) |
allocated_adjusted_corporate_emissions_kgco2e |
This property's share of corporate emissions |
total_sessions |
Number of sessions in the same time period as corporate emissions |
organization_model_quality |
Parent organization model quality (1-5) |
model_quality |
Model quality (1-5) |
Field | Description |
---|---|
emissions_per_creative_request_per_geo_gco2_per_imp |
Adjusted, allocated emissions per creative request by continent (NAMER, LATAM, EMEA, JAPAC) |
emissions_per_bid_request_per_geo_gco2_per_imp |
Adjusted, allocated emissions per bid request by continent (NAMER, LATAM, EMEA, JAPAC) |
emissions_per_rtdp_request_per_geo_gco2_per_imp |
Adjusted, allocated emissions per rtdp request by continent (NAMER, LATAM, EMEA, JAPAC) |
bidders |
Array of ad platforms that are sent bid requests |
real_time_data_providers |
Array of ad platforms that are sent real-time data requests (not propagated) |
distribution_rate_by_bidder_by_country |
Traffic shaping data for each bidder by country (eg 'xandr.com', 'US', 0.58 ) |
average_bid_request_size |
Average size of a client-side bid request |
sends_client_side_requests |
Does this platform send client-side bid requests (eg prebid client) |
model_quality |
Model quality (1-5) |
Field | Description |
---|---|
ad_platforms |
The ad platforms called by this placement |
Field | Description |
---|---|
impressions |
The number of impressions counted (required for all channels other than DOOH) |
views |
The number of views counted |
plays |
The number of plays (required for DOOH) |
utc_datetime |
Date and time, in UTC, when impressions were delivered |
country |
The country where the impression was delivered |
region |
The region of the country where the impression was delivered |
channel |
See channels |
device_type |
See device types |
network_type |
See network types |
property |
See property |
creative_ad_format |
Either a basic or vendor-provided ad format |
creative_ad_platforms |
Ad serving, verification, and measurement ad platforms wrapping or embedded in the creative |
creative_total_image_data_transfer_bytes |
Total bytes for the data transfer for the image itself for all impressions, ideally measured by the CDN |
creative_image_sizes |
Array of image sizes included in the creative |
creative_total_audio_data_transfer_bytes |
Total bytes for the data transfer for the core audio asset for all impressions, ideally measured by the CDN |
creative_audio_duration_seconds |
Average audio duration in seconds for a single impression |
creative_total_video_data_transfer_bytes |
Total bytes for the data transfer for the core video asset for all loads, ideally measured by the CDN |
creative_video_vast_bytes |
Average size of VAST/VPAID wrapper for the video in bytes for a single load |
creative_video_bitrate_kbps |
Video bitrate as delivered in kilobits per second |
creative_video_size_bytes |
Average video size as delivered in bytes for a single load |
creative_video_duration_seconds |
Video duration in seconds |
creative_video_view_time_seconds |
Average time, in seconds, that a video is viewed |
creative_video_view_rate |
Average percentage of a video that is viewed |
creative_time_in_view_seconds |
Time that the creative was visible on the device |
creative_is_3p_served |
Is the ad format served by a third party ad server |
From SRIxAD database 2.1, original source ADEME_220830_v1.4
From Carbon impact of video streaming (Carbon Trust), Table 5; and calculated here
From ITU Data Hub (2022 data)
Based on actual data transfer of https://vjs.zencdn.net/8.10.0/video.min.js on February 23, 2024
Based on YouTube recommendations, Wikipedia
From common devices (Quad HD 27” monitor, iPhone 13, Nexus 5X, iPad Air 1/2, iPad 2/3, Nexus 9, 1080P TV)
See Consumer Devices
Observations from various channels
Observations from various channels
Providers should clearly and publicly document:
- Which data provider is used for carbon intensity data (for instance, WattTime or ElectricityMaps)
- What carbon intensity metric is used (marginal vs average)
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
should look up the carbon intensity in gCO2e based on 100-year global warming potential (GWP100) from a database at no less than hourly granularity.
lookup_carbon_intensity_quality(country, region)
should return the quality of the underlying grid mix data on a scale of 1-5 per Model Quality.
We use all data we have available on every single request but in many situations we may lack some information, for this we have a series of fallbacks to be able to provide reasonable estimates in most situations.
To determine network when it's not submitted we calculate costs associated to network type as a weighted average of the fixed and mobile usage in the country (if available) or worldwide.
We can also generally determine the channel from the property or when that is ambiguous but we have device information we fall back to a default channel by device.
pct_mobile =
country ?
default_percent_mobile_by_country[country] / 100 :
default_percent_mobile / 100
average_embodied_emissions_gco2e_per_kb =
default_network_embodied_emissions_gco2e_per_kb['mobile'] x pct_mobile +
default_network_embodied_emissions_gco2e_per_kb['fixed'] x (1 - pct_mobile)
embodied_emissions_gco2e_per_kb =
network_type ?
default_network_embodied_emissions_gco2e_per_kb[network_type] :
average_embodied_emissions_gco2e_per_kb
average_usage_kwh_per_gb =
default_usage_kwh_per_gb['mobile'] x pct_mobile +
default_usage_kwh_per_gb['fixed'] x (1 - pct_mobile)
usage_kwh_per_gb =
network_type ?
default_usage_kwh_per_gb['network_type'] :
average_usage_kwh_per_gb
average_baseload_watts =
default_baseload_watts['mobile'] x pct_mobile +
default_baseload_watts['fixed'] x (1 - pct_mobile)
average_dynamic_watts_per_mbps =
default_dynamic_watts_per_mbps['mobile'] x pct_mobile +
default_dynamic_watts_per_mbps['fixed'] x (1 - pct_mobile)
baseload_watts =
network_type ?
default_baseload_watts[network_type] :
average_baseload_watts
dynamic_watts_per_mbps =
network_type ?
default_dynamic_watts_per_mbps[network_type] :
average_dynamic_watts_per_mbps
lookup_channel:
if property.channels.length == 1:
return property.channels[0]
if channel && channel in property.channels:
return channel
is_audio_creative =
creative_audio_data_transfer_bytes ||
creative_audio_duration_seconds ||
ad_format.audio_duration_seconds
if is_audio_creative && 'audio' in property.channels:
return 'audio'
if device_type && default_channel_by_device[device_type] in property.channels:
return default_channel_by_device[device_type]
return property.channels[0]
channel = lookup_channel()
device_type = device_type ? default_device_by_channel[channel]
creative_data_transfer_emissions_gco2_per_imp =
creative_data_transfer_usage_emissions_gco2_per_imp +
creative_data_transfer_embodied_emissions_gco2_per_imp
For all channels other than CTV/BVOD, use the conventional model:
creative_data_transfer_bytes =
video_bytes +
audio_bytes +
image_bytes +
ad_format.video_player.size_bytes +
ad_format.other_asset_bytes
creative_data_transfer_usage_emissions_gco2 =
creative_data_transfer_bytes / 1000 x
usage_kwh_per_gb / 1000000 x
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
creative_data_transfer_embodied_emissions_gco2 =
creative_data_transfer_bytes / 1000 x
embodied_emissions_gco2e_per_kb
If data transfer is provided in the delivery row, use it:
image_bytes = creative_total_image_data_transfer_bytes
video_bytes = creative_total_video_data_transfer_bytes + (creative_video_vast_bytes x loads)
audio_bytes = creative_total_audio_data_transfer_bytes
Otherwise, calculate data transfer:
image_sizes = creative_image_sizes ? ad_format.image_sizes
image_bytes = SUM(image_sizes[n].width x image_sizes[n].height) x 3 / default_image_compression_ratio x impressions
audio_duration = creative_audio_duration_seconds ?? ad_format.audio_duration_seconds
audio_bytes = audio_duration_seconds x default_audio_bitrate_kbps[device_type] / 8 x 1000 x impressions
is_primary_experience = !ad_format.rendered_width_pixels && !ad_format.rendered_height_pixels
default_bitrate_kbps =
is_primary_experience ?
default_video_bitrate_kbps[device_type] :
default_non_primary_video_bitrate_kbps
video_bitrate_kbps =
creative_video_bitrate_kbps ??
creative_video_size_bytes x 8 / 1000 / creative_video_duration ??
property.video_bitrate_kbps[device_type] ??
default_bitrate_kbps
video_duration = creative_video_duration_seconds ?? ad_format.video_duration_seconds
seconds_watched = creative_video_view_time_seconds ??
creative_video_view_rate x video_duration_seconds ??
video_duration_seconds
buffer = ad_format.video_player.buffering_seconds ?? infinity
seconds_streamed = MIN(seconds_watched + buffer, video_duration_seconds)
loads = switch(ad_format.video_player.download_trigger):
'view': views
'play': plays
'impression': impressions
video_bytes = (video_bitrate_kbps / 8 x 1000 x seconds_streamed + creative_video_vast_bytes) x loads
For CTV/BVOD, use the power model:
video_bitrate_kbps =
creative_video_bitrate_kbps ??
property.video_bitrate_kbps[device_type] ??
default_video_bitrate_kbps[device_type]
power_watts =
baseload_watts +
dynamic_watts_per_mbps x video_bitrate_kbps / 1000
creative_data_transfer_usage_emissions_gco2_per_imp =
creative_video_duration_seconds / 3600 x
power_watts / 1000 x
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
creative_data_transfer_embodied_emissions_gco2_per_imp =
creative_video_duration_seconds x
video_bitrate_kbps / 128 x
embodied_emissions_gco2e_per_kb
default_creative_platforms =
creative_is_3p_served ?
[generic_creative_ad_server, generic_measurement_platform] :
[]
creative_platforms = creative_ad_platforms ?? default_creative_platforms
creative_platform_emissions_gco2_per_imp = 0
for platform in [creative_platforms, ad_format.ad_platforms]:
creative_platform_emissions_gco2_per_imp += platform.emissions_per_creative_request_per_geo_gco2_per_imp
audio_device_coverage =
device_type == 'smart-speaker' ? 1 : 0
audio_device_coverage_seconds =
audio_device_coverage x
audio_duration
device_pixels = default_device_width[device_type] x default_device_height[device_type]
rendered_width = ad_format.rendered_width_pixels ?? default_device_width[device_type]
rendered_height = ad_format.rendered_height_pixels ?? default_device_height[device_type]
visual_device_coverage =
is_primary_experience ?
1 :
MIN(1, rendered_width x rendered_height / device_pixels)
time_in_view =
video_duration ??
creative_time_in_view_seconds ??
default_time_in_view_seconds
device_coverage_seconds =
audio_duration ?
audio_device_coverage_seconds :
visual_device_coverage x time_in_view
creative_consumer_device_usage_emissions_gco2_per_imp =
device_coverage_seconds / 3600 x
default_device_watts[device_type] / 1000 x
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
creative_consumer_device_embodied_emissions_gco2_per_imp =
device_coverage_seconds x
default_device_embodied_emissions_per_second[device_type]
media_data_transfer_emissions_gco2_per_imp =
media_data_transfer_usage_emissions_gco2_per_imp +
media_data_transfer_embodied_emissions_gco2_per_imp
Determing the session seconds for a single impressions
session_seconds_per_imp =
property.average_seconds_per_session_excluding_ads x
property.ad_funded_percentage/100 /
property.average_imps_per_session
For all channels other than CTV/BVOD, use the conventional model:
media_data_transfer_kb_per_imp =
property.average_data_kb_per_session_excluding_ads x
property.ad_funded_percentage/100 /
property.average_imps_per_session
media_data_transfer_usage_emissions_gco2_per_imp =
media_data_transfer_kb_per_imp x
usage_kwh_per_gb / 1000000 x
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
media_data_transfer_embodied_emissions_gco2_per_imp =
media_data_transfer_kb_per_imp x
embodied_emissions_gco2e_per_kb
For CTV/BVOD, use the power model:
video_bitrate_kbps = property.video_bitrate_kbps[device_type] ?? default_video_bitrate_kbps[device_type]
power_watts =
baseload_watts +
dynamic_watts_per_mbps x video_bitrate_kbps / 1000
media_data_transfer_usage_emissions_gco2_per_imp =
session_seconds_per_imp / 3600 x
power_watts / 1000 x
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
media_data_transfer_embodied_emissions_gco2_per_imp =
session_seconds_per_imp x
video_bitrate_kbps / 128 x
embodied_emissions_gco2e_per_kb
media_consumer_device_usage_emissions_gco2_per_imp =
session_seconds_per_imp / 3600 x
default_device_watts[device_type] / 1000 x
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
media_consumer_device_embodied_emissions_gco2_per_imp =
session_seconds_per_imp x
default_device_embodied_emissions_per_second[device_type]
media_corporate_emissions_gco2_per_imp =
property.allocated_adjusted_corporate_emissions_kg x 1000 /
property.total_sessions /
property.average_imps_per_session
get_platform_emissions(ad_platform):
direct_emissions = emissions_per_bid_request_per_geo_gco2_per_imp
rtdp_emissions = 0
for rtdp in ad_platform.real_time_data_providers:
rtdp_emissions += emissions_per_rtdp_request_per_geo_gco2_per_imp
bidder_emissions = 0
for bidder in ad_platform.bidders:
bidder_emissions += get_platform_emissions(bidder) x
ad_platform.distribution_rate_by_bidder_by_country[country, bidder] ?? 1
return direct_emissions + rtdp_emissions + bidder_emissions
ad_selection_platform_emissions_gco2_per_imp = 0
data_transfer_bytes = 0
for platform in placement.ad_platforms:
ad_selection_platform_emissions_gco2_per_imp += get_platform_emissions(platform)
platform_bytes =
platform.average_bid_request_size ??
default_consumer_device_request_size_bytes[channel]
data_transfer_bytes += default_consumer_device_request_size_bytes[channel]
if platform.sends_client_side_requests:
for bidder in platform.bidders:
bidder_bytes =
bidder.average_bid_request_size ??
default_consumer_device_request_size_bytes[channel]
data_transfer_bytes +=
bidder_bytes x
platform.distribution_rate_by_bidder_by_country[country, bidder] ?? 1
ad_selection_data_transfer_usage_emissions_gco2_per_imp =
data_transfer_bytes / 1000 x
usage_kwh_per_gb / 1000000 x
lookup_carbon_intensity_gco2e_per_kwh(country, region, utc_datetime)
ad_selection_data_transfer_embodied_emissions_gco2_per_imp =
data_transfer_bytes / 1000 x
embodied_emissions_gco2e_per_kb
ad_selection_data_transfer_emissions_gco2_per_imp =
ad_selection_data_transfer_usage_emissions_gco2_per_imp +
ad_selection_data_transfer_embodied_emissions_gco2_per_imp
grid_mix_model_quality = lookup_carbon_intensity_quality(country, region)
organization_model_quality = property.organization_model_quality
property_model_quality = property.model_quality
total_platforms = 0
modeled_platforms = 0
for platform in placement.ad_platforms:
total_platforms++
if platform.model_quality > 1
modeled_platforms++
# Model one level of downstream platforms
for bidder in ad_platform.bidders:
total_platforms++
if bidder.model_quality > 1
modeled_platforms++
ad_platform_modeled_ratio = modeled_platforms / total_platforms