Why We Self-Host Fonts (and You Probably Should Too)
Published 11 February 2026 · Engineering Notes · ~5 min read
A client asked us last quarter why their site briefly displayed fallback fonts for the first second of every page load. We checked the network tab. There it was: fonts.googleapis.com taking 380 ms on a 4G connection, then fonts.gstatic.com taking another 290 ms before the first font byte arrived. Two thirds of a second of every visit, the user saw a flash of unstyled text on a corporate marketing site that prides itself on "professional polish."
We moved their fonts on-host. The flash disappeared. The Lighthouse score went up. And along the way, we eliminated a third-party network call we had been doing on autopilot.
Here is the case for self-hosting fonts on any production site you own. It is short and it is opinionated.
Reason 1: Privacy
Every visit to your site that loads fonts.googleapis.com sends Google a request containing the visitor's IP address, their User-Agent string, and the Referer header (which is to say, the page they were looking at on your site). Google does not need this data, but they get it anyway, and your visitor never consented to it.
In jurisdictions with active data-protection enforcement, this is now a problem. The Bavarian regional court ruled in January 2022 that embedding Google Fonts via the CDN was unlawful processing of personal data without legal basis under the GDPR. The fine in that case was modest — €100 — but the precedent has produced a steady stream of warning letters across Europe. India's DPDP Act 2023 takes a similar shape: any automatic transmission of identifiers to a third party for a purpose outside the user's expectation requires consent.
Self-hosting eliminates the entire question. The fonts ship with your site. No third party is involved.
Reason 2: Performance
A self-hosted font on the same origin gets:
- One DNS lookup, not three. The browser already knows your origin's IP. Google Fonts requires resolving
fonts.googleapis.comandfonts.gstatic.com, each of which is a separate round trip if not pre-resolved. - One TCP/TLS handshake, not two. Same logic. Three origins means three handshakes unless connection coalescing helps, which on shared CDN IPs is unreliable.
- HTTP/2 priority you control. When the font is on your origin, it competes for bandwidth with your own resources, which means your
<link rel="preload">actually does what it says. Cross-origin priority is at the mercy of the third party.
In our measurements on a 4G mobile profile from Mumbai, replacing fonts.googleapis.com with same-origin woff2 shaved 280–420 ms off Largest Contentful Paint. That is not a tuning gain. That is the difference between "fast" and "fine."
Reason 3: A failure mode you have not considered
This is the one that bit our client. In November 2024, a regional ISP began intermittently throttling fonts.gstatic.com because of a misconfigured shaping rule. The font request did not fail — it just took 4–9 seconds to complete. Browsers honour the FOIT (Flash of Invisible Text) timeout, which on Chrome is 3 seconds, after which they swap in fallback fonts. So users in that ISP's region saw the corporate font for half a second, then a swap to Arial, then a swap back to the corporate font two seconds later when the request finally completed.
It looked broken. It was broken, in user-experience terms. And the cause was an ISP we had no relationship with, throttling a CDN we had no control over.
When the fonts ship from your origin, this entire failure mode disappears. If your origin is up, the fonts are up. If your origin is down, the user has bigger problems than fonts.
How to actually do it
It is mechanically simple. We give clients a 30-line procedure:
1. Decide the families and weights you actually use. Most sites need 3–5 weights of one body face and 2–3 weights of one display face. That is it. 2. Download from the Google Fonts API (or fonts.bunny.net for a privacy-respecting mirror) as woff2. 3. Place under assets/fonts/. Reference with @font-face declarations using font-display: swap. 4. Add <link rel="preload" as="font" type="font/woff2" crossorigin> for the 1–2 weights actually used above the fold. 5. Update your CSP to drop fonts.googleapis.com and fonts.gstatic.com from the font-src and style-src allowlists. This is the moment of truth — if anything still requests them, you will see a CSP violation, which is exactly what you want.
The total weight added to your origin is 50–150 KB depending on family choice. The total weight removed from third-party calls is the same. Net byte cost: zero.
When not to bother
If you serve a developer-tooling site to engineers in offices on enterprise fibre, the gains are smaller and you may have legitimate reasons to use a CDN. For everyone else — corporate marketing sites, e-commerce, B2B SI sites like ours — self-hosting fonts is a net win on privacy, on performance, and on the failure-mode robustness of the site you ship.
We did this on our own site as part of the v7.1 hardening. The Lighthouse Performance score went from 92 to 96. The number of third-party origins our site contacts went from three to zero.
— SRI INFOIT, Visakhapatnam · Web Engineering practice