To store embeddings in a vector database, choose an embedding model and note how many dimensions it outputs, create an index or collection with that dimension and a distance metric, split your documents into chunks, embed each chunk, then write the vectors with an ID and metadata. Query with a filter to check it works.
Storing embeddings sounds like a database chore, and mostly that holds. But two or three choices you make in the first hour decide whether search works well for years or quietly falls apart the day you change models. If you're new to the idea, my explainer on what a vector database does and why it exists covers the background; this page is the practical job.
Three decisions to settle before you write a single vector
Which embedding model, and how many dimensions it outputs
An embedding is a list of numbers that represents the meaning of a piece of text, so similar items sit close together when compared. Every model produces lists of a fixed length, called its dimensions. Write that number down. The database must match it exactly, and you'll type it into your collection or table definition in the next step.
Who makes the vectors: you, or the database
Some stores can create the embeddings for you. Others expect you to bring vectors from any model you like. Neither is wrong. Letting the database embed on import means less code, while embedding yourself keeps you free to move between stores. Decide early, because it changes how you write data.
Where the vectors live next to the rest of your data
If your app already runs on Postgres, keeping embeddings in an ordinary column beside your other records can be simpler than running a separate system. If search is the heart of the product, a dedicated vector store may suit you better. Size and stack decide this, not fashion.
The walkthrough: from a document to a searchable vector
- Record the model's output size. Note the dimensions of the embedding model you've picked. Chroma and Weaviate both work from the model you choose, and Weaviate can name a vectorizer in the collection definition so it embeds your data on import.
- Create the container. Make the index, collection or table with that dimension and a distance metric such as cosine. In Pinecone that's an index with a schema; in Qdrant it's a named collection; with Supabase it's a vector column on a normal table once the vector extension is enabled.
- Chunk and embed. Split your documents into chunks that make sense on their own, then embed each one. One embedding per chunk is what retrieval matches against, so a chunk that only makes sense alongside its neighbours will come back as a confusing answer.
- Write each vector with an ID and metadata. Store fields such as source, title and chunk number with every vector. Metadata lets you filter results and trace an answer back to where it came from. One managed store's own page notes that nested JSON and null values aren't supported in metadata, so keep the fields flat.
- Test with and without a filter. Run a query you know the answer to, once on its own and once with a metadata filter, and check the right chunks come back both times. It's the quickest check that the dimensions and the data are correct.
- Keep vectors in step with the text. Re-embed and re-write a chunk whenever its source text changes, and keep a record of which model made each vector. Stale or mixed vectors quietly degrade search, and you won't see an error when it happens.
Why a new embedding model means a fresh collection
Dimensions are fixed per collection. Qdrant's own collections documentation says every vector in a collection must have the same dimensionality and be compared by a single metric. Its answer for holding vectors of different sizes on one record is named vectors, where a single point carries several vectors, each with its own size.
The practical upshot is simple and often missed. Switching to an embedding model with a different output size isn't an in-place edit. It means creating a new collection and re-embedding your content. The pgvector docs show the same rule from the Postgres side: the number in the vector column definition has to match your model.
Even when a new model happens to share the old one's dimensions, mixing vectors from two models in one collection is a bad idea, because their numbers don't mean the same thing. That's why step six says to record which model made each vector. When you upgrade, you'll know exactly what needs re-embedding, and you can build the new collection alongside the old one, test it, then switch your app over.
Five places to keep your embeddings
Pinecone
A managed vector database that stores data in an index with a schema, with namespaces and metadata filtering. Its standout is integrated embedding, where the database creates the vectors for you, though you can still bring your own.
Qdrant
An open-source vector database that stores points, meaning vectors with a payload, in named collections searched by the distance metric you choose.
Weaviate
A vector database where the collection definition can name a vectorizer module, so your data is embedded on import. Generative modules are set in the same definition.
Chroma
An open-source embedding store that starts with everything built in. You store embeddings with metadata, search with dense and sparse vectors, filter by metadata and use any embedding model.
Want AI doing the heavy lifting in your marketing?
I build the systems that handle the boring 80 percent, so you get your week back. Done properly, with the human kept in.
Supabase (pgvector)
Postgres with vectors: enable the vector extension, add a vector column to a normal table, and your embeddings live next to the rest of your data in an ordinary column.
If you want to compare more options, including hosting and scale, my roundup of the vector databases worth considering goes wider than the five here.
Verdict: write down which model made every vector
Pick the store that fits the stack you already run, not the one with the loudest launch. Then do the boring thing that saves you later: tag every vector with its source, its chunk number and the model that made it. When you change models, and you will, that record turns a scary migration into a planned rebuild. Test with a known query after every load, filter on and off, and you'll catch a mismatch on day one instead of month six.
Want your tool on this list? Featured spots and reviews here are paid partnerships. Here's how to partner with me.
Frequently asked questions
What is an embedding?
A list of numbers that represents the meaning of a piece of text or other data, so similar items sit close together when compared.
Can I use Postgres as a vector database?
Yes. Supabase's docs describe pgvector, a Postgres extension for storing and querying vectors, enabled from the dashboard's extensions page.
Do I need to embed the data myself?
Not always. Some stores offer integrated embedding or a vectorizer module that embeds your data on import, while others work with vectors from any model you choose.
What metadata should I store with each vector?
Source, title and chunk number are a sensible starting set. Keep the fields flat, since one managed store's docs note nested JSON and null values aren't supported in metadata.
Which vector database should I choose?
It depends on your size and stack. If you already run Postgres, a vector column may be enough; if search is the core of your product, a dedicated store may suit you better.

