diff --git a/defaults/docs-defaults.yaml b/defaults/docs-defaults.yaml index dde741cb..58db1214 100644 --- a/defaults/docs-defaults.yaml +++ b/defaults/docs-defaults.yaml @@ -269,6 +269,9 @@ defaults: social: 0.049000000 streaming-video: 0.049000000 web: 0.049000000 + default_server_side_request_size_bytes: 1500 + default_server_to_server_embodied_emissions_gco2e_per_kb: 0.000000007 + default_server_to_server_kwh_per_gb: 0.000200000 default_time_in_view_seconds: 6 default_usage_kwh_per_gb: scope3: diff --git a/docs/calculations.mdx b/docs/calculations.mdx index d6456d4d..ba8c8fd4 100644 --- a/docs/calculations.mdx +++ b/docs/calculations.mdx @@ -541,40 +541,76 @@ get_platform_emissions(ad_platform): 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: +get_platform_client_side_data_transfer(platform, is_client_side): + if !is_client_side + return 0 + bytes_sent = 0 for bidder in platform.bidders: bidder_bytes = bidder.average_bid_request_size ?? default_consumer_device_request_size_bytes[channel] - data_transfer_bytes += + bytes_sent += bidder_bytes x platform.distribution_rate_by_bidder_by_country[country, bidder] ?? 1 + return bytes_sent + +get_platform_server_side_data_transfer(platform, is_client_side): + bytes_sent = 0 + for bidder in platform.bidders: + bytes_sent += get_platform_server_side_data_transfer(bidder, false) + if is_client_side: + continue + bidder_bytes = + bidder.average_bid_request_size ?? + default_server_side_request_size_bytes + bytes_sent += + bidder_bytes x + platform.distribution_rate_by_bidder_by_country[country, bidder] ?? 1 + return bytes_sent + +ad_selection_platform_emissions_gco2_per_imp = 0 +client_side_data_transfer_bytes = 0 +server_side_data_transfer_bytes = 0 + +for platform in placement.ad_platforms: + ad_selection_platform_emissions_gco2_per_imp += get_platform_emissions(platform) + client_side_data_transfer_bytes += + platform.average_bid_request_size ?? + default_consumer_device_request_size_bytes[channel] + client_side_data_transfer_bytes += default_consumer_device_request_size_bytes[channel] + client_side_data_transfer_bytes += + get_platform_client_side_data_transfer(platform, platform.sends_client_side_requests) + server_side_data_transfer_bytes += + get_platform_server_side_data_transfer(platform, platform.sends_client_side_requests) + ``` ### Ad Selection - Data Transfer ``` -ad_selection_data_transfer_usage_emissions_gco2_per_imp = - data_transfer_bytes / 1000 x - usage_kwh_per_gb / 1000000 x +ad_selection_client_side_data_transfer_usage_emissions_gco2_per_imp = + client_side_data_transfer_bytes / 1024 x + usage_kwh_per_gb / 1024 / 1024 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 +ad_selection_client_side_data_transfer_embodied_emissions_gco2_per_imp = + client_side_data_transfer_bytes / 1024 x embodied_emissions_gco2e_per_kb +ad_selection_server_side_data_transfer_usage_emissions_gco2_per_imp = + server_side_data_transfer_bytes / 1024 x + default_server_to_server_kwh_per_gb / 1024 / 1024 x + lookup_carbon_intensity_gco2e_by_continent(country, region, utc_datetime) + +ad_selection_server_side_data_transfer_embodied_emissions_gco2_per_imp = + server_side_data_transfer_bytes / 1024 x + default_server_to_server_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 + ad_selection_server_side_data_transfer_usage_emissions_gco2_per_imp + + ad_selection_server_side_data_transfer_embodied_emissions_gco2_per_imp + + ad_selection_client_side_data_transfer_usage_emissions_gco2_per_imp + + ad_selection_client_side_data_transfer_embodied_emissions_gco2_per_imp ``` ### Model Quality diff --git a/docs/data_transfer.mdx b/docs/data_transfer.mdx index b816c9e9..62f2fd87 100644 --- a/docs/data_transfer.mdx +++ b/docs/data_transfer.mdx @@ -79,3 +79,10 @@ The [SRI methodology](https://www.sri-france.org/wp-content/uploads/2023/06/SRI_ ## Handling unknown networks The SRI methodology suggests a ratio of 90% fixed to 10% mobile. However, this ratio is not representative globally. The ITU publishes [research](https://datahub.itu.int) on fixed and mobile traffic by country. This indicates that for 2022 the weighted average of global traffic was 23.6% mobile. However, this research notably omits the US which is likely similar to other advanced economies in the 5% range, so we have added this to the dataset as an estimate (along with the 10% France number for SRI consistency). + +## Server-to-server data transfer +[Marion Ficher, Françoise Berthoud, Anne-Laure Ligozat, Patrick Sigonneau, Maxime Wisslé, et al.. Assessing the carbon footprint of the data transmission on a backbone network. 24th Conference on Innovation in Clouds, Internet and Networks, Mar 2021, Paris, France. hal-03196527](https://hal.science/hal-03196527) + +Per Table III, a local request (which is the likely case for RTB where the round trip time needs to be ~10ms or less), and assuming a peak day as the majority of requests will be at peak, use phase emissions are 0.433 gCO2e/GB and embodied emissions are .0143 gCO2e/GB. To reverse the use phase to kWh we remove the emissions factor used (0.108 kgCO2e/kWh) and get 0.00401 kWh/GB. + +According to the research, "All the devices of the network are built to handle a larger quantity of data, generally 50 times more. It is essential to maximize the traffic on them." This implies a utilization of around 2%. Large cloud and datacenter providers will operate at much higher utilization levels (~40%), so we need to adjust these numbers by a factor of approximately 20. diff --git a/docs/model_quality.mdx b/docs/model_quality.mdx index f2f4adf6..32337ef7 100644 --- a/docs/model_quality.mdx +++ b/docs/model_quality.mdx @@ -3,11 +3,13 @@ Given the many layers of assumptions and allocations involved in modeling the em ## Model Quality Components Each modeled request should include: + - Grid mix model quality (1-5) -- Organization model quality (1-5) +- Organization model quality (1-5) - Property model quality (1-5) - Ad stack model quality (1-5) -- Average ad platform / vendor quality (1-5) +- Average ad platform quality (1-5) +- Ad format model quality (1-5) - Input granularity score (1-5) ## Grid mix @@ -26,11 +28,11 @@ Grid intensity can fluctuate significantly on an hourly basis due to the variabl Criteria for accurate sustainability data at the organization level: -* An organization should provide a sustainability report that details its full carbon footprint, including scopes 1, 2, and all scope 3 categories. This report should clearly detail methodology for each category. +- An organization should provide a sustainability report that details its full carbon footprint, including scopes 1, 2, and all scope 3 categories. This report should clearly detail methodology for each category. -* Any adjustments to the calculations for RECs, PPAs, offsets, or carbon credits should detail exactly what was purchased, from whom, and on what timeframe. Location-based scope 2 data should always be provided. +- Any adjustments to the calculations for RECs, PPAs, offsets, or carbon credits should detail exactly what was purchased, from whom, and on what timeframe. Location-based scope 2 data should always be provided. -* A sustainability report should be published within 6 months of the end of the previous calendar year to be considered for sustainability purposes. +- A sustainability report should be published within 6 months of the end of the previous calendar year to be considered for sustainability purposes. | Report element | Model Quality | | ------------------------------- | ------------- | @@ -39,12 +41,12 @@ Criteria for accurate sustainability data at the organization level: | All scope 3 categories provided | +1 | | Lines of business broken out | +1 | -## Vendor / Ad Platform Quality +## Ad Platform -An ad platform should provide 1) requests received, 2) requests sent (traffic shaping), and 3) emissions data from datacenters or cloud providers. The vendor / ad platform score starts at 1 and increments based on the presence of various modeled components. +An ad platform should provide 1) requests received, 2) requests sent (traffic shaping), and 3) emissions data from datacenters or cloud providers. The ad platform score starts at 1 and increments based on the presence of various modeled components. -| Vendor data element | Model Quality | -| --------------------------------- | ------------- | +| Ad platform data element | Model Quality | +| -------------------------------------- | ------------- | | Server emissions and request data | +1 | | Traffic shaping data | +1 | | All data provided monthly | +1 | @@ -52,9 +54,9 @@ An ad platform should provide 1) requests received, 2) requests sent (traffic sh Example: A company provides annual server emissions, requests received, and traffic shaping data. This would be model quality 3. -The average vendor model quality is the average score of all direct vendors that the property works with. +The average ad platform model quality is the average score of all direct ad platforms that the property works with. -## Property Activity +## Property For media properties, key metrics include session time, session weight, and ad load. For OOH screens, the key metric is power draw. A measured metric is acquired on a per-property basis - for instance, using Google Analytics on a website or a power meter on a screen. An estimated or average metric uses a third-party source or historical averages to project key metrics, for instance, using screen size and type to model power usage. @@ -68,14 +70,25 @@ For media properties, key metrics include session time, session weight, and ad l ## Ad Stack -The accuracy of the ad stack used by the publisher for the placement depends on accurate representation of all direct and indirect vendors. The ad stack score starts at 1 and increments based on modeled components. +The accuracy of the ad stack used by the publisher for the placement depends on accurate representation of all direct and indirect ad platforms. The ad stack score starts at 1 and increments based on modeled components. | Ad Stack Component | Model Quality | | ------------------------------------------- | ------------- | | Ad stack mapped via observed data | +1 | | Ads.txt validated | +1 | -| Vendors mapped to region, device, and format| +1 | -| Placements mapped to GPID and vendors | +1 | +| Ad platforms mapped to region, device, and format| +1 | +| Placements mapped to GPID and ad platform | +1 | + +## Ad Format + +The ad format model should include all of elements included upon the initial render of the ad format. Advertiser-provided assets should be identified so that they can be replaced with actual data during the measurement process. All ad platforms that are part of the rendering process should be included, especially ad servers, real-time measurement providers, and video players. + +| Ad Format data element | Model Quality | +| -------------------------------------------------------------- | ------------- | +| Technical specs provided | +1 | +| Media assets identified | +1 | +| All static assets measured and included | +1 | +| Video player is identified and has model quality of at least 3 | +1 | ## Input granularity @@ -126,6 +139,6 @@ Granularity % is the percentage of recommended input fields that are provided an | Ad format | 320x50 banner | yes | | Creative weight | (omitted) | no | -Input granularity percentage: 6/12 = 50% +Input granularity percentage: 6/12 = 50% Input granularity score: 2 diff --git a/docs/snippets/defaults_ad_platform.mdx b/docs/snippets/defaults_ad_platform.mdx index c81244a2..69ab230b 100644 --- a/docs/snippets/defaults_ad_platform.mdx +++ b/docs/snippets/defaults_ad_platform.mdx @@ -8,6 +8,8 @@ default_consumer_device_request_size_bytes: social: 1000 streaming-video: 0 +default_server_side_request_size_bytes: 1500 + default_emissions_per_creative_request_gco2_per_imp: 0.0003 default_emissions_per_bid_request_gco2_per_imp: 0.11442 default_emissions_per_rtdp_request_gco2_per_imp: 0.01 diff --git a/docs/snippets/defaults_conventional_model.mdx b/docs/snippets/defaults_conventional_model.mdx index d204ea83..f86a099e 100644 --- a/docs/snippets/defaults_conventional_model.mdx +++ b/docs/snippets/defaults_conventional_model.mdx @@ -13,4 +13,6 @@ default_network_embodied_emissions_gco2e_per_kb: sri: fixed: 0.00000443 mobile: 0.00000797 +default_server_to_server_kwh_per_gb: 0.0002 +default_server_to_server_embodied_emissions_gco2e_per_kb: 0.0000000068 ``` diff --git a/requirements.txt b/requirements.txt index 1a3c4dcd..b89e3dcf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,9 +19,9 @@ fastapi==0.110.0 ; python_version >= "3.10" \ h11==0.14.0 ; python_version >= "3.10" \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 -idna==3.6 ; python_version >= "3.10" \ - --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ - --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f +idna==3.7 ; python_version >= "3.10" \ + --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ + --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 pydantic-core==2.16.3 ; python_version >= "3.10" \ --hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \ --hash=sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed \ diff --git a/scope3_methodology/test/test_api.py b/scope3_methodology/test/test_api.py index e0b71fae..73a7b2ab 100644 --- a/scope3_methodology/test/test_api.py +++ b/scope3_methodology/test/test_api.py @@ -239,7 +239,7 @@ def test_startup(self): ) docs_defs = docs_defaults - self.assertEqual(len(docs_defs), 33) + self.assertEqual(len(docs_defs), 36) def test_get_all_con_networking_connection_device_fixed_defaults(self): """Test get_all_networking_connection_device_defaults returns expected output"""