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.
Which ranges to keep for a European site
The default answer for a site in a western European language is narrower than most people think, and the omissions are what bite later. A safe minimum is basic Latin, the Latin-1 supplement and Latin Extended-A — that last one is where the Turkish, Polish, Czech and Hungarian letters live.
- Basic Latin: the alphabet, digits and the common punctuation.
- Latin-1 supplement: accented letters for French, Spanish, German and the Nordic languages, plus the degree and currency signs.
- Latin Extended-A: Turkish, Polish, Czech, Hungarian, Romanian, Baltic. This is the one people cut by accident.
- General punctuation: the proper quotation marks, the en and em dashes, the ellipsis. Cutting these is why a site sometimes shows a straight apostrophe in a different face.
Splitting by range instead of cutting
There is a middle path between the whole font and a subset: several files, each with a unicode-range in its @font-face. The browser reads the ranges, works out which files the page actually needs, and downloads only those. A reader of an English page gets the Latin slice; the one page with a Greek quotation on it fetches the Greek slice as well.
This is what the big font services do behind the scenes, and it is the reason their CSS looks like twenty @font-face rules for one family. You can do the same with a subsetting tool and a handful of files, and it is worth it for a font carrying several alphabets.
Check what you cut
- Compare glyph counts before and after. A drop from 900 to 260 is a Latin subset; a drop to 90 means something went wrong.
- Open the subset in a specimen and paste the hardest string your site contains — a name with accents, a price, a quotation with proper marks.
- Check a page in every language the site ships in, not just the default one.
- Keep the original file. A subset is a build artefact, and you will want to rebuild it the first time the content changes.
If all of that sounds like more work than it is worth for one site, the Latin-only web font on every font page here is exactly this job already done: the same font with the character set cut to Latin and Latin Extended, every weight intact.
