<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
  <title>github.com/timescale</title>
  <link>https://aggr.aymericbeaumet.com/sources/github.com/timescale/</link>
  <description>Browse aymeric&#39;s, an independent, searchable archive of readable snapshots from followed feeds, preserved in Git with aggr.</description>
  <language>en</language>
  <atom:link href="https://aggr.aymericbeaumet.com/sources/github.com/timescale/rss.xml" rel="self" type="application/rss+xml"/>
  <lastBuildDate>Wed, 14 Oct 2026 11:47:53 +0000</lastBuildDate>
  <generator>aggr</generator>
  <item>
    <title>Pg_vectorsearch: An index that is faster than pgvector&#39;s IVFFlat and HNSW</title>
    <link>https://aggr.aymericbeaumet.com/items/hnrss-org/2026-10-14-pg-vectorsearch-an-index-that-is-faster-than-pgvector-s/</link>
    <guid isPermaLink="false">urn:aggr:item:8864bb793ae5c3a5d9d1849501b17c6c2c9a4c2d</guid>
    <atom:link href="https://github.com/timescale/pg_vectorsearch" rel="via" type="text/html"/>
    <pubDate>Wed, 14 Oct 2026 11:47:53 +0000</pubDate>
    <dc:creator>jascha_eng</dc:creator>
    <description>A PostgreSQL extension for high-performance approximate nearest neighbor (ANN) search. Status: alpha. Meant for testing, not production. Upgrading between prereleases may not be possible; plan to drop and recreate the extension and its…</description>
    <content:encoded>&lt;p&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/actions/workflows/build.yml?query=branch%3Amain+event%3Apush&quot;&gt;&lt;picture class=&quot;article-picture article-badge&quot; style=&quot;--image-width:160px;--image-ratio:160 / 24&quot;&gt;&lt;img src=&quot;https://github.com/timescale/pg_vectorsearch/actions/workflows/build.yml/badge.svg?branch=main&amp;amp;event=push&quot; width=&quot;160&quot; height=&quot;24&quot; alt=&quot;Build&quot; loading=&quot;eager&quot; decoding=&quot;async&quot; fetchpriority=&quot;high&quot; referrerpolicy=&quot;no-referrer&quot; class=&quot;progressive-image&quot;&gt;&lt;/picture&gt;&lt;/a&gt; &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://timescale.github.io/pg_vectorsearch/coverage/&quot;&gt;&lt;picture class=&quot;article-picture article-badge&quot; style=&quot;--image-width:160px;--image-ratio:160 / 24&quot;&gt;&lt;img src=&quot;https://camo.githubusercontent.com/94d6957c816eb3e23de12a7667353594703591c1e342e0ec2e23e4dde4b807f0/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f74696d657363616c652e6769746875622e696f2f70675f766563746f727365617263682f636f7665726167652d62616467652e6a736f6e&quot; width=&quot;160&quot; height=&quot;24&quot; alt=&quot;Coverage&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;low&quot; referrerpolicy=&quot;no-referrer&quot; class=&quot;progressive-image&quot;&gt;&lt;/picture&gt;&lt;/a&gt; &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://scan.coverity.com/projects/timescale-pg_vectorsearch&quot;&gt;&lt;picture class=&quot;article-picture article-badge&quot; style=&quot;--image-width:160px;--image-ratio:160 / 24&quot;&gt;&lt;img src=&quot;https://camo.githubusercontent.com/b14b414026fcae54c331173f9b694d0fd26adaa1cba9e00a20df430d217ab016/68747470733a2f2f7363616e2e636f7665726974792e636f6d2f70726f6a656374732f74696d657363616c652d70675f766563746f727365617263682f62616467652e737667&quot; width=&quot;160&quot; height=&quot;24&quot; alt=&quot;Coverity&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;low&quot; referrerpolicy=&quot;no-referrer&quot; class=&quot;progressive-image&quot;&gt;&lt;/picture&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A PostgreSQL extension for high-performance approximate nearest neighbor (ANN) search.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Status: alpha.&lt;/strong&gt; Meant for testing, not production. Upgrading between prereleases may not be possible; plan to drop and recreate the extension and its indexes. See the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt; for known issues.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PRISM index&lt;/strong&gt; (100M+ vectors) — IVF-style, with hierarchical routing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RaBitQ quantization&lt;/strong&gt; with theoretical error bounds for two-stage search&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SIMD-optimized distance computation&lt;/strong&gt; (AVX2, AVX512, NEON)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic updates&lt;/strong&gt; — inserts, updates and deletes, with posting-list splits via &lt;code&gt;prism_rebalance&lt;/code&gt; (see &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#maintenance&quot;&gt;Maintenance&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pgvector compatible&lt;/strong&gt; — index existing &lt;code&gt;vector&lt;/code&gt; and &lt;code&gt;halfvec&lt;/code&gt; columns as-is (see &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#existing-pgvector-tables&quot;&gt;Existing pgvector tables&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;PRISM Index&lt;/h2&gt;
