An SXG is a delivery mechanism that makes it possible to authenticate the origin of a resource independently of how it was delivered.
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.
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.
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="https://test.web.app/ViFgi0WfQ-NotPJf8PBo2T5dEuZ13NdZefPybXq_HhE"; date=1597680503;expires=1598285303;integrity="digest/mi-sha256-03";sig=<em>MEUCIQD5VqojZ1ujXXQaBt1CPKgJxuJTvFlIGLgkyNkC6d7LdAIgQUQ8lC4eaoxBjcVNKLrbS9kRMoCHKG67MweqNXy6wJg=</em>; validity-url="https://example.org/webpkg/validity" header integrity: sha256-Gl9bFHnNvHppKsv+bFEZwlYbbJ4vyf4MnaMMvTitTGQ=</p> <p>The exchange has a valid signature. payload [1256 bytes]:</p> <pre class="prettyprint"><code><title>SXG example</title> <meta charset="utf-8"> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; } </style> </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.
The Preview tab provides more information about the contents of a SXG.
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.
sxg-rs/fastly_compute
runs on Fastly Compute@Edge.Automatic Signed Exchanges is a Cloudflare feature that automatically acquires certificates and generates Signed Exchanges.
NGINX SXG module generates and serves SXGs for sites that use nginx. Setup instructions can be found here.
Envoy SXG Filter generates and serves SXGs for sites that use Envoy.
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 thecloudflare_worker
andfastly_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.