Self-Hosted Fonts vs Google Fonts for Static Sites

For a decade, linking Google Fonts was the default way to use a web font, and the argument for it was caching: so many sites used Roboto or Open Sans that a reader probably had the font already. That argument ended when browsers partitioned their caches by site — Chrome in version 86, Safari earlier, Firefox in 2021. A font downloaded for one site is now downloaded again for the next. What remains is a trade-off between Google's convenience and automatic subsetting, and self-hosting's shorter critical path and privacy.

This comparison runs the same static site — a 400-page Astro marketing and docs site using Inter (variable, two styles) and JetBrains Mono — with fonts from Google Fonts and with self-hosted fonts, and measures what readers experience on slow and fast connections, plus layout shift, privacy and maintenance. It belongs to Font Loading Strategies for Static Sites.

Method

  • Google Fonts: the embed code from fonts.google.com — preconnect to both fonts.googleapis.com and fonts.gstatic.com, then the stylesheet link with display=swap.
  • Self-hosted: the same font files downloaded with google-webfonts-helper, Latin and Latin-Extended subsets, served from the site's own domain with font-display: swap, a preload for the regular body weight, and a metric-matched fallback.
  • Measurement: WebPageTest, Moto G Power on Slow 4G and a desktop on Cable, first view, nine runs each; field data from web-vitals RUM split by variant over two weeks (50/50 by cookie).

The Critical Path

Request sequence for Google Fonts compared with self-hosted fonts Four actors, the browser, the site's host, fonts.googleapis.com and fonts.gstatic.com. With Google Fonts, the browser fetches the HTML from the site, then the font CSS from googleapis on a new connection, then the font file from gstatic on another new connection. With self-hosting and a preload, the browser fetches the HTML and immediately requests the font file from the same host on the existing connection. How each setup reaches the font file Browser Site host googleapis.com gstatic.com GET HTML new connection, GET font CSS new connection, GET woff2 self-hosted: preload woff2, same connection
Self-hosting removes two DNS lookups, two TLS handshakes and one round trip for the CSS from the path to the font.

With Google Fonts, the font file is three steps from the HTML: a connection to fonts.googleapis.com and its CSS, then a connection to fonts.gstatic.com and the file. preconnect overlaps the connection setup but not the CSS round trip. Self-hosted with a preload, the font request starts as soon as the browser parses the <head>, on the connection it already has.

Results: Slow Mobile

Measure (Slow 4G, median of 9)Google FontsSelf-hostedDifference
Body font request starts1,020 ms210 ms−810 ms
Body text in web font1,890 ms1,510 ms−380 ms
LCP2,140 ms1,830 ms−310 ms
Font bytes98 KB92 KB−6 KB
Connections opened31−2

Results: Fast Desktop

Measure (Cable, median of 9)Google FontsSelf-hostedDifference
Body text in web font420 ms350 ms−70 ms
LCP610 ms560 ms−50 ms

On a fast connection the extra round trips cost little. On a slow one, connection setup dominates, and self-hosting won clearly.

LCP for Google Fonts and self-hosted fonts on slow mobile and fast desktop Paired bars. On Slow 4G mobile, LCP was 2,140 milliseconds with Google Fonts and 1,830 self-hosted. On cable desktop, 610 and 560 milliseconds. In the field at the 75th percentile on mobile, 2,050 and 1,790 milliseconds. LCP by connection Google Fonts Self-hosted Lab, Slow 4G mobile 2140 ms 1830 ms Lab, cable desktop 610 ms 560 ms Field p75, mobile 2050 ms 1790 ms
WebPageTest medians of nine runs; field values from two weeks of RUM split 50/50 between variants.

Layout Shift

Both used font-display: swap, so both swapped fonts after first paint. The difference was the fallback. Google Fonts' CSS offers no way to declare a metric-matched fallback for its faces, so the default fallback (the browser's sans-serif) reflowed text on swap: CLS from fonts was 0.04 on article pages. Self-hosted, with size-adjust and ascent and descent overrides on a local Arial fallback, it was 0.003. A metric-matched fallback can be declared alongside Google Fonts too, by adding the fallback @font-face in your own CSS and naming it in font-family after the Google family; with that added, the Google variant's font CLS dropped to 0.005. So layout shift is not inherently better with self-hosting — it just requires your own CSS either way.

Caching

Self-hosted fonts were served with Cache-Control: public, max-age=31536000, immutable under versioned paths. Google's font files are also cached for a year, but its CSS for only a day, so returning visitors after a day repeat the CSS request (and its connection) before the browser can use the cached font file. On repeat visits after two days, self-hosted pages rendered text with the first paint; Google Fonts pages rendered it about 250 ms later on Slow 4G.

Privacy