&lt;p&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/images/prism-logo.jpg&quot;&gt;&lt;picture class=&quot;article-picture article-picture-fallback&quot; style=&quot;--image-ratio:16 / 9&quot;&gt;&lt;img src=&quot;https://github.com/timescale/pg_vectorsearch/raw/main/images/prism-logo.jpg&quot; alt=&quot;PRISM&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;low&quot; referrerpolicy=&quot;no-referrer&quot; class=&quot;progressive-image&quot;&gt;&lt;/picture&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PRISM (Partitioned Routing Index for Similarity Matching) is a PostgreSQL-native index access method that is conceptually similar to &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/pgvector/pgvector&quot;&gt;pgvector&lt;/a&gt;&#39;s IVFFlat, but it is built around state-of-the-art quantization, routing, and partitioning techniques. It is implemented in C for high performance and seamless integration with PostgreSQL.&lt;/p&gt;
&lt;p&gt;The result: an &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.tigerdata.com/blog/announcing-pg_vectorsearch-scalable-open-source-vector-search-postgresql&quot;&gt;index that is significantly faster&lt;/a&gt; than pgvector&#39;s IVFFlat and HNSW, for both querying and index building. In fact, compared to graph-based HNSW, PRISM is faster at equivalent recall on a 100-million-vector dataset, on an instance with a quarter of the memory.&lt;/p&gt;
&lt;p&gt;To achieve this performance, PRISM uses a hierarchical centroid tree to partition vectors into clusters, and relies on the PostgreSQL buffer cache to keep that tree warm in memory. Vectors are &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/gaoj0017/RaBitQ&quot;&gt;RaBitQ&lt;/a&gt;-quantized and stored in posting lists with a page layout optimized for SIMD distance computation. The RaBitQ encoding carries error bounds that let a search rule out vectors that cannot possibly be nearest neighbors, so far fewer of them need reranking against the full-precision vectors stored in the table.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;Query Flow:
1. Traverse centroid tree to find nearest clusters (buffer cache)
2. Scan posting lists for candidates (buffer cache, async I/O)
3. RaBitQ two-stage filtering: estimate → error bound → rerank
4. Full-precision reranking from heap
5. Return k nearest neighbors
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For detailed architecture, see &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/architecture.md&quot;&gt;docs/architecture.md&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;Install the extension first; see &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#building&quot;&gt;Building&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are two ways to use a PRISM index. Pick the one that matches where your vectors live:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#native-types&quot;&gt;Native types&lt;/a&gt;.&lt;/strong&gt; Starting fresh, or not using pgvector? Store vectors in &lt;code&gt;pg_vectorsearch&lt;/code&gt;&#39;s own &lt;code&gt;vec32&lt;/code&gt; (float32) or &lt;code&gt;vec16&lt;/code&gt; (float16) columns. No other extension is needed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#existing-pgvector-tables&quot;&gt;Existing pgvector tables&lt;/a&gt;.&lt;/strong&gt; Already have &lt;code&gt;vector&lt;/code&gt; or &lt;code&gt;halfvec&lt;/code&gt; columns? Install &lt;code&gt;pg_vectorsearch&lt;/code&gt; next to pgvector and build a PRISM index on those columns as they are. Your table and queries stay unchanged.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both paths build the same index and use the same operators (&lt;code&gt;&amp;lt;-&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;#&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt;) and &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#tuning&quot;&gt;tuning&lt;/a&gt; knobs.&lt;/p&gt;
&lt;h3&gt;Native types&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;SQL&quot;&gt;&lt;span class=&quot;syntax-source syntax-sql&quot;&gt;CREATE EXTENSION pg_vectorsearch;

