Signed Exchanges (SXGs)

An SXG is a delivery mechanism that makes it possible to authenticate the origin of a resource independently of how it was delivered.

Katie Hempenius
Katie Hempenius
Devin Mullins
Devin Mullins

Signed exchanges (SXG) are a delivery mechanism that makes it possible to authenticate the origin of a resource independently of how it was delivered. Implementing SXG can improve Largest Contentful Paint (LCP) by enabling privacy-preserving cross-origin prefetch. Additionally, this decoupling advances a variety of use cases such as offline internet experiences and serving from third-party caches.

This article provides a comprehensive overview of SXG: how it works, use cases, and tooling.

Browser compatibility

SXG is supported by Chromium-based browsers (starting with versions: Chrome 73, Edge 79, and Opera 64).

Overview

As its primary use case, SXG uses a cache to prefetch and serve content that has been cryptographically signed by the origin. This helps speed cross origin navigations from referer sites while also ensuring that pages remain unaltered and properly attributed to their origin. Any potentially identifying information is hidden until after the user navigates to a site thereby protecting the user’s privacy. Google Search is an early adopter of SXG prefetching capabilities and for sites that receive a large portion of their traffic from Google Search, SXG can be an important tool for delivering faster page loads to users. Over time, we hope this impact will expand to additional referrers.

How it Works

A site signs a request/response pair (an "HTTP exchange") in a way that makes it possible for the browser to verify the origin and integrity of the content independently of how the content was distributed. As a result, the browser can display the URL of the origin site in the address bar, rather than the URL of the server that delivered the content.

Diagram explaining how Signed Exchanges Works. Browser communicating with the cache which communicates with the destination site

Historically, the only way for a site to use a third-party to distribute its content while maintaining attribution has been for the site to share its SSL certificates with the distributor. This has security drawbacks; moreover, it is a far stretch from making content truly portable.

The SXG format

An SXG is encapsulated in a binary-encoded file that has two primary components: an HTTP exchange and a signature that covers the exchange. The HTTP exchange consists of a request URL, content negotiation information, and an HTTP response.

Here's an example of a decoded SXG file.

format version: 1b3
request:
  method: GET
  uri: https://example.org/
  headers:
response:
  status: 200
  headers:
    Cache-Control: max-age=604800
    Digest: mi-sha256-03=kcwVP6aOwYmA/j9JbUU0GbuiZdnjaBVB/1ag6miNUMY=
    Expires: Mon, 24 Aug 2020 16:08:24 GMT
    Content-Type: text/html; charset=UTF-8
    Content-Encoding: mi-sha256-03
    Date: Mon, 17 Aug 2020 16:08:24 GMT
    Vary: Accept-Encoding
signature:
    label;cert-sha256=<em>ViFgi0WfQ+NotPJf8PBo2T5dEuZ13NdZefPybXq/HhE=</em>;
    cert-url=&quot;https://test.web.app/ViFgi0WfQ-NotPJf8PBo2T5dEuZ13NdZefPybXq_HhE&quot;;
    date=1597680503;expires=1598285303;integrity=&quot;digest/mi-sha256-03&quot;;sig=<em>MEUCIQD5VqojZ1ujXXQaBt1CPKgJxuJTvFlIGLgkyNkC6d7LdAIgQUQ8lC4eaoxBjcVNKLrbS9kRMoCHKG67MweqNXy6wJg=</em>;
    validity-url=&quot;https://example.org/webpkg/validity&quot;
header integrity: sha256-Gl9bFHnNvHppKsv+bFEZwlYbbJ4vyf4MnaMMvTitTGQ=</p>

<p>The exchange has a valid signature.
payload [1256 bytes]:</p>
<pre class="prettyprint"><code>&lt;title&gt;SXG example&lt;/title&gt;
&lt;meta charset=&#34;utf-8&#34;&gt;
&lt;meta http-equiv=&#34;Content-type&#34; content=&#34;text/html; charset=utf-8&#34;&gt;
&lt;style type=&#34;text/css&#34;&gt;
body {
    background-color: #f0f0f2;
    margin: 0;
    padding: 0;
}
&lt;/style&gt;
</code></pre>
<div>
    <h1>Hello</h1>
