How big should a GLB file be for a website?
Most answers to this stop at "it depends" without saying what it depends on. Here are four models running live in a browser, measured, and the thing that actually predicts their size.
Aim for under 2 MB for a single hero model on a marketing page, and under 500 KB if several load at once. But the number you should actually be watching is texture count, not triangle count.
The four models
These are all live on this site right now. Triangle counts were read out of each file's glTF accessors, and the byte sizes are what the server sends. Nothing here is estimated or rounded up from memory.
| Model | Triangles | Textures | Shipped size | Draco |
|---|---|---|---|---|
| DNA strand | 179,214 | 0 | 461 KB | yes |
| Turbofan engine | 86,554 | 24 WebP | 1,253 KB | yes |
| Rover | 48,262 | 1 PNG | 312 KB | yes |
| Logo | 1,048 | 0 | 60 KB | no |
Read those numbers again
The relationship is the opposite of what most people expect:
- The DNA strand has 3.7× the rover's triangles but is only 1.5× the file size.
- The turbofan has half the DNA's triangles but is 2.7× the file size.
The heaviest mesh on the site is one of the smallest files. The lightest of the three real models is the largest download. Triangle count is barely predicting anything here.
Textures are. The DNA strand carries none, so Draco squeezes 180,000 triangles into 461 KB. The turbofan carries twenty-four texture images, and that is essentially the entire 1.25 MB.
For scale: a single PNG on this site's atlas is 878 KB — larger than the whole rover model, geometry and texture together.
So what should you budget?
These are working numbers, not standards. They are where we set the line for our own work, and the reasoning is stated so you can move it for your case.
| Situation | Target | Why |
|---|---|---|
| One hero model, desktop and mobile | < 2 MB | Loads over cellular without a visible stall |
| Several models on one page | < 500 KB each | They compete for the same connection |
| Product configurator, many variants | < 300 KB each | Users switch repeatedly; each swap is a fetch |
| Character with morph targets | budget separately | See below — the usual rules do not hold |
Triangles matter for frame rate rather than download. The turbofan runs at 60fps on desktop and is usable on a phone at 86,554 triangles, so on modern hardware geometry is rarely the first thing to break.
The exception nobody mentions: morph targets
Ask which compression to use and you will be told meshopt or Draco, usually with a confident recommendation. Both answers quietly assume a static mesh.
They stop being true for a rigged character:
- Draco does not compress morph targets. A prop with 80,000 triangles collapses beautifully. A character with fifty blend shapes barely moves, because the blend shape data is untouched.
- Quantisation and meshopt break Character Creator morphs outright. We shipped a CC4 avatar at roughly a tenth of its original size with the morphs intact only by leaving both alone and dropping morph normals instead.
If your model has facial animation or blend shapes, benchmark it directly. The general advice is written for props.
What to do, in order
- Measure before you optimise. Look at the split between geometry and textures first. Most people start by decimating a mesh that was never the problem.
- Delete textures that are not textures. A metallic or roughness map that is one flat value is a scalar factor wearing a costume. On one job that removed ten image files with no visual change at all.
- Convert to WebP. Usually the single biggest win, because textures are usually the bulk.
- Then apply Draco to the geometry, unless the model has morph targets.
- Re-measure. Optimisation without a before and after number is guessing.
How these were measured
Worth stating, because "3D file size" numbers on the web are usually quoted from memory or from a modelling package, and both mislead.
Byte sizes are what the server actually sends, taken from the HTTP response, not what the file looks like on a local disk before compression. Triangle counts were read directly out of each GLB's JSON chunk by summing the index accessor counts across every mesh primitive and dividing by three.
One trap that caught us while writing this. Blender reports faces; the web cares about triangles. Our own build notes recorded the turbofan at 46,073 faces, but it ships 86,554 triangles, because quads become two triangles on export. Quoting the face count would have understated the model by nearly half. If you are comparing a number from your modelling package against a web budget, check which unit you are holding.
Textures were counted from the glTF images array, so they are the
images actually packed into the file rather than what exists in the source
project.
The turbofan in that table is a full interactive walkthrough — seven stages, cutaway, airflow, and a test at the end. It is the 1,253 KB file from the first row, running in your browser.
Open the demo