&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; PLAIN keeps the vector inline. EXTERNAL (the default) toasts a value
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; over ~2 kB, and rerank then pays an extra fetch the planner does not cost.
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-create syntax-sql&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-create syntax-sql&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-other syntax-sql&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-sql&quot;&gt;items&lt;/span&gt;&lt;/span&gt; (
    id &lt;span class=&quot;syntax-storage syntax-type syntax-sql&quot;&gt;serial&lt;/span&gt; &lt;span class=&quot;syntax-storage syntax-modifier syntax-sql&quot;&gt;PRIMARY KEY&lt;/span&gt;,
    embedding vec32(&lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;3&lt;/span&gt;) STORAGE PLAIN
);

&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; Load first; the index is sized from the row count at CREATE INDEX.
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; 500 rows is enough for the planner to use the index.
&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;INSERT INTO&lt;/span&gt; items (embedding)
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;SELECT&lt;/span&gt; ARRAY[i::&lt;span class=&quot;syntax-storage syntax-type syntax-sql&quot;&gt;real&lt;/span&gt;, (i % &lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;7&lt;/span&gt;)::&lt;span class=&quot;syntax-storage syntax-type syntax-sql&quot;&gt;real&lt;/span&gt;, (i % &lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;5&lt;/span&gt;)::&lt;span class=&quot;syntax-storage syntax-type syntax-sql&quot;&gt;real&lt;/span&gt;]::vec32
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;FROM&lt;/span&gt; generate_series(&lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;1000&lt;/span&gt;) i;

&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; For inner product or cosine, see Operator classes below.
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-create syntax-sql&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-create syntax-sql&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-other syntax-sql&quot;&gt;INDEX&lt;/span&gt; &lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-sql&quot;&gt;ON&lt;/span&gt;&lt;/span&gt; items USING prism (embedding vec32_l2_ops);

&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; 0 = auto (~0.95 recall). Raise for recall, lower for speed.
&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-other syntax-database-name syntax-sql&quot;&gt;prism&lt;/span&gt;.&lt;span class=&quot;syntax-constant syntax-other syntax-table-name syntax-sql&quot;&gt;nprobe&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-sql&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;40&lt;/span&gt;;

&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-star syntax-sql&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;FROM&lt;/span&gt; items
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;ORDER BY&lt;/span&gt; embedding &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-sql&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-math syntax-sql&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-sql&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-sql&quot;&gt;&amp;#39;&lt;/span&gt;[3,1,2]&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-sql&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;5&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use &lt;code&gt;vec16&lt;/code&gt; instead of &lt;code&gt;vec32&lt;/code&gt; to halve the space vectors take in the table, with the matching &lt;code&gt;vec16_*&lt;/code&gt; &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#operator-classes&quot;&gt;operator classes&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Existing pgvector tables&lt;/h3&gt;
&lt;p&gt;If you already have a table with pgvector&#39;s &lt;code&gt;vector&lt;/code&gt; or &lt;code&gt;halfvec&lt;/code&gt; columns, you can build a PRISM index on it directly. Nothing about the table or your queries needs to change. &lt;code&gt;vec32&lt;/code&gt; and &lt;code&gt;vec16&lt;/code&gt; are binary-compatible with pgvector&#39;s &lt;code&gt;vector&lt;/code&gt; and &lt;code&gt;halfvec&lt;/code&gt; but have different names, so the two extensions can be installed side by side, even in the same schema.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;SQL&quot;&gt;&lt;span class=&quot;syntax-source syntax-sql&quot;&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; The table you already have, included so the example runs on its own.
&lt;/span&gt;CREATE EXTENSION vector;

