Blog · Deep dives

Draco compression explained

Last updated 11 June 2026

Draco is the reason a 100 MB raw 3D model can load on a phone over 4G in under a second. It's an open-source geometry compression library Google published in 2017, now baked into the glTF spec and used by Sketchfab, Google Maps, e-commerce viewers, and most production WebXR. Here's what it does, how it does it, and when it's the right tool.

The problem Draco solves

Uncompressed 3D geometry is huge. A million-triangle mesh with positions, normals and UV coordinates takes around 35 MB in the standard glTF/GLB binary layout. That's fine if it's loading from disk, painful over the web.

General-purpose compression like gzip helps a little but not a lot — typically 1.5–2x reduction on already-binary 3D data, because the byte patterns don't repeat the way text does. You need something that understands what the bytes mean.

What Draco does

Draco is a specialised codec for triangle meshes. It exploits things general compressors can't:

Vertex prediction from neighbours

Adjacent vertices on a smooth surface are usually close to each other in space. Instead of storing each vertex's absolute position, Draco stores it as a delta from a prediction made from already-decoded neighbours. The deltas are smaller numbers than the absolutes, so they encode in fewer bits.

Quantisation with controllable precision

Floating point positions usually carry far more precision than the model needs. A character model that's 2 metres tall doesn't need sub-micrometre vertex accuracy. Draco quantises positions to a configurable bit depth — 14 bits is the typical default, giving roughly 16 000 distinct positions along each axis (about 0.01% of the bounding box). That alone halves the bits before any other compression kicks in.

Normals, UVs, vertex colours all quantise too, with different defaults — 10 bits for normals, 12 bits for UVs.

Connectivity compression

The triangle index list is compressed using a corner-table representation and Edgebreaker — a 1998 algorithm that encodes triangle connectivity as a sequence of letters describing how each triangle attaches to its neighbours. Very efficient on real-world manifold meshes.

Entropy coding

The final pass is range coding (related to arithmetic coding), which squeezes out residual redundancy in the quantised, predicted, connectivity-compressed stream.

Real-world numbers

Typical compression ratios on production glTF models:

The cost — decode time

Draco is asymmetric — encode is slow, decode is fast but not free. On a desktop, decoding a million-triangle Draco mesh takes 100–300 ms. On mobile, 300–800 ms. For most use cases that's fine, but it does mean for very small meshes Draco isn't worth it — the decode overhead can exceed the bytes you save.

Three.js and most loaders run Draco decode in a worker so it doesn't block the main thread.

When to use Draco

When to skip it

How to apply Draco

With glTF-Transform CLI:

npm install -g @gltf-transform/cli
gltf-transform draco model.glb model-draco.glb

With Blender: in the glTF export dialog, tick "Compression" — Blender applies Draco automatically.

With three.js: nothing changes on your side. The standard GLTFLoader reads Draco automatically as long as you've registered the DRACOLoader with the decoder path.

Draco vs Meshopt

Meshopt is a newer alternative compression scheme (Arseny Kapoulkine, 2020). Trade-offs:

For modern projects starting fresh, Meshopt is increasingly preferred for the decode performance. For maximum file size reduction, Draco still wins by a small margin.

Want to see Draco in action? Drop a regular GLB into the Open3D viewer, then compress with glTF-Transform and compare load times. The compressed version usually loads faster despite the decode step.