Origin trials are a way for developers to get early access to experimental web platform features. They’re carefully controlled “beta tests” run by browsers to ensure that the feature works and is worth more time on implementation and standardization. Check out Getting started with origin trials to learn more.

What’s interesting to me is seeing how sites are using origin trials across the web, with the help of the public HTTP Archive dataset. By detecting and extracting these origin trial tokens, we can decode them to understand more about: which experimental features the sites are enrolling in, when the trial expires, whether the functionality can be added by a third party, who that third party is, and whether the origin trial also extends to all subdomains of a site. There’s a lot of info packed into a token, and lots we can learn about how these origin trials are (mis)used on the web.

Which origin trials are used the most?

The first question worth answering is to find out what the most popular origin trials are. The results will be extremely volatile over time because origin trials are ephemeral by nature and heavily influenced by third party adoption. With that in mind, it’s still useful to get a baseline understanding of what origin trials are out in the wild.

At any given time you can browse the complete list of active origin trials for Chrome, Edge, and Firefox. Safari doesn’t have a program for origin trials.

So let’s see what’s being used the most as of today.

FeatureWebsites
PrivacySandboxAdsAPIs3,697,720
WebViewXRequestedWithDeprecation1,254,718
AttributionReportingCrossAppWeb1,191,638
InterestCohortAPI36,990
CoepCredentialless8,591
PendingBeaconAPI1,006
SendFullUserAgentAfterReduction577
FedCmAutoReauthn410
InstalledApp371
PermissionsPolicyUnload329
BackForwardCacheNotRestoredReasons324
Top 11 features used by mobile pages as of June 2023. (Source: HTTP Archive)

So, what do these features do? Let’s look at each of the top 11 one by one. And let’s count it down in reverse order—why not.

The eleventh most used origin trial is BackForwardCacheNotRestoredReasons, found on 324 sites. This feature lists the reasons why a user didn’t get a page served from the back/forward cache (bfcache). I’m particularly excited about this one, because the bfcache is very effective at giving users the feeling of instant navigations. But eligibility can vary by user, and it’s otherwise impossible for a site owner to understand why they’re not seeing the bfcache restores that they’d expect. Unfortunately, tokens on 302 sites are configured incorrectly (wrong origin). That plus the 6 tokens that have expired means that only 16 sites are actually able to successfully collect data from the API—yikes! It’s expiring next month, so time is running out.

The tenth most used origin trial is PermissionsPolicyUnload, found on 329 sites. This one lets site owners disallow all scripts from running unload event handlers. It’s related to the previous origin trial, because a page with an unload handler is ineligible for the bfcache. It recently expired in June, so it’s not working anymore anyway, but it had a similar configuration issue in which 304 sites had an invalid origin. So any performance A/B tests they were hoping to run should not have worked and, given that the trial is expired, it’s too late to rerun them.

Aside: Looking more closely at the previous two origin trials, it seems what happened was that many TLD variations of google.com (.ca, .cl, .co.in, .co.jp…) incorrectly reused the origin trial token that was explicitly activated for the google.com origin. Let this be a lesson: always validate your origin trial tokens!

The ninth most used origin trial feature is the InstalledApp feature, which is found on 371 sites. It allows sites to determine whether the user has installed their corresponding app, using getInstalledRelatedApps(). The trial ended in January 2020, so all of these sites can save a few bytes by removing the expired tokens from the markup.

The eighth most used origin trial is FedCmAutoReauthn, on 410 sites. This is part of the Federated Credentials Management API (think “Sign in with…”) and the experimental feature is a streamlined re-authentication UX. In all but 14 cases, sites are inheriting this origin trial via a third party accounts.google.com script.

Number seven is SendFullUserAgentAfterReduction coming in at 577 sites. This feature helps sites migrate any of their dependencies off of the full User Agent (UA) string by delaying the newer, reduced UA string format. The UA string is being discouraged for browser/feature detection in favor of the User-Agent Client Hints API.

At number six we have PendingBeaconAPI, found on 1,006 sites. Per the origin trial page, it “allows website authors to specify one or more beacons (HTTP requests) that should be sent reliably when the page is being unloaded.” Oddly, even though the trial is active until September 19 (Chrome 115), all but one site are inheriting an expired origin trial token from a third party ad.doubleclick.net script. The only other site? Also expired. Maybe that’s intentional though, as the PendingBeacon API explainer doc warns that the API is being replaced with fetchLater() after feedback.