&lt;span class=&quot;syntax-meta syntax-create syntax-sql&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-create syntax-sql&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-other syntax-sql&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-sql&quot;&gt;documents&lt;/span&gt;&lt;/span&gt; (
    id        &lt;span class=&quot;syntax-storage syntax-type syntax-sql&quot;&gt;bigserial&lt;/span&gt; &lt;span class=&quot;syntax-storage syntax-modifier syntax-sql&quot;&gt;PRIMARY KEY&lt;/span&gt;,
    body      &lt;span class=&quot;syntax-storage syntax-type syntax-sql&quot;&gt;text&lt;/span&gt;,
    embedding vector(&lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;384&lt;/span&gt;)
);
&lt;span class=&quot;syntax-meta syntax-create syntax-sql&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-create syntax-sql&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-other syntax-sql&quot;&gt;INDEX&lt;/span&gt; &lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-sql&quot;&gt;documents_embedding_hnsw&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;syntax-keyword syntax-other syntax-DDL syntax-create syntax-II syntax-sql&quot;&gt;ON&lt;/span&gt; documents USING hnsw (embedding vector_l2_ops);

&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; Install pg_vectorsearch next to pgvector and build the index on the
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; existing column. The column is not rewritten or copied.
&lt;/span&gt;CREATE EXTENSION pg_vectorsearch;

&lt;span class=&quot;syntax-meta syntax-create syntax-sql&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-create syntax-sql&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-other syntax-sql&quot;&gt;INDEX&lt;/span&gt; &lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-sql&quot;&gt;documents_embedding_prism&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;syntax-keyword syntax-other syntax-DDL syntax-create syntax-II syntax-sql&quot;&gt;ON&lt;/span&gt; documents USING prism (embedding vec32_l2_ops);

&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; Your queries keep working as before. PRISM is normally faster, so
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; the planner should prefer it over the HNSW index while both exist.
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; Verify with an EXPLAIN:
&lt;/span&gt;EXPLAIN (COSTS OFF)
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;SELECT&lt;/span&gt; id, body
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;FROM&lt;/span&gt; documents
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;ORDER BY&lt;/span&gt; embedding &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-sql&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-math syntax-sql&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-sql&quot;&gt;&amp;gt;&lt;/span&gt; (&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;SELECT&lt;/span&gt; embedding &lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;FROM&lt;/span&gt; documents &lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;WHERE&lt;/span&gt; id &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-sql&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;42&lt;/span&gt;)
&lt;span class=&quot;syntax-keyword syntax-other syntax-DML syntax-sql&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-sql&quot;&gt;10&lt;/span&gt;;
&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt;  Limit
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt;    InitPlan 1
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt;      -&amp;gt;  Index Scan using documents_pkey on documents documents_1
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt;            Index Cond: (id = 42)
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt;    -&amp;gt;  Index Scan using documents_embedding_prism on documents
&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt;          Order By: (embedding &amp;lt;-&amp;gt; (InitPlan 1).col1)
&lt;/span&gt;
&lt;span class=&quot;syntax-comment syntax-line syntax-double-dash syntax-sql&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-sql&quot;&gt;--&lt;/span&gt; Once you are happy with it, drop the HNSW index.
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-drop syntax-sql&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-create syntax-sql&quot;&gt;DROP&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-other syntax-sql&quot;&gt;INDEX&lt;/span&gt;&lt;/span&gt; documents_embedding_hnsw;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the PRISM &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch#operator-classes&quot;&gt;operator class&lt;/a&gt; for the same distance metric as your HNSW index.&lt;/p&gt;
&lt;h3&gt;Operator classes&lt;/h3&gt;
&lt;p&gt;Pick the operator class for your distance metric and column type. L2 is the default.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Distance&lt;/th&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;&lt;code&gt;vec32&lt;/code&gt; / &lt;code&gt;vector&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;vec16&lt;/code&gt; / &lt;code&gt;halfvec&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;L2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;-&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vec32_l2_ops&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vec16_l2_ops&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inner product&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;#&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vec32_ip_ops&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vec16_ip_ops&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cosine&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vec32_cosine_ops&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vec16_cosine_ops&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;When replacing an HNSW index, pgvector&#39;s &lt;code&gt;vector_&amp;lt;metric&amp;gt;_ops&lt;/code&gt; maps to &lt;code&gt;vec32_&amp;lt;metric&amp;gt;_ops&lt;/code&gt; and &lt;code&gt;halfvec_&amp;lt;metric&amp;gt;_ops&lt;/code&gt; to &lt;code&gt;vec16_&amp;lt;metric&amp;gt;_ops&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Tuning&lt;/h3&gt;
&lt;p&gt;Defaults are tuned from large-scale benchmarks; most deployments only ever adjust &lt;code&gt;prism.nprobe&lt;/code&gt;. See the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/tuning.md&quot;&gt;tuning guide&lt;/a&gt; for every index parameter and GUC, their tradeoffs, and when changing them makes sense.&lt;/p&gt;
&lt;h3&gt;Maintenance&lt;/h3&gt;
&lt;p&gt;An insert appends to whichever posting list its vector routes to, so lists grow as rows arrive and never split on their own. Besides &lt;code&gt;REINDEX&lt;/code&gt;, the &lt;code&gt;prism_rebalance&lt;/code&gt; procedure splits oversized lists in place. See the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/maintenance.md&quot;&gt;maintenance guide&lt;/a&gt; for how it works and its current limitations.&lt;/p&gt;
&lt;h2&gt;Building&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PostgreSQL 18+ (with development headers)&lt;/li&gt;
&lt;li&gt;GNU C11 compiler (GCC 11+ or Clang 14+)&lt;/li&gt;
&lt;li&gt;Meson build system&lt;/li&gt;
&lt;li&gt;Optional: CBLAS, for faster RaBitQ encoding. See &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/development.md#blas&quot;&gt;Development&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-number-sign syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-number-sign syntax-shell&quot;&gt; Release build&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-number-sign syntax-shell&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;meson&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; setup builddir&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; --&lt;/span&gt;buildtype&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell&quot;&gt;=&lt;/span&gt;release&lt;/span&gt;