Each Google Fonts request sends the visitor's IP address and user agent to Google. A 2022 ruling by the Munich regional court found embedding Google Fonts without consent unlawful under GDPR, which led many European organisations to self-host. Self-hosting sends nothing to third parties, removes Google's font domains from the site's Content Security Policy, and removes fonts from the cookie-consent conversation entirely.

Maintenance

TaskGoogle FontsSelf-hosted
Initial setupPaste embed codeDownload, subset, write @font-face, preload
Subsetting by scriptAutomatic, per requestManual or with a tool (glyphhanger, fonttools)
Font updatesAutomaticRe-download when needed
Multilingual sitesMany subsets served on demandGenerate and declare each subset

For this English-language site, self-hosting took about two hours to set up with a script (scripts/fonts.mjs) that downloads, subsets and writes the CSS, and has needed no maintenance since. For a site in 20 languages including CJK scripts, Google's automatic subsetting is worth more.

Self-hosted fonts and Google Fonts compared on six criteria A matrix of six criteria. On slow connections self-hosting is about 380 milliseconds faster to text. On fast connections the difference is small. Layout shift is equal when a metric-matched fallback is declared for both. Repeat visits favour self-hosting because Google's CSS expires daily. Privacy favours self-hosting. Multilingual subsetting favours Google Fonts. How the two compare Criterion Google Fonts Self-hosted Slow-connection text render +380 ms baseline Fast-connection render +70 ms baseline Layout shift with matched fallback 0.005 0.003 Repeat visit after a day CSS refetched immutable cache Visitor data to third party IP + user agent none Many scripts and languages automatic subsets manual subsets
Self-hosting wins on everything except automatic subsetting for many scripts.

Migrating an Existing Site

Moving from Google Fonts to self-hosting is low-risk and quick to verify. The steps used on this site:

  1. Record the exact families, weights, styles and subsets requested in the current Google Fonts URL.
  2. Download those files as WOFF2 — variable versions where available, which here replaced four static weights of Inter with one 46 KB Latin file.
  3. Write @font-face rules with the same font-family names, so no other CSS changes; add font-display: swap and unicode-range per subset.
  4. Add a preload for the one file used above the fold, with crossorigin.
  5. Remove the Google Fonts <link> and both preconnect hints, and remove the two Google domains from the Content Security Policy.
  6. Compare a WebPageTest filmstrip and a screenshot diff of key pages before and after.

The screenshot diff found one change: Google had served a slightly newer version of Inter with adjusted kerning on a few character pairs, so a handful of headings wrapped differently. Downloading the current version from the font's own repository instead of the helper's cached copy fixed it. The whole migration, including the comparison, took an afternoon.

Field data confirmed the lab results: over two weeks of the 50/50 split, mobile LCP at the 75th percentile was 260 ms lower for the self-hosted variant, with no difference in CLS once both had a matched fallback.

Verdict

  • Self-host for almost every static site: faster to text on slow connections, better repeat visits, no third-party data transfer, simpler CSP, and a one-time setup.
  • Use Google Fonts for prototypes, or for sites in many scripts where on-demand subsetting would be a lot of work — and even then, add a metric-matched fallback.

Pitfalls

  • Assuming shared caching still exists. It has not since cache partitioning.
  • Self-hosting without subsetting. A full multilingual font file can be several times larger than Google's subsets.
  • Preloading without crossorigin. The font downloads twice.
  • Forgetting the fallback. Both approaches need it to avoid swap-related CLS.

Conclusion

Measured on the same site, self-hosted fonts reached readers 380 ms sooner on a slow mobile connection and improved field LCP by about 260 ms, with no third-party data transfer and better repeat visits. Google Fonts' remaining advantage is automatic subsetting, which matters for sites in many scripts and very little for the rest.

FAQ

Is Google Fonts still faster because fonts are cached across sites?

No. Browsers have partitioned their HTTP caches by top-level site since about 2020, so a font downloaded on one site is not reused on another. Every site pays for its own font downloads, which removes the main historical performance argument for Google Fonts.

How much faster is self-hosting fonts?

In the measurements in this guide, self-hosting with a preload made body text render 380 milliseconds earlier on a slow mobile connection and improved LCP by 310 milliseconds, mostly by removing two extra connections and a CSS request from the critical path. On a fast connection the difference was under 100 milliseconds.

In the EU, a German court ruled in 2022 that embedding Google Fonts transmitted visitors' IP addresses to Google without a legal basis. Self-hosting avoids sending visitor data to a third party for fonts at all. Check with your own legal advice, but many European sites self-host for this reason alone.

What does Google Fonts do better than self-hosting?

It serves fonts already split into small unicode-range subsets, optimised per browser, and updated when the font is updated, all without any work. Self-hosting means doing that subsetting yourself or with a tool, and tracking font updates. For multilingual sites needing many scripts, Google's automatic subsetting is genuinely useful.

Filed underComparisons