The number five most used origin trial is CoepCredentialless, used on 8,591 sites. COEP, which stands for Cross-Origin-Embedder-Policy, enables cross-origin isolation. All but two instances are inherited from a third party itch.io script, and for the first time, 100% of the tokens pass validation checks!

Despite expiring nearly two years ago, the fourth most used origin trial is InterestCohortAPI, used on 36,990 sites. The major driver for its continued popularity seems to be a third party script from adroll.com, used by 36,607 sites, and a script by criteo.net on 321 sites. A wild airhorner.com also appears as one of the holdouts.

Ok now we’re getting into some serious levels of adoption. At number three we have AttributionReportingCrossAppWeb, on 1,191,638 sites. This is an extension of the Attribution Reporting API, which enables measurements like ad conversions in a privacy-preserving way without third-party cookies. This experiment allows attribution events on mobile web to be joinable with events in Android’s Privacy Sandbox. Only two third-party origins are responsible for its popularity: googletagmanager.com (1,184,189 sites), and googleadservices.com (9,380 sites), with some overlapping sites having both.

The second most used origin trial is WebViewXRequestedWithDeprecation, on 1,254,718 sites, which permits WebView requests to continue using the legacy X-Requested-With header while it’s being deprecated. Again, with lots of overlap, the top third-party origins to be using it are doubleclick.net (1,254,708 sites) and googlesyndication.com (1,253,735 sites).

And finally, the most used origin trial is PrivacySandboxAdsAPIs, used on 3,697,720 sites. It’s a collection of APIs to facilitate advertising: FLEDGE, Topics, Fenced Frames, and Attribution Reporting. A whopping 399,172 sites contain an expired token for this feature with the biggest offenders being criteo.com (225,711 sites), criteo.net (225,707 sites—hmm), and s.pinimg.com (171,817).

For reference, here’s the query used to generate all of these stats:

SELECT
  feature,
  COUNT(DISTINCT page) AS pages,
  COUNT(DISTINCT IF(is_expired_token, page, NULL)) AS expired,
  COUNT(DISTINCT IF(is_invalid_subdomain, page, NULL)) AS invalid_subdomain,
  COUNT(DISTINCT IF(is_invalid_third_party, page, NULL)) AS invalid_3p,
  COUNT(DISTINCT IF(source = 'meta', page, NULL)) AS meta_source,
  CAST(MAX(expiry) AS DATETIME) AS most_recent_expiry,
  APPROX_TOP_COUNT(origin, 1) AS top_origin
FROM
  `httparchive.scratchspace.origin_trials`
GROUP BY
  feature
ORDER BY
  pages DESC
Code language: SQL (Structured Query Language) (sql)

Jump to the setup section below to see how the origin_trials scratch table was created.

How many pages directly or indirectly include an origin trial?

SELECT
  COUNT(DISTINCT page) AS pages
FROM
  `httparchive.scratchspace.origin_trials`
Code language: SQL (Structured Query Language) (sql)

This is a quick and easy one to answer. 3,720,272 mobile sites include an origin trial as of June 2023. That’s about 22% of the 16,563,413 sites in the dataset.

SELECT
  COUNT(DISTINCT page) AS pages
FROM
  `httparchive.scratchspace.origin_trials`
WHERE
  NET.REG_DOMAIN(page) = NET.REG_DOMAIN(origin)
Code language: SQL (Structured Query Language) (sql)

If we only look at sites that explicitly self-register for an origin trial, we find there are 10,427 of them. Since we’re only looking at sites under the same domain as the registrant on the origin trial, this will include lots of subdomain variants and “tenant” subdomains. For example, itch.io shows up 8,589 times in this list, facebook.com 155 times, and pinterest.com 68 times.

So what features are individual sites enabling for themselves?

SELECT
  feature,
  COUNT(DISTINCT page) AS pages,
  COUNT(DISTINCT IF(is_expired_token, page, NULL)) AS expired
FROM
  `httparchive.scratchspace.origin_trials`
WHERE
  NET.REG_DOMAIN(page) = NET.REG_DOMAIN(origin)
