Tools Review

pg_vectorsearch PRISM: Indeks Vektor PostgreSQL 20x Lebih Cepat dari HNSW

pg_vectorsearch PRISM: Indeks Vektor PostgreSQL 20x Lebih Cepat dari HNSW

pg_vectorsearch adalah extension PostgreSQL baru dari Timescale yang memperkenalkan indeks vektor bernama PRISM, dan klaim benchmarknya diukur pada 100 juta vektor: build selesai dalam 1 jam 40 menit di mesin 128 GB, sementara HNSW pgvector tidak selesai dibangun sama sekali di ukuran RAM itu dan butuh 42 jam di mesin 512 GB. Latensinya 6 ms pada recall 95 persen. Extension ini masih berstatus alpha dan mensyaratkan PostgreSQL 18 ke atas.

TL;DR

  • PRISM memakai pendekatan partisi berbasis IVF dengan kuantisasi RaBitQ, bukan graf HNSW, sehingga indeksnya dibaca sekuensial dan bisa hidup di buffer cache PostgreSQL.
  • Di 100 juta vektor: build 1 jam 40 menit versus 42 jam, ukuran indeks 25 GB versus 180 GB, dan 6 ms p50 pada 95 persen recall di mesin dengan RAM seperempat milik HNSW.
  • Di 1 juta vektor pada instance 4 GB: indeks PRISM sekitar 7 kali lebih kecil dan query sekitar 40 kali lebih cepat dibanding HNSW pada recall yang sama.
  • Yang belum siap: churn tinggi memicu drift recall dan butuh prism_rebalance atau REINDEX manual, delete memakai tombstone tanpa memakai ulang ruang, dan belum ada jaminan uji replikasi fisik serta backup restore.
  • Kompatibel dengan pgvector: indeks PRISM bisa dibangun di kolom vector atau halfvec yang sudah ada tanpa rewrite, dan keduanya bisa diinstal berdampingan.

Kenapa HNSW bisa minta RAM 512 GB?

Karena struktur graf memaksa baca acak. HNSW menghubungkan tiap vektor dengan tetangganya, jadi pencarian berpindah dari satu simpul ke simpul lain yang alamatnya baru diketahui setelah simpul sebelumnya dibaca. CPU tidak bisa prefetch alamat yang tidak bisa diprediksi, sehingga hampir setiap lompatan meleset dari cache dan inti prosesor menganggur menunggu memori. Supaya tetap cepat, sebagian besar graf harus berada di RAM, dan tiap vektor ikut menyimpan daftar edge yang membuat graf itu besar. Timescale mengukur, pada 100 juta vektor, mesin terkecil tempat HNSW berhasil menyelesaikan build punya 512 GB RAM. Angka itu bukan kebutuhan hasil tune, melainkan batas yang muncul dari bentuk strukturnya.

Masalah ini bukan baru di rumah Timescale. Pada 2024 mereka merilis pgvectorscale dengan algoritma berbasis graf yang terinspirasi riset DiskANN Microsoft, dengan desain yang dioptimalkan untuk disk supaya indeks bisa tumbuh melampaui RAM. Ketika diuji ke lebih banyak dataset, terutama yang berdimensi rendah, sebagian graf ternyata bisa menjadi tidak terjangkau dan recall turun tanpa suara. Yang membuat kesal, recall yang memburuk tidak terukur seperti query yang lambat, dan pengguna baru sadar ketika hasil pencarian mulai dipertanyakan.

Berapa bedanya di 100 juta vektor?

Perbandingan dilakukan pada dataset Cohere embeddings 100 juta baris di dua instance AWS, dengan konfigurasi PostgreSQL yang sama dan recall@10 terhadap hasil brute force. Semua hasil HNSW memakai tipe halfvec 16 bit milik pgvector, yang menurut tim Timescale memberi tradeoff terbaik antara performa query dan ukuran indeks.

MetrikPRISM di 128 GBHNSW di 128 GBPRISM di 512 GBHNSW di 512 GB
Biaya instance per jam (relatif)1x1x4x4x
Waktu build indeks1 jam 40 menitTidak selesai49 menit42 jam
Ukuran indeks25 GBTidak selesai25 GB180 GB
Latensi p50 pada 95 persen recall6 msTidak selesai4 ms8 ms
Latensi p50 pada 99 persen recall21 msTidak selesai19 msTidak tercapai

Dua hal yang paling layak digarisbawahi dari tabel itu. Pertama, pada mesin 128 GB HNSW tidak menyelesaikan build, sehingga perbandingan latensi di kolom itu memang tidak ada, bukan angka yang disembunyikan. Kedua, PRISM tetap menang di mesin besar, dengan build 49 menit versus 42 jam pada instance yang sama, yang berarti biaya percobaan tuning ikut turun drastis. Timescale juga mencoba jalan pintas: membangun graf di mesin 512 GB lalu menyajikan indeksnya di mesin 128 GB. Hasilnya tetap buruk, lebih dari satu detik per query pada 95 persen recall dan 99 persen tidak tercapai sama sekali.

