A font drawn for international use carries Latin, Latin Extended, Cyrillic, Greek and often Vietnamese. If your site is in English, four of those five are downloaded by every visitor and drawn by none of them. Subsetting is removing the characters you will never set, and on a typical family it halves the file.
It is the largest single saving available on a web font, larger than switching from WOFF to WOFF2, and it is the one most sites never do.
What subsetting actually removes
A font file is a set of tables: the outlines, the widths, the character-to-glyph map, the kerning, the names. Subsetting rebuilds all of them around a smaller list of characters. The glyphs you dropped go, their entries in the character map go, and every kerning pair that mentioned them goes with them.
What is left is a real font, not a damaged one. It renders identically for every character it still contains. Ask it for a character it no longer has and the browser falls back to another typeface, exactly as it would for a font that never had it.
How much it saves
It depends entirely on how much the font was carrying. A face that only ever covered Latin subsets to within a few per cent of itself — there is nothing to remove. A face covering four alphabets can lose three quarters of its weight. Every font page on this site shows the exact figures for that family, because both files are built and measured rather than estimated.
| Family | Variable download | Static download |
|---|---|---|
| Inter | 957 KB2 files | 9.1 MB54 files |
| Roboto | 597 KB2 files | 5.2 MB54 files |
| Arimo | 638 KB2 files | 1.5 MB8 files |
| IBM Plex Mono | None published | 835 KB14 files |
The three ways to do it
Take a subset that is already built
Every font page here offers two WOFF2 downloads: the complete font, and the same font cut to Latin and Latin Extended with every weight still in it. That covers English, Turkish and the western European languages, and it is one click. See Inter or Roboto.
Let a CDN do it per request
Google Fonts serves a different subset depending on the browser asking, using the unicode-range descriptor to split a family into a dozen files and let the browser fetch only the ones it needs for the text on the page. It is the most efficient approach and it costs you a request to a third party on every page load, which is a privacy decision as much as a performance one.
Cut it yourself
Tools like fonttools, glyphhanger and harfbuzz will build a subset from an explicit list of characters. This is the right answer when you know exactly what a page contains — a logo, a heading set once, a interface with a fixed vocabulary — because you can go far below an alphabet. A five-character wordmark does not need a font, it needs five glyphs.
The mistake to avoid
Do not subset to the characters currently on the page. Content changes, a user types their own name, a product gets an accent in it, and the missing glyph shows up months later in a font that has silently fallen back. Subset to an alphabet rather than to a string, unless the text genuinely cannot change.
And check the punctuation. Curly quotes, the en and em dash, the ellipsis and the currency symbol you use are all outside the basic Latin block, and a subset built from A-Za-z0-9 will drop every one of them. The Latin cut offered here keeps the general punctuation and currency ranges for exactly this reason.
What about variable fonts?
A variable font can be subsetted like any other, and the weights survive — the character set and the axes are independent. The Latin downloads here keep every weight the family has. What some tools also offer is instancing: pinning the axes to one value and throwing the rest away, which turns a variable font into a single static weight and makes it very much smaller. That is a different operation with a different trade-off, and it is worth knowing they are not the same thing. See the variable font post.