GROUP BY
  feature
ORDER BY
  pages DESC
Code language: SQL (Structured Query Language) (sql)
FeatureWebsites
CoepCredentialless8,591
PrivacySandboxAdsAPIs368
SendFullUserAgentAfterReduction280
PrivateNetworkAccessNonSecureContextsAllowed210
UnrestrictedSharedArrayBuffer146
InstalledApp161
DisableDifferentOriginSubframeDialogSuppression116
SmsReceiver103
AllowSyncXHRInPageDismissal43
Launch Handler42
PriorityHintsAPI39
Top 11 features directly used by mobile pages as of June 2023. (Source: HTTP Archive)

As mentioned earlier, itch.io is responsible for much of the CoepCredentialless usage, so that’s really an outlier. For the rest, no more than a few hundred sites are enrolling in any given first-party origin trial.

I won’t go through each feature again, but I do want to call out that a few of them look quite old. That raises a related question: what percent of first-party sites include an expired token?

SELECT
  COUNT(DISTINCT IF(is_expired_token, page, NULL)) / COUNT(DISTINCT page) AS pct_expired
FROM
  `httparchive.scratchspace.origin_trials`
WHERE
  NET.REG_DOMAIN(page) = NET.REG_DOMAIN(origin)
Code language: SQL (Structured Query Language) (sql)

17%, or about one in five sites, sign up for an origin trial token and keep it around past its expiration.

Which third parties are injecting the most invalid tokens?