Apakah manfaatnya hilang di dataset kecil?

Justru sebaliknya, dan ini bagian yang paling relevan untuk mayoritas proyek RAG di Indonesia yang jauh dari 100 juta vektor. Di uji skala 1 juta vektor pada instance c8g.large dengan 4 GB RAM, PRISM membangun indeks dalam sekitar 3 menit sementara HNSW butuh sekitar 21,7 jam karena grafnya tidak muat di 4 GB saat konstruksi dan build-nya thrashing. Ukuran indeksnya 280 MB versus 2,05 GB, atau sekitar 7 kali lebih kecil, dan latensi p50 pada recall 95 persen tercatat 3 ms versus 122 ms pada mesin yang sama, sekitar 40 kali lebih cepat. Di mesin 2 GB, tempat HNSW bahkan tidak dicoba karena build 4 GB saja sudah gagal, PRISM melayani 15 ms pada recall 99 persen. Untuk konteks biaya, instance kelas 2 GB adalah tingkat yang biasa dipakai aplikasi internal, bukan infrastruktur khusus.

Bagaimana cara memakainya tanpa menulis ulang tabel?

Dengan membangun indeks PRISM di kolom pgvector yang sudah ada. Tipe vec32 dan vec16 bikinan pg_vectorsearch binary-compatible dengan vector dan halfvec, hanya namanya berbeda, sehingga kedua extension bisa diinstal berdampingan bahkan di schema yang sama, dan kolom tidak ditulis ulang atau disalin.

CREATE EXTENSION pg_vectorsearch;
CREATE INDEX documents_embedding_prism
  ON documents USING prism (embedding vec32_l2_ops);

EXPLAIN (COSTS OFF)
SELECT id, body FROM documents
ORDER BY embedding '[0.11, 0.02, 0.9]' LIMIT 10;

SET prism.nprobe = 40;

Operator class dipilih mengikuti metrik jarak yang dipakai indeks HNSW lama: vec32_l2_ops, vec32_ip_ops, atau vec32_cosine_ops, dengan padanan vec16 untuk kolom halfvec. Setelah EXPLAIN menunjukkan indeks PRISM yang dipilih planner, indeks HNSW lama bisa di-drop. Panduan tuning dan migrasi dari HNSW ditulis di README proyeknya. Satu-satunya knob yang biasanya disentuh di produksi adalah prism.nprobe, yaitu jumlah partisi yang dipindai tiap query; default 0 memilih otomatis dengan target sekitar 95 persen recall, dan menaikkannya memberi recall tambahan dengan konsekuensi latensi. Untuk tabel baru, pgvector bahkan tidak dibutuhkan karena extension ini mengirim tipe vektornya sendiri. Satu catatan dari README: indeks sebaiknya dibangun setelah data termuat, karena ukuran indeks ditentukan dari jumlah baris saat CREATE INDEX dan sekitar 500 baris sudah cukup supaya planner mau memakai indeks itu.

Kenapa partisi bisa lebih murah secara hardware?

Karena pemindaian sekuensial memakai bandwidth, sementara graf memakai latency. PRISM membelah ruang vektor menjadi cluster dengan k-means, menyimpan kode vektor yang sudah dikompresi dan row ID berdampingan di halaman database yang dipadatkan, lalu menelusuri pohon centroid kecil yang tetap hangat di buffer cache PostgreSQL. Sisa pemindaian berjalan lurus di memori sehingga prefetcher CPU bisa mendahului dan loop SIMD menilai banyak vektor per instruksi. Kuantisasinya memakai RaBitQ, kurang lebih satu bit per dimensi, dengan bound kesalahan teoretis yang membuat kandidat yang pasti bukan tetangga terdekat bisa dibuang sebelum reranking. Efeknya berlipat: makin sedikit data yang dipindah, makin sedikit baca acak ke tabel penuh. Bound itu juga makin ketat karena yang dikompresi adalah selisih vektor terhadap centroid cluster, yang nilainya jauh lebih kecil daripada vektor relatif ke titik asal, dan HNSW tidak punya centroid untuk dikurangi.

Arah ini bukan inovasi tunggal. Google memakai pendekatan serupa di ScaNN untuk AlloyDB, Microsoft di SPANN, dan turbopuffer di mesin ANN mereka: partisi ruang vektor, kompres, lalu pindai partisi terdekat dengan SIMD. PRISM bahkan ikut mengadopsi teknik spilling SOAR dari ScaNN, yaitu menyimpan vektor di dekat batas partisi ke lebih dari satu partisi, dengan menukar sedikit ruang penyimpanan demi recall.

