Authenticating Resources Independently of Delivery

Signed exchanges (SXG) are a delivery mechanism that authenticates the origin of a resource regardless of how it was delivered. By decoupling content from its transport path, SXG enables a variety of use cases, including privacy-preserving cross-origin prefetch, offline internet experiences, and serving from third-party caches. In practice, implementing SXG can reduce Largest Contentful Paint (LCP) on cross-origin navigations, with Chromium-based browsers (Chrome 73 and later, Edge 79, and Opera 64) providing support.

The Mechanics of an HTTP Exchange

At its core, an SXG is a cryptographically signed request/response pair, referred to as an "HTTP exchange." The origin signs both the request and response in a way that lets the browser verify the content's integrity and origin independent of the channel through which it was distributed. This means the address bar reflects the origin's URL rather than the URL of the server that actually delivered the content.

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

Historically, maintaining attribution while using a third-party distributor required sharing SSL certificates. That approach carries significant security drawbacks and does little to make content portable. SXG removes that constraint by making the certificate unnecessary for delivery.

The SXG File Format

An SXG is a binary-encoded file with two key components: the HTTP exchange itself and a signature that covers it. The exchange consists of the request URL, content negotiation information, and the HTTP response. Each SXG signature includes an expires parameter, and an SXG can be valid for up to 7 days.

For sites that tailor HTML per user, SXG supports server-side personalization via a Vary: Cookie header. An SXG bearing this header is only shown to users who don't already have cookies for the signed request URL, allowing logged-in experiences to remain unaffected.

Relationship to Web Packaging

SXG is part of the broader Web Packaging specification family, which also includes Web Bundles. Web Bundles package a collection of HTTP resources and the metadata needed to interpret them. The two technologies are independent, though: Web Bundles can contain signed or unsigned exchanges, and both support sharing sites in full for offline use. They also share a common goal-toward truly portable, verifiable content.

Performance Gains and Case Studies

SXG is often implemented to improve page-load performance, most notably by enabling cross-origin prefetch. As an early adopter, Google Search crawls and caches SXGs when available, and will prefetch an SXG for a page it anticipates the user will visit-such as the first search result. SXG works best when layered on other optimizations like CDN use and reduced render-blocking subresources.

Past experiments show an average 300ms to 400ms reduction in LCP from SXG-enabled prefetches. Real-world campaigns reinforce this: RebelMouse customers saw a 41% LCP improvement at Narcity, a 27% increase in sessions per user at Paper Magazine, and a 21% decrease in page-load time at MLT Blog. Cloudflare testing found SXG improved TTFB for 98% of sites tested, and LCP for 85% of them, with a median improvement greater than 20% among SXG-eligible loads. These gains often translate into better business metrics through an improved first impression.

Note that the SXG representation of a page is indexed and ranked exactly as its non-SXG counterpart-by definition, SXG is a delivery mechanism, not a content transformation. AMP content can also be served via SXG, enabling prefetch and canonical-URL display rather than AMP URLs; dedicated tooling exists for generating these DXGs.

Inspecting SXGs in Chrome DevTools

To see an SXG in action, open a Chromium browser, launch DevTools, and go to the Network panel. Visiting a test search page will list signed exchanges; these are identifiable as signed-exchange in the Type column.

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

Selecting a resource and opening the Preview tab details the SXG's inner contents.

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

Choosing an SXG Toolchain

Implementing SXG boils down to two tasks: generating the SXG for a given URL, and serving it to requesters—typically crawlers. Before any of that, however, you need a certificate capable of signing SXGs. Some tools acquire these automatically. The list of certificate authorities that can issue these is maintained publicly. For automated acquisition, any ACME client can obtain certificates from the Google certificate authority; Web Packager Server has a built-in ACME client, and sxg-rs will soon add support as well.

Platform-specific Tools

If your site already runs on a supported platform, one of the following integrations is likely the fastest path to SXG:

General-Purpose Tools

For more control, or if you are not on the above platforms, Google offers several standalone servers and utilities:

  • The sxg-rs http_server acts as a reverse proxy. It signs responses from your backend and returns an SXG to SXG-aware crawlers. Its README covers the installation process.

  • Web Packager Server (webpkgserver) is a Go-based alternative to the http_server. See the setup guide.

  • The Web Packager CLI generates a single SXG file for a given URL:

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

After generating the file, upload it and serve it with the application/signed-exchange;v=b3 MIME type. The SXG certificate must be served separately with application/cert-chain+cbor.

SXG Libraries for Custom Builds

If you prefer to build your own generator, three libraries are available at different levels of abstraction:

  • sxg_rs is the most featureful option, a Rust library that powers the Cloudflare and Fastly tools.

  • libsxg is a minimal C library, underpinning the NGINX module and Envoy filter.

  • go/signed-exchange is the Go reference implementation from the webpackage spec. It is the basis for the gen-signedexchange CLI tool and the more full-featured Web Packager suite.

Serving and Caching SXGs

Content Negotiation

To avoid serving SXGs to browsers that don't support them, only respond with an SXG when the Accept header shows a q-value for application/signed-exchange that is greater than or equal to the q-value for text/html. This means crawlers get SXGs, but standard browsers see normal HTML. Most of the tools above handle this automatically. For manual setup, match the Accept header against the following regular expression:

http Accept: /(^|,)\s\*application\/signed-exchange\s\*;\s\*v=[[:alnum:]\_-]+\s\*(,|$)/

The content negotiation recommendation includes working examples for Apache and nginx.

Invalidating the Cache

By default, SXGs are removed from the Google SXG Cache when their Cache-Control: max-age expires. Site owners who need earlier removal can use the update cache API reference.

Linking from Other Pages

Any site can prefetch or serve SXGs of pages it links to, provided those SXGs exist. The standard way is with an anchor link and a prefetch hint pointing directly at the .sxg file:

html <a href="https://example.com/article.html.sxg"> <link rel="prefetch" as="document" href="https://example.com/article.html.sxg">

A practical example shows how to distribute SXGs with nginx.

Why Use SXG?

SXG is one approach to cross-origin prefetching, and the choice among approaches involves trade-offs between different performance goals. SXG's current strengths are in reducing server load and improving observed page speed:

  • Fewer wasted requests. Since SXGs are cached and can be served until they expire, cached copies handle many prefetches without contacting your origin. Additionally, because SXGs work with or without cookies on your site, a prefetched page is less likely to need a fresh fetch after the user navigates.
  • Faster page loads for real users. SXGs can be displayed to users even when they have cookies set for your site. Subresources (JavaScript, CSS, fonts, images) are prefetched too when they are declared in a Link header. Google is also expected to expand SXG prefetching to more search result types over time.

The expected result is that prefetching surfaces return content more quickly while your origin handles fewer requests overall.