Skip to content
Notifications
Clear all

Has anyone tried using LlamaIndex with Supabase Vector DB?

4 Posts
4 Users
0 Reactions
1 Views
(@ci_cd_plumber_99)
Estimable Member
Joined: 4 months ago
Posts: 112
Topic starter   [#7941]

Alright, let's get this started because I've wasted a weekend on this and you shouldn't have to. I'm evaluating LlamaIndex for a new RAG pipeline, aiming to replace a clunky, multi-stage Jenkins monstrosity that takes 45 minutes just to generate embeddings. The idea was simple: use Supabase's built-in vector DB (which is just pgvector under the hood) to keep things in one place and hopefully make the CI/CD for our doc updates less of a crawl.

Here's the blunt review after hacking through it: it *works*, but the path is littered with sharp edges and outdated documentation. The `SupabaseVectorStore` is functional for basic operations, but you're going to hit friction points if you need anything beyond the trivial "ingest and query."

My main gripes, in no particular order:

* **Connection Pooling & Performance:** The official integration examples often show a new client instantiated per operation. In a pipeline step processing hundreds of documents, that's a one-way ticket to connection limit town. You need to manage the Supabase client lifecycle yourself.
* **Metadata Handling:** Supabase stores metadata as JSONB, which is fine. However, I've seen inconsistencies with nested filters when using the `VectorStoreIndex` abstraction. You often fall back to writing raw SQL queries via the client, which defeats the purpose of using the LlamaIndex abstractions in the first place.
* **Incremental Updates:** This was the big one for me. Our docs repo gets minor updates constantly. The process for updating only *changed* embeddings, without a full rebuild, required a custom script. The built-in tooling isn't pipeline-friendly. You'll be writing more orchestration code than you'd like.

Here's a snippet of the least-worst way I found to get a batch ingestion working reliably in a GitHub Actions step, after the poetry installs and whatnot:

```python
from llama_index.vector_stores.supabase import SupabaseVectorStore
import os

# Initialize the store directly, not through the high-level wrapper
supabase_client = supabase.create_client(
os.environ["SUPABASE_URL"],
os.environ["SUPABASE_SERVICE_KEY"]
)

vector_store = SupabaseVectorStore(
supabase_client=supabase_client,
table_name=os.environ.get("TABLE_NAME", "documents"),
embedding_dimension=1536 # Match your embedding model
)

# Build your index from documents
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
show_progress=True # At least you get a progress bar
)
```

The real trick is what you do *after* this. For any non-toy implementation, you'll need to:
* Implement a checksum or last-modified check on your source documents to skip unchanged ones.
* Handle deletes from the source in your vector DB (a manual `delete()` query).
* Monitor your Supabase compute time, as bulk inserts/upserts can spike CPU.

In the end, it got the job done and the pipeline now runs in under 10 minutes, but the "batteries-included" feeling wasn't there. If your use case is simple, go for it. If you have dynamic data and need robust, incremental pipeline steps, be prepared to get your hands dirty and write the glue code yourself.

So, has anyone else been down this road? Did you find a cleaner way to handle incremental syncs, or did you just accept the full-rebuild tax? I'm especially interested in how you might have integrated the update logic into a GitOps-style workflow.

fix the pipe


Speed up your build


   
Quote
(@data_pipeline_guy)
Estimable Member
Joined: 4 months ago
Posts: 107
 

45 minutes to generate embeddings in Jenkins? That's a process problem, not a tool problem. The vector DB is just the storage layer.

Connection pooling is a basic ops concern. If you're hitting limits, you're probably letting LlamaIndex manage the client instead of building a proper service layer. Seen it a dozen times. The hype pushes quickstart scripts, not production patterns.

Metadata as JSONB is fine until you need to index it or join it. Then you're back in SQL land anyway, so why abstract it through another framework's leaky wrapper?


SQL is enough


   
ReplyQuote
(@evanj)
Estimable Member
Joined: 1 week ago
Posts: 56
 

I just hit the exact same metadata inconsistency you mentioned while building a test pipeline. It felt like a coin toss whether a nested field would be queryable later, especially after a batch upsert.

Did you find any pattern to it, or did you end up flattening your metadata structure as a workaround? I was trying to store document sections with subsection IDs, and it became a mess pretty quickly.



   
ReplyQuote
(@juliam)
Trusted Member
Joined: 1 week ago
Posts: 36
 

Yeah, the nested metadata was a total headache for me too. I ended up flattening everything into top-level keys like `document_section_id` and `subsection_id`. It felt like a step backwards, but at least the queries worked predictably.

I think the inconsistency might happen when the automatic JSON schema inference in pgvector gets confused by nested arrays or nulls? I never got a clear answer from the docs.

Has anyone tried using a separate `metadata_json` column just for the nested stuff and keeping the queryable fields flat? Seems messy, but maybe it's the only way right now.



   
ReplyQuote