Apa yang belum siap di versi alpha ini?

Cukup banyak, dan timnya menyebutnya sendiri di pengumuman 13 Oktober 2026. Insert dan update sudah jalan, tetapi churn berat bisa membuat partisi menjadi suboptimal dan recall bergeser, sementara belum ada repartisi otomatis, sehingga operator harus memanggil prism_rebalance untuk memecah partisi yang terlalu besar atau REINDEX untuk membangun ulang dari nol. Delete sudah jalan tetapi ruang di halaman indeks belum dipakai ulang karena baris berubah menjadi tombstone oleh VACUUM dan hanya dilewati saat pemindaian; ruangnya baru kembali setelah REINDEX. Membuat indeks di tabel kosong lalu mengisinya juga tidak disarankan di versi ini. Untuk GA, yang dijanjikan adalah rebalancing inkremental otomatis, streaming search agar klausa WHERE bisa disaring sambil indeks terus menghasilkan kandidat, serta penguatan uji replikasi fisik, backup restore, dan throughput multi-klien. Yang lebih jauh: eksekusi query paralel, indeks multi-kolom untuk tabel multi-tenant, reklaim ruang saat VACUUM, dan benchmark miliaran vektor.

Syarat teknisnya juga harus dicatat karena membatasi siapa yang bisa mencoba hari ini: PostgreSQL 18 atau lebih baru dengan development headers, compiler GNU C11 (GCC 11 atau Clang 14 ke atas), sistem build Meson, dan CBLAS opsional untuk encoding RaBitQ yang lebih cepat. Source-nya tersedia di bawah PostgreSQL License dan bisa dikompilasi sendiri. Untuk lingkungan yang masih memegang PostgreSQL 15 atau 16, artinya jalur PRISM belum terbuka dan upgrade versi database menjadi prasyarat tersendiri.

Kapan tetap pakai HNSW?

Ketika datanya kecil dan berubah cepat. HNSW tumbuh satu vektor pada satu waktu, sementara indeks partisi butuh cukup data untuk membentuk cluster yang bermakna, dan itulah alasan graf masih cocok untuk sebagian workload. Jarak ini memang menyempit karena teknik partisi, merge, dan rebalance terus dikembangkan, dan Timescale menuliskan rencana otomatisasinya, tetapi untuk hari ini berlaku aturan praktis sederhana: kalau datasetmu ratusan ribu ke atas dan masalah terbesarmu adalah RAM, PRISM layak dicoba; kalau datasetmu kecil dan sering di-mutate, HNSW tetap pilihan yang masuk akal. Karena statusnya alpha dan upgrade antar prerelease bisa tidak mungkin, pemakaiannya di produksi penuh belum saatnya, sementara rencana penghentiannya sudah jelas karena pgvectorscale resmi masuk maintenance mode.

Seluruh angka di artikel ini dikutip dari pengumuman rilis Announcing pg_vectorsearch tanggal 13 Oktober 2026 oleh Erik Nordstrom, Matvey Arye, dan Noah Hein, serta dari README repositori resminya; tidak ada angka yang dihitung ulang di luar dua sumber itu.

FAQ

Apakah pg_vectorsearch menggantikan pgvector?

Tidak. Keduanya bisa diinstal berdampingan dan indeks PRISM dibangun di kolom pgvector yang ada tanpa mengubah query. pgvector tetap menyediakan tipe vektor dan operatornya, sementara pg_vectorsearch menyediakan access method indeks baru.

Berapa versi PostgreSQL minimum yang dibutuhkan?

PostgreSQL 18 ke atas, dengan development headers, compiler GCC 11 atau Clang 14, dan Meson sebagai sistem build. CBLAS bersifat opsional untuk mempercepat encoding RaBitQ.

Kenapa recall saya turun setelah banyak update?

Karena versi alpha belum melakukan repartisi otomatis. Partisi bisa menjadi tidak seimbang setelah churn tinggi, sehingga pemindaian melewatkan kandidat yang relevan. Solusi resminya sekarang adalah memanggil prism_rebalance atau membangun ulang indeks dengan REINDEX.

Apakah angka benchmark ini bisa saya ulangi?

Tim Timescale menyatakan seluruh hasilnya datang dari alat benchmark publik mereka dan memakai recall@10 terhadap brute force. Satu hal yang perlu diperhatikan: angka itu diukur di instance AWS tertentu, sehingga hasil di hardware lain bisa berbeda, dan mereka sendiri mengundang pengguna membuka issue kalau hasilnya tidak cocok.

💬 Komentar (0)

Belum ada komentar. Jadilah yang pertama! 💬

Komentar akan muncul setelah moderasi.