</div>

<p>

The expires parameter in the signature indicates a SXG's expiration date. A SXG may be valid for at most 7 days. Find more information on the signature header in the Signed HTTP Exchanges spec.

Support for server-side personalization

An SXG containing a Vary: Cookie header will be shown only to users who don't have cookies for the signed request URL. If your site presents different HTML to its logged-in users, you can use this feature to take advantage of SXGs without altering that experience. See details on server-side personalization with Dynamic SXG.

Web Packaging

SXG is part of the broader Web Packaging spec proposal family. In addition to SXGs, the other major component of the Web Packaging spec is Web Bundles ("bundled HTTP exchanges"). Web Bundles are a collection of HTTP resources and the metadata necessary to interpret the bundle.

The relationship between SXGs and Web Bundles is a common point of confusion. SXG and Web Bundles are two distinct technologies that don't depend on each other—Web Bundles can be used with both signed and unsigned exchanges. A common goal advanced by both SXGs and Web Bundles is the creation of a "web packaging" format that allows sites to be shared in their entirety for offline consumption.

Speeding up Page Loads with Signed Exchanges

Enabling Signed Exchanges can help speed up web page performance and thereby impact your site’s Core Web Vitals, in Particular Largest Contentful Paint (LCP). As an early adopter, Google Search uses SXG to provide users with a faster page load experience for pages loaded from the search results page.

Google Search crawls and caches SXGs when available and prefetches SXG that the user is likely to visit—for example, the page corresponding to the first search result.

SXG works best in tandem with other performance optimizations such as use of CDNs and reduction of render-blocking subresources. After implementing, follow these recommendations to maximize the LCP benefit from prefetching SXGs. In many cases, such optimization can result in nearly instant page loads coming from Google Search:

Impact of Signed Exchanges

From past experiments we have observed an average of 300ms to 400ms reduction in LCP from SXG-enabled prefetches. This helps sites make a better first-impression on users and often has a positive impact on business metrics.

Several global brands and sites have already benefited from Signed Exchanges. As a case study, lets look at how implementing Signed Exchanges helped RebelMouse, a prominent Content Management System (CMS), improve their customers' performance and business metrics:

  • Narcity improved LCP by 41%
  • Paper Magazine noticed a 27% increase in Sessions per user
  • MLT Blog decreased Page Load time by 21%

Cloudflare found that SXG improved TTFB for 98% of sites it tested, and improved LCP for 85% of sites, with a median improvement of over 20% in SXG-eligible page loads.

Indexing

The SXG and non-SXG representations of a page are not ranked or indexed differently by Google Search. SXG is ultimately a delivery mechanism—it does not change the underlying content.

AMP

AMP content can be delivered using SXG. SXG allows AMP content to be prefetched and displayed using its canonical URL, rather than its AMP URL.AMP has its own separate tooling for generating SXGs.Learn how to serve AMP using signed exchanges on amp.dev.

Debugging SXGs with Chrome DevTools

To see a SXG firsthand, use a Chromium browser, open DevTools, open the Network panel, and visit this example search page. Signed Exchanges can be identified by looking for signed-exchange in the Type column.

Screenshot showing a SXG request within the 'Network' panel in DevTools
The Network panel in DevTools

The Preview tab provides more information about the contents of a SXG.

Screenshot of the 'Preview' tab for a SXG
The Preview tab in DevTools

Tooling

Implementing SXGs consists of generating the SXG corresponding to a given URL and then serving that SXG to requestors (usually crawlers).

Certificates

To generate a SXG you will need a certificate that can sign SXGs, although some tools acquire these automatically. This page lists the certificate authorities that can issue this type of certificate. Certificates can be obtained automatically from the Google certificate authority using any ACME client. Web Packager Server has a built-in ACME client, and sxg-rs will soon.