For a third party to make use of an origin trial, it needs to dynamically inject the token in a meta[http-equiv="Origin-Trial] tag. Two main things can go wrong with this:

  • The token is expired
  • The token doesn’t have the thirdParty flag set

Tokens are intentionally short-lived. When they expire, they should be removed along with any experimental functionality.

SELECT
  origin,
  COUNT(DISTINCT page) AS pages,
  CAST(APPROX_QUANTILES(expiry, 1000)[OFFSET(500)] AS DATETIME) AS median_expiry
FROM
  `httparchive.scratchspace.origin_trials`
WHERE
  is_expired_token
GROUP BY
  origin
ORDER BY
  pages DESC
Code language: SQL (Structured Query Language) (sql)
OriginWebsites
https://criteo.net:443226,027
https://criteo.com:443225,711
https://s.pinimg.com:443171,825
https://adroll.com:44336,607
https://teads.tv:4437,935
https://ladsp.com:4434,079
https://ad.doubleclick.net:4431,005
https://www.googletagmanager.com:443848
https://doubleclick.net:443681
https://googletagservices.com:443671
https://googlesyndication.com:443664
Top 11 origins injecting expired tokens as of June 2023. (Source: HTTP Archive)

We saw earlier that Criteo, an adtech company, was responsible for the expired PrivacySandboxAdsAPIs tokens. So it’s no surprise to see it topping the list here. But it is interesting to note that half of their tokens have been expired since November 2022.

s.pinimg.com is an image sharing hostname from Pinterest. Again, almost all of its expired tokens are for the PrivacySandboxAdsAPIs feature, with a median expiration date of April 2023.

We also saw adroll.com earlier as the main driver of the expired InterestCohortAPI feature.

Injecting an expired token isn’t the worst thing. Presumably, it lived long enough in production to be useful. Invalid third party tokens are something else, though.

SELECT
  origin,
  COUNT(DISTINCT page) AS pages
FROM
  `httparchive.scratchspace.origin_trials`
WHERE
  is_invalid_third_party
GROUP BY
  origin
ORDER BY
  pages DESC
Code language: SQL (Structured Query Language) (sql)
OriginWebsites
https://doubleclick.net:4431,254,708
https://googlesyndication.com:4431,253,735
https://themoneytizer.com:4435,501
https://www.google.com:443303
https://facebook.com:443203
https://airbnb.com:44387
https://m.youtube.com:44352
https://pinterest.com:44320
https://brands-id.shortlyst.com:44316
https://m.redbus.in:44315
Top 10 origins injecting invalid third party tokens as of June 2023. (Source: HTTP Archive)

These are the most prevalent third parties injecting origin trial tokens that will never work on a given site. Actually, let’s clarify one major assumption: the origin encoded in the token is assumed to be the same one injecting the token into its host page. It’s also possible that someone else (a fourth party?) is mishandling the origin’s token. For example, if I clone example.com onto my own site, all of their meta tag tokens will be invalidly served from rviscomi.dev.

Setting that aside, doubleclick.net (Google) and googlesyndication.com (also Google) are the two biggest origins that omit the thirdParty flag. In both cases, they’re missing the flag on their third party WebViewXRequestedWithDeprecation token.

Is that a big deal? I hope not. It means the X-Requested-With header would be unexpectedly stripped from WebView requests. Maybe in some cases that’s a load bearing header, but it doesn’t seem like a big deal.

I do worry about the origin trials more in my neck of the woods, like PermissionsPolicyUnload and BackForwardCacheNotRestoredReasons, which I highlighted earlier as being served by the wrong Google TLDs. At worst, someone might give up on them because they don’t seem to work or have any positive effect, all due to a misconfiguration.

Setting up the data table

Since I know I’ll be repeatedly querying the HTTP Archive dataset for the same origin trial info, the first thing I’ll do is preprocess the data and save it to a temporary table.

CREATE TEMP FUNCTION DECODE_ORIGIN_TRIAL(token STRING) RETURNS STRING DETERMINISTIC AS (
  REGEXP_EXTRACT(SAFE_CONVERT_BYTES_TO_STRING(SAFE.FROM_BASE64(token)), r'({".*)')
);

CREATE TEMP FUNCTION PARSE_ORIGIN_TRIAL(token STRING)
RETURNS STRUCT<
  token STRING,
  feature STRING,
  origin STRING,
  expiry TIMESTAMP,
  is_subdomain BOOL,
  is_third_party BOOL
> AS (
  STRUCT(
    token,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.feature') AS feature,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.origin') AS origin,
    TIMESTAMP_SECONDS(CAST(JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.expiry') AS INT64)) AS expiry,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.isSubdomain') = 'true' AS is_subdomain,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.isThirdParty') = 'true' AS is_third_party
  )
);


CREATE OR REPLACE TABLE `httparchive.scratchspace.origin_trials` AS

WITH valid_pages AS (
  SELECT
    page
  FROM
    `httparchive.all.requests`
  WHERE
    date = '2023-06-01' AND
    client = 'mobile' AND
    is_main_document AND
    NET.REG_DOMAIN(page) = NET.REG_DOMAIN(url)
),

ranks AS (
  SELECT
    rank,
    page
  FROM
    `httparchive.all.pages`
  WHERE
    date = '2023-06-01' AND
    client = 'mobile'
),

origin_trials AS (
  SELECT
    rank,
    page,
    'meta' AS source,
    PARSE_ORIGIN_TRIAL(TRIM(token)).*
  FROM
    `httparchive.all.pages`,
    UNNEST(JSON_QUERY_ARRAY(custom_metrics, '$.almanac.meta-nodes.nodes')) AS meta,
    UNNEST(SPLIT(JSON_VALUE(meta, '$.content'), ',')) AS token
  JOIN
    valid_pages
  USING
    (page)
  WHERE
    date = '2023-06-01' AND
    client = 'mobile' AND
    is_root_page AND
    LOWER(JSON_VALUE(meta, '$.http-equiv')) = 'origin-trial'
UNION ALL
  SELECT
    rank,
    page,
    'header' AS source,
    PARSE_ORIGIN_TRIAL(header.value).*
  FROM
    `httparchive.all.requests`,
    UNNEST(response_headers) AS header
  JOIN
    valid_pages
  USING
    (page)
  JOIN
    ranks
  USING
    (page)
  WHERE
    date = '2023-06-01' AND
    client = 'mobile' AND
    is_root_page AND
    is_main_document AND
    LOWER(header.name) = 'origin-trial'
)

SELECT
  *,
  feature IS NULL AS is_invalid_token,
  expiry < CURRENT_TIMESTAMP() AS is_expired_token,
  NET.REG_DOMAIN(page) != NET.REG_DOMAIN(origin) AND is_third_party IS NOT TRUE AS is_invalid_third_party,
  NET.REG_DOMAIN(page) = NET.REG_DOMAIN(origin) AND NET.HOST(page) != NET.HOST(origin) AND is_subdomain IS NOT TRUE AS is_invalid_subdomain
FROM
  origin_trials
Code language: SQL (Structured Query Language) (sql)

Warning: this query processes 1.97 TB, which costs about $10.

I’d love for more people to get comfortable writing their own queries over the HTTP Archive dataset, so let’s walk through what this query does.

Custom functions

CREATE TEMP FUNCTION DECODE_ORIGIN_TRIAL(token STRING) RETURNS STRING DETERMINISTIC AS (
  REGEXP_EXTRACT(SAFE_CONVERT_BYTES_TO_STRING(SAFE.FROM_BASE64(token)), r'({".*)')
);

CREATE TEMP FUNCTION PARSE_ORIGIN_TRIAL(token STRING)
RETURNS STRUCT<
  token STRING,
  feature STRING,
  origin STRING,
  expiry TIMESTAMP,
  is_subdomain BOOL,
  is_third_party BOOL
> AS (
  STRUCT(
    token,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.feature') AS feature,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.origin') AS origin,
    TIMESTAMP_SECONDS(CAST(JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.expiry') AS INT64)) AS expiry,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.isSubdomain') = 'true' AS is_subdomain,
    JSON_VALUE(DECODE_ORIGIN_TRIAL(token), '$.isThirdParty') = 'true' AS is_third_party
  )
);Code language: SQL (Structured Query Language) (sql)

I’m creating two BigQuery functions: DECODE_ORIGIN_TRIAL and PARSE_ORIGIN_TRIAL. These two functions were adapted from the ot-decode project by fellow Chromie Sam Dutton, which itself takes inspiration from Jack‘s origin-trials-viewer project. Why didn’t I just use a JavaScript function in BigQuery? Some of the APIs weren’t available, and since it was relatively straightforward to port over to SQL, I opted to take advantage of the performance benefits.

Destination table

CREATE OR REPLACE TABLE httparchive.scratchspace.origin_trials ASCode language: SQL (Structured Query Language) (sql)

This takes the output of the query and saves it to a table in the httparchive project. This will only work if you have write access to the project, so feel free to comment it out or replace it with a table in your own BigQuery project if you’d like. The httparchive table is still publicly queryable, so feel free to explore it.

Subqueries

WITH valid_pages AS (
  SELECT
    page
  FROM
    `httparchive.all.requests`
  WHERE
    date = '2023-06-01' AND
    client = 'mobile' AND
    is_main_document AND
    NET.REG_DOMAIN(page) = NET.REG_DOMAIN(url)
),Code language: SQL (Structured Query Language) (sql)

The WITH clause aliases the output of the following subqueries so that I can reference them later. It’s not a temp table necessarily, but it makes the query a lot more readable.

The valid_pages subquery creates a verified subset of pages that don’t have a cross-domain redirect. If foo.com redirects to bar.com, we don’t want bar’s origin trials mistakenly attributed to foo. We’ll join the following queries with this one to ensure that we’re only looking at valid pages.

ranks AS (
  SELECT
    rank,
    page
  FROM
    `httparchive.all.pages`
  WHERE
    date = '2023-06-01' AND
    client = 'mobile'
),Code language: SQL (Structured Query Language) (sql)

This next ranks subquery simply gets the rank for each page in the mobile dataset, which will be used later.

origin_trials AS (
  SELECT
    rank,
    page,
    'meta' AS source,
    PARSE_ORIGIN_TRIAL(TRIM(token)).*
  FROM
    `httparchive.all.pages`,
    UNNEST(JSON_QUERY_ARRAY(custom_metrics, '$.almanac.meta-nodes.nodes')) AS meta,
    UNNEST(SPLIT(JSON_VALUE(meta, '$.content'), ',')) AS token
  JOIN
    valid_pages
  USING
    (page)
  WHERE
    date = '2023-06-01' AND
    client = 'mobile' AND
    is_root_page AND
    LOWER(JSON_VALUE(meta, '$.http-equiv')) = 'origin-trial'Code language: SQL (Structured Query Language) (sql)

The next subquery origin_trials extracts the origin trial metadata from all of the <meta> tags on the page.

If you’re wondering why I didn’t parse the HTML response body directly in BigQuery, that approach would have only yielded the static <meta> tags. Crucially, we need to also include dynamically injected tags from JavaScript. It’s possible (necessary, even) for third party scripts to inject an origin trial token into the <head> of the main page after it’s already loaded.

This query takes advantage of the almanac.meta-nodes custom metric, which runs document.querySelectorAll('head meta') on the page and returns the attributes of each tag. So we’re able to filter the results down to only the ones with http-equiv=origin-trial (case insensitive) and extract their content attributes, which contain the origin trial token.

Also note that I’m only querying the June 2023 dataset (latest at this time of writing) with is_root_page set, which limits the dataset to only the home pages. We could remove this and include secondary pages, for example the article page on a news website, but I don’t suspect the overall results would be much different. Maybe that’s something you can check, if you’re up for it đŸ¤ 

The output of this query is the rank of the page, the URL of the page itself, the source of the token (which is meta in this case), and the parsed origin trial data from the custom function above.

UNION ALL
  SELECT
    rank,
    page,
    'header' AS source,
    PARSE_ORIGIN_TRIAL(header.value).*
  FROM
    `httparchive.all.requests`,
    UNNEST(response_headers) AS header
  JOIN
    valid_pages
  USING
    (page)
  JOIN
    ranks
  USING
    (page)
  WHERE
    date = '2023-06-01' AND
    client = 'mobile' AND
    is_root_page AND
    is_main_document AND
    LOWER(header.name) = 'origin-trial'
)Code language: SQL (Structured Query Language) (sql)

The origin_trials subquery continues with a UNION ALL clause to effectively mash together the results of the previous SELECT statement with this one.

The key difference here is that I’m looking at the requests table so that I can extract any Origin-Trial HTTP headers from the document response.

Amazingly, even though this table is 2.4 PB (yes, petabytes) with over 60 billion rows, this part of the query only processes about 12 GB of data. That’s thanks to the built-in partitioning and clustering, and the fact that the headers are directly accessible under the response_headers field rather than having to be parsed out of a massive JSON blob with other request metadata.

Also note that this is where the ranks data comes into play, because the requests table doesn’t annotate each page with its rank. Maybe it should!

There’s one thing missing from this query worth mentioning, and that is origin trial tokens set in HTTP headers outside of the main page. For example, ServiceWorkerBypassFetchHandlerForMainResource requires the token to be set on the response headers of the service worker itself. A quick check of the dataset found no instances of this particular origin trial, but it’s definitely possible that I’m overlooking some other valid tokens. For the sake of simplicity, this post only looks at origin trials set on the main page via first party headers or meta tags.

Validation

SELECT
  *,
  feature IS NULL AS is_invalid_token,
  expiry < CURRENT_TIMESTAMP() AS is_expired_token,
  NET.REG_DOMAIN(page) != NET.REG_DOMAIN(origin) AND is_third_party IS NOT TRUE AS is_invalid_third_party,
  NET.REG_DOMAIN(page) = NET.REG_DOMAIN(origin) AND NET.HOST(page) != NET.HOST(origin) AND is_subdomain IS NOT TRUE AS is_invalid_subdomain
FROM
  origin_trialsCode language: SQL (Structured Query Language) (sql)

The rest of the query is where it all comes together. This is what determines what actually gets written to the output table.

I’m piping everything out of the origin_trials pseudo-table and adding a few validation flags:

  • If the feature field is null, there must have been a decoding/parsing error, so mark the token as invalid.
  • If the token’s expiry field is in the past, mark it as expired.
  • If the origin of the token doesn’t match up with the origin of the page, and there is no thirdParty flag set, mark it as invalid.
  • If the domain of the token does match up with the domain of the page, but the hosts don’t match (eg foo.example.com and bar.example.com), and there is no subdomain flag set, mark it as invalid.

The output table contains 20,000,950 rows and is 7.22 GB. So it’s definitely affordable for anyone to query and stay well under the 1 TB/month free tier on GCP. (Even still, always set up cost controls!)

The table is publicly accessible at httparchive.scratchspace.origin_trials. Feel free to run your own queries to explore the data, and share what you find with me on Twitter or down in the comments.

Be aware that this table—and every other table in the scratchspace dataset—is provided with no guarantees of uptime/correctness/maintenance. So it won’t be updated regularly with the latest month’s data, it may contain inaccurate or missing data, and it might even be deleted without notice.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *