Build your own vector database
Scalar (int8) quantization·6 min

Why quantize

0 / 1

Vectors are the memory hog. A corpus of 100k × 128 float32 = 51 MB; a billion vectors = terabytes. Qdrant's scalar quantization maps each float32 dimension to a signed int8 (4x smaller, faster integer distance), then rescores the top candidates with the original float32 vectors to recover accuracy.

The mapping

Signed int8 codec
bucket = round( (f - offset) / alpha )   in [0, 255]
i8     = bucket - 128                     in [-128, 127]
f ~= alpha * (i8 + 128) + offset

[offset, offset + 255*alpha] = the value range, taken at a
quantile (~0.99) to clip outliers.

Worked example, value range [-0.5, 0.5]: offset = -0.5, alpha = 1.0/255 ≈ 0.003922.

  • f = 0.0 → bucket round((0 + 0.5)/0.003922) = round(127.5) = 128 → i8 = 0. Recover: 0.003922·128 - 0.5 ≈ 0.0. ✓
  • f = -0.5 → bucket 0 → i8 = -128.
  • f = 0.5 → bucket 255 → i8 = 127.

Every code lands in [-128, 127]; the value 128 never appears.

Signed int8, end to end

We use signed int8 [-128, 127] everywhere — it matches Int8Array and Qdrant's int8 framing. Qdrant's articles show both signed and unsigned variants; we pick signed and never mix them, so the fixture codes are signed integers.