Platform-specific SXG tooling

These tools support specific technology stacks. If you are already using a platform supported by one of these tools, you may find it easier to set up than a general-purpose tool.

General-purpose SXG tooling

sxg-rs HTTP server

The sxg-rs http_server acts as a reverse proxy for serving SXGs. For requests from SXG crawlers, http_server will sign the responses from the backend and respond with an SXG. For installation instructions, see the README.

Web Packager Server

The Web Packager Server, webpkgserver, is an alternative to sxg-rs http_server, written in Go. For instructions on setting up the Web Packager server, see How to set up signed exchanges using Web Packager.

Web Packager CLI

The Web Packager CLI generates a SXG corresponding to a given URL.

webpackager \
    --private\_key=private.key \
    --cert\_url=https://example.com/certificate.cbor \
    --url=https://example.com

Once the SXG file has been generated, upload it to your server and serve it with the application/signed-exchange;v=b3 MIME type. In addition, you will need to serve the SXG certificate as application/cert-chain+cbor.

SXG libraries

These libraries could be used to build your own SXG generator:

  • sxg_rs is a Rust library for generating SXGs. It is the most featureful SXG library and is used as the basis for the cloudflare_worker and fastly_compute tools.

  • libsxg is a minimal C library for generating SXGs. It is used as the basis for the NGINX SXG module and the Envoy SXG Filter.

  • go/signed-exchange is a minimal Go library provided by the webpackage specification as a reference implementation of generating SXGs. It is used as the basis for its reference CLI tool, gen-signedexchange and the more featureful Web Packager tools.

Content negotiation

Servers should serve SXG when the Accept header indicates that the q-value for application/signed-exchange is greater than or equal to the q-value for text/html. In practice, this means that an origin server will serve SXG to crawlers, but not browsers. Many of the above tools do this by default, but for other tools, the following regular expression can be used to match the Accept header of requests that should be served as SXG: http Accept: /(^|,)\s\*application\/signed-exchange\s\*;\s\*v=[[:alnum:]\_-]+\s\*(,|$)/

This recommendation includes examples for Apache and nginx.

Update cache API

The Google SXG Cache has an API that site owners can use to remove SXGs from the cache before they've expired due to Cache-Control: max-age. See the update cache API reference for details.

Linking to SXG

Any site can cache, serve, and prefetch SXGs of the pages that it links to, where available, using the and tags: html <a href="https://example.com/article.html.sxg"> <link rel="prefetch" as="document" href="https://example.com/article.html.sxg"> This article illustrates how to use nginx to distribute SXGs.

Unique Advantages

SXG is one of many possible technologies to enable cross-origin prefetching. When deciding which technology to use, you may need to trade off between optimizing different aspects. The following sections illustrate a few of the unique values that SXG provides in the space of possible solutions. These factors may change over time as the space of available solutions evolves.

Fewer requests to serve

With cross-site prefetching, your server may need to serve additional requests. This corresponds to cases where a page was prefetched, but either the user didn't visit the page, or the prefetched bytes couldn't be shown to the user. For SXG, these additional unused requests can be significantly reduced:

  • SXGs are cached and may be sent to users until they expire. Thus, many prefetches can be handled solely by the cache server.
  • SXGs can be shown to users both with and without cookies on your site. Thus, there are fewer times when the page will need to be fetched again after navigation.

Page speed improvement

You may see additional page speed improvement due to the prefetch surfaces and capabilities it currently supports:

  • SXGs can be shown to users with cookies for your site.
  • SXG also prefetches subresources for your pages, such as JavaScript, CSS, fonts, and images, when specified using a Link header.
  • In the near future, SXG prefetching from Google Search will be available on more search result types.

Conclusion

Signed Exchanges are a delivery mechanism that make it possible to verify the origin and validity of a resource independently of how the resource was delivered. As a result, SXGs can be distributed by third-parties while maintaining full publisher attribution.

Further reading