&lt;span class=&quot;syntax-comment syntax-line syntax-number-sign syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-number-sign syntax-shell&quot;&gt; Build and install to PostgreSQL&lt;/span&gt;&lt;span class=&quot;syntax-comment syntax-line syntax-number-sign syntax-shell&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;meson&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; install&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;C&lt;/span&gt; builddir&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/development.md#build-options&quot;&gt;development guide&lt;/a&gt; for build options.&lt;/p&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/tuning.md&quot;&gt;Tuning&lt;/a&gt; - Index parameters, GUCs, tradeoffs, defaults&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/maintenance.md&quot;&gt;Maintenance&lt;/a&gt; - Rebalancing and splitting posting lists&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/architecture.md&quot;&gt;Architecture&lt;/a&gt; - High-level design and data structures&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/simd.md&quot;&gt;SIMD&lt;/a&gt; - SIMD build options and distance computation&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/docs/development.md&quot;&gt;Development&lt;/a&gt; - Build options, testing, CI scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;h3&gt;Research&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/gaoj0017/RaBitQ&quot;&gt;RaBitQ&lt;/a&gt; - Binary quantization with theoretical error bounds (SIGMOD 2024)&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://dl.acm.org/doi/10.1145/3600006.3613166&quot;&gt;SPFresh&lt;/a&gt; - LIRE protocol for incremental updates (SOSP 2023)&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.microsoft.com/en-us/research/wp-content/uploads/2021/11/SPANN_finalversion1.pdf&quot;&gt;SPANN&lt;/a&gt; - Billion-scale ANN with boundary replication (NeurIPS 2021)&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://services.google.com/fh/files/misc/scann_for_alloydb_whitepaper.pdf&quot;&gt;ScaNN for AlloyDB&lt;/a&gt; - Hierarchical clustering (Google)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Related Projects&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/pgvector/pgvector&quot;&gt;pgvector&lt;/a&gt; - Vector type and operators for PostgreSQL&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pgvectorscale&quot;&gt;pgvectorscale&lt;/a&gt; - DiskANN-based vector index for PostgreSQL&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;License&lt;/h2&gt;
&lt;p&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/timescale/pg_vectorsearch/blob/main/LICENSE&quot;&gt;The PostgreSQL License&lt;/a&gt;&lt;/p&gt;
</content:encoded>
    <category>news</category>
  </item>
</channel>
</rss>
