Skip to main content
Version: Next

Defaults and Benchmarks

This page explains why the defaults are what they are, with the numbers that decided each one. It exists so you can judge whether a default fits your data.

Data set size and homogeneity

Every measurement here comes from the demo dataset: one product category (Car), in one language (English), around 300 objects, and 338 image assets, with several near-identical variants per car model.

Use the Evaluation Tool to analyze and reproduce any of this on your own content before treating a default as the right choice for you.

Summary

DecisionDefaultReason
Text modelnomic-ai/nomic-embed-text-v2-moe (768-d)Multilingual and Apache-2.0, and it beats the English-only predecessor on English too — so the language support costs nothing.
Image modelgoogle/siglip2-base-patch16-256 (768-d), two towers, one shared_spaceThe only multilingual image family among the candidates, in its cheap base variant — the English-only alternative cannot serve non-English queries at all.
Text representationvalues-only (keyless)Field names spend the model's attention on schema words nobody queries.
Chunk size / overlap1000 / 150 charactersA convention — see below.
Image thumbnail256×256 cover, JPEG q90Matches siglip2-base-patch16-256's native input; a smaller thumbnail is upscaled and throws detail away.
Compressionon_disk + 32x binary~13× less graph memory at no accuracy cost on this dataset.
Duplicate detectioncontent hash + vector + MinHashA vector score alone over-merges; the exact hash is the only fully reliable signal.

Models

The candidates

The defaults are the two multilingual models in this table. That is the whole story: multilingual support became a hard requirement, and among the candidates that have it, these were the cheapest with a commercially usable licence.

ModelRoleMultilingualDimRel. speedWeightsLicence
nomic-embed-text-v2-moe (default)textyes (~100 langs)768~1.2× †1.77 GBApache-2.0
siglip2-base-patch16-256 (default)image + query toweryes768~1.4× img, ~1.5× text †1.40 GBApache-2.0
nomic-embed-text-v1.5textno7681.0× (text baseline)0.51 GBApache-2.0
nomic-embed-vision-v1.5imageno7681.0× (image baseline)0.35 GBApache-2.0
clip-vit-base-patch16imageno512~0.9× img †0.56 GBMIT
Qwen3-Embedding-0.6Btextyes10244.3× slower1.11 GBApache-2.0
siglip2-so400m-patch14-384imageyes115216.4× slower4.23 GBApache-2.0

Weights is the model's safetensors size, measured from the served model cache. It is comparable across rows but is not runtime memory.

Rel. speed is per modality — text models timed on text, image models on images, each against the Nomic model of the same modality. For multilingual support Qwen3 was several× slower, so400m tens of× slower.

Candidates excluded before benchmarking

ModelMultilingualWhy it never reached the run
jina-clip-v2, jina-embeddings-v3yesCC-BY-NC-4.0 — non-commercial; unusable in a shipped product without a paid licence.
jina-embeddings-v4yesQwen Research Licence (commercial on request); 3.8B params and 2048-d inflate GPU and index cost.
Cohere Embed v4yesCommercial API only, not self-hostable — contradicts the local-inference default and adds per-token cost.
BGE-M3, multilingual-e5-large, LAION XLM-R CLIPyesMIT and viable for text, but BGE-M3 has no image tower, so an image model would still be needed alongside.

Image thumbnail

The image model embeds a Pimcore thumbnail, not the original file, and its size is a real quality decision rather than a formality:

SettingRecommendedWhy
Dimensions256×256 (cover)The native input of siglip2-base-patch16-256.
Format / qualityJPEG, 90A lossless format costs bandwidth per request without changing what the model sees; below ~85, compression artefacts start reaching the vectors.
MethodcoverFills the square by cropping rather than letterboxing — padding bars are content the model would otherwise embed.

Err upward rather than downward when unsure: a larger thumbnail is downscaled correctly by the service, while a smaller one is interpolated up and cannot recover detail that was never there.

Each image model names one via thumbnail, so the size is always a choice you made. Its pixel-affecting settings are fingerprinted into the identity key, so changing the definition re-embeds exactly that model's images.

Text data format

The composed text can name its fields or not. In the beginning there were eight different candidates compared from which three best performing candidates were selected for the further benchmark. Candidates were compared on identical data, queries, and index settings:

Known-item retrieval — one query per object, "did the right object come back in the top 10":

FormatWhole-document hit@10Chunked hit@10
values-only0.9751.000
key-value0.9610.989
position-labeled0.9360.993

Curated relevance labels — precision within the first page, scored against handwritten label files (24 general + 7 attribute queries):

FormatP@10 (general)P@10 (attribute)
values-only0.470.27
key-value0.420.21
position-labeled0.420.24

Both metrics put values-only first, and the reason is consistent: human scaffolding dilutes the signal. Field names ("cylinders: 4" instead of "4") and full sentences ("The manufacturer is…") spend the model's limited attention on schema words no user ever types.

Chunking

**These are based on conventions:

ParameterValueBasis
Chunk size1000 characters~250 tokens, a standard retrieval size. Never swept.
Overlap150 characters (15%)Same.
Fusion across chunksmaximumLocked for the first version; max did beat mean for the default format.
max_input_chars20000A cost guard, bounding how many requests one element can trigger — not a quality tuning knob.

Chunk boundaries are measured in characters rather than tokens on purpose: a third-party inference endpoint exposes no tokenizer, so a character budget is the only thing the bundle can apply consistently.

Why to chunk at all? On the same run, chunking improved 7 of 8 candidate formats (up to +0.225 recall) and took values-only from 0.975 to a perfect 1.000 hit@10.

Compression

The default is on_disk + 32x binary quantization, because vector storage dominates cost at scale. Measured on real vectors:

StrategyDedup recall@1Search recall@10LatencyGraph memory
float321.0001.00012.2 ms1734 KB
int81.0000.98611.8 ms
int40.8600.80415.4 ms185 KB
binary (32x)1.0001.00027.6 ms133 KB

551 documents, nomic_text; pass bars were dedup recall@1 ≥ 0.99 and search recall@10 ≥ 0.95. int4 fails both — it is not a supported option for that reason.

Storage at scale, 768 dimensions:

LevelPer vector@ 1M vectors
1x float323.0 KB~3.15 GB
4x int8~0.75 KB~0.9 GB
32x binary~0.1 KB~92 MB floor, ~242 MB

Binary is the default because it passed every quality bar on real vectors while using roughly 13× less graph memory than float32. It also brings some downsides:

  • Longer query latency due to rescoring and disk storage.
  • It relies on rescore oversampling (×3.0), which keeps a full-precision copy on disk.

Quantization is per-model, and changing it needs only a reindex — no re-embedding — so it is inexpensive to test alternatives. For uncompressed vectors set quantization: { mode: in_memory, compression_level: '1x' }.

Reproducing this

All of it comes from the Evaluation Tool, which runs against a real index with curated label files. The tool can be used to reproduce any of the above measurements on your own data and to compare alternative models, formats, and compression strategies. It is the recommended way to know whether a default is right for your content.