Stell dir das übliche Setup im Jahr 2026 vor: eine Symfony- oder Laravel-App, ein Queue-Worker, der jedes hochgeladene Dokument embeddet, und ein Qdrant-Node, der neben der Datenbank sitzt und semantische Suche über alles fährt. Die App selbst ist billig im Betrieb. Der Vektorspeicher nicht, denn Vektoren wollen RAM, und RAM ist das Teuerste, was man mieten kann. Qdrant 1.19 liefert darauf zwei Antworten, und ich will dafür plädieren, dass die unglamouröse davon, die vereinheitlichte Memory-Tier-API, das Feature ist, für das die meisten von uns upgraden sollten, während der schlagzeilenträchtige Datentyp turbo4 sowohl Bewunderung als auch einen Warnaufkleber verdient. Er wirft deine Full-Precision-Vektoren dauerhaft weg, und diese Entscheidung gehört nicht allein in eine Infra-Config-Datei.
{
"vectors": {
"size": 1536,
"distance": "Cosine",
"datatype": "turbo4"
}
}Fangen wir mit dem langweiligen Gewinn an. Vor 1.19 bedeutete die Kontrolle darüber, wo Qdrant Daten hält, ein Jonglieren mit on_disk in den Vector-Params, always_ram in der Quantization-Config und on_disk_payload auf Collection-Ebene, drei Flags mit drei Namen an drei Stellen. Den HNSW-Graphen selbst konntest du gar nicht platzieren, er lag immer im Heap. Version 1.19 verdichtet das zu einem einzigen memory-Parameter mit drei Werten: pinned (fest im RAM), cached (auf Disk, Page-Cache vorgewärmt, verdrängbar) und cold (auf Disk, lazy geladen). Er funktioniert gleichermaßen für Vektoren, HNSW-Links, quantisierte Kopien, Payloads und Payload-Indizes, und du kannst ihn per update_collection auf einer laufenden Collection ändern, ganz ohne Rebuild. Für alle, die Qdrant als Sidecar neben einer PHP-App betreiben und per HTTP mit ihm reden, macht das aus der Speicherplanung endlich einen echten Drehknopf statt Folklore.
Der Knopf zählt, weil die Rechnung hässlich ist. Cloud-RAM kostet irgendwo zwischen 3 und 8 Dollar pro GB und Monat, NVMe-Disk grob 0,10 bis 0,30 Dollar. Das Beispiel aus den Release Notes selbst: eine Milliarde float32-Vektoren mit 768 Dimensionen brauchen etwa 2,9 TB Storage, und ein komplett gepinntes Deployment will rund 3,7 TB RAM. Verschiebe die Originale in Cold Storage und pinne nur eine int8-quantisierte Kopie für die Graph-Traversierung, und du landest bei etwa 768 GB. Bei 5 Dollar pro GB und Monat sind das 18.500 Dollar gegenüber 3.840 Dollar. Du und ich sind vermutlich nicht bei einer Milliarde Vektoren, aber das Verhältnis übersteht die Reise runter auf zehn Millionen problemlos, und zehn Millionen Chunks sind eine sehr erreichbare Zahl für jedes Produkt, das Kundendokumente embeddet.
Jetzt zum scharfen Messer. TurboQuant kam in 1.18 als Quantisierungsmethode, aufgebaut auf einer Idee von Google Research: Rotiere den Vektor zufällig vor dem Komprimieren, damit sich die Information gleichmäßig über die Dimensionen verteilt und die 4-Bit-Kodierung überall ein bisschen verliert statt irgendwo viel. In 1.18 lag diese 4-Bit-Kopie noch zusätzlich auf deinen float32-Originalen, was insgesamt 36 Bits pro Dimension bedeutete. In 1.19 wird turbo4 zum Datentyp. Setzt du ihn bei der Collection-Erstellung, speichert Qdrant nur noch die 4-Bit-Form. Kein float32 auf Disk, keins im RAM, keins irgendwo. Zehn Millionen text-embedding-3-small-Vektoren mit 1536 Dimensionen schrumpfen von rund 64 GB unter dem alten Muster auf etwa 7 GB. Bei Multi-Vector-Collections im ColBERT-Stil, wo jedes Dokument Dutzende Token-Embeddings trägt, multiplizieren sich die Einsparungen pro Vektor.
Der Preis ist das Rescoring, genauer gesagt dessen dauerhafte Abwesenheit. Ohne Full-Precision-Kopie laufen sowohl die Graph-Traversierung als auch das finale Ranking auf 4-Bit-Distanzen, und der typische Recall landet bei etwa 0,90 bis 0,95, verglichen mit 0,97 bis 0,99, wenn du gegen float32 rescorest. Und hier kommt mein eigentlicher Punkt: Diese Lücke ist eine Produktentscheidung im Ops-Kostüm. Wer datatype turbo4 in eine Collection-Config schreibt, entscheidet, dass ungefähr eins von zwanzig relevanten Ergebnissen stillschweigend nicht mehr zurückkommen darf. Für First-Stage-Retrieval, das einen Cross-Encoder-Reranker füttert, oder für ein Empfehlungs-Widget ist dieser Tausch oft richtig. Für alles, wo ein verpasster Treffer Konsequenzen hat, ein juristisches Archiv, eine Compliance-Abfrage, sollte die Person, die die Config deployt, nicht die einzige sein, die das abgesegnet hat.
Das faire Gegenargument lautet, dass diese Tür nicht wirklich verschlossen ist. Wenn du den Quelltext behalten hast, und das solltest du, kannst du jederzeit alles neu embedden und eine float32-Collection wieder aufbauen. Stimmt, und das nimmt der Entscheidung das Drama. Aber zehn Millionen Chunks neu zu embedden kostet echtes API-Geld und echte Tage, und der Fehlerfall ist genau deshalb gemein, weil er leise ist: Recall-Regressionen tauchen als Support-Ticket auf, in dem steht, die Suche fühle sich schlechter an, und niemandes erster Verdächtiger ist ein Storage-Datentyp, der vor acht Monaten gewählt wurde. Also miss vor dem Umlegen den Recall mit deinen eigenen Queries auf deinen eigenen Daten, nicht mit synthetischen Vektoren. Achte außerdem aufs Kleingedruckte: turbo4 ist dense-only, und Manhattan-Distanz erzwingt die vollständige Vektor-Rekonstruktion, bleib also bei Cosine, Dot oder Euclidean. Und es gibt einen Mittelweg, den ich wirklich mag: Staple 1-Bit-TurboQuant auf turbo4 und rescore gegen die 4-Bit-Werte, besserer Recall als gar keiner, immer noch der 4-Bit-Disk-Footprint.
Man muss dazusagen: Niemand sonst bietet genau diesen Tausch gerade an. Weaviate hat ein eigenes rotationsbasiertes Quantisierungsschema, behält aber immer die unkomprimierten Vektoren, Milvus geht nicht unter 8 Bit, und Pinecones Serverless-Tier bietet überhaupt keine Kontrolle über Kompression oder Platzierung. Aus PHP-Land, wo der Vektorspeicher meist ein Dienst ist, den wir aus einem Worker aufrufen, statt ein System, das wir patchen, nehme ich einen expliziten Regler jederzeit lieber als eine intransparente Managed-Entscheidung, denn die Rechnung landet so oder so in unserem Briefkasten.
Also, hier lande ich: Upgrade wegen der Memory-Tiers, behandle turbo4 wie eine Schema-Migration, die du nicht billig zurückrollen kannst, und schreib die Recall-Zahl in die Pull-Request-Beschreibung, wo ein Mensch sie lesen muss. Jetzt sag mir, wo deine Grenze liegt. Würdest du turbo4 für nutzerseitige Suche in Produktion fahren, und wenn ja, bei welchem Recall-Wert, gemessen auf deinem eigenen Query-Log, wärst du bereit, die Originale zu löschen? Ich ahne, dass die Antworten unter dieser Kolumne von 0,99 bis zu einem Schulterzucken reichen werden, und ich will beide sehen.
Kommentare
Noch keine Kommentare — schreib den ersten.
Starte die Diskussion
Kein Konto, kein Passwort nötig — gib einfach deine E-Mail-Adresse ein, wir senden dir einen einmaligen Anmelde-Link. Beim ersten Mal bist du damit automatisch angemeldet.
Deine Bewertung wird nach der Anmeldung automatisch übernommen.
Schau in dein Postfach
Wir haben einen Anmelde-Link an … gesendet. Öffne ihn auf diesem Gerät — dieser Tab meldet dich automatisch an.
Nichts angekommen? Wirf einen Blick in den Spam-Ordner — und markiere die Mail dort als „Kein Spam“, dann landet sie künftig direkt im Postfach.