What Is FAISS? β Definition and How It Works
Learn what FAISS is, which index types it offers, and why it is a library rather than a database.
FAISS is a library for similarity search over dense vectors. It is not a database β it is an in-process index you build, query, and persist yourself.
1. Library, Not Database
This distinction determines whether FAISS fits. It gives you an index; everything around it is yours to build.
| Concern | FAISS provides |
|---|---|
| Similarity search | Yes, and very fast |
| Index persistence | Save and load to a file |
| Metadata storage | No β you keep your own mapping |
| Filtering | No β filter before or after yourself |
| Updates and deletes | Limited, index-type dependent |
| Network API | No β it runs in your process |
| Replication, sharding | No |
So the usual pattern is FAISS for vectors plus a real database for the payload, joined on an integer id you manage.
2. Basic Use
import faiss, numpy as np
dim = 1536
vectors = np.asarray(embeddings, dtype="float32")
faiss.normalize_L2(vectors) # cosine via inner product
index = faiss.IndexFlatIP(dim) # exact search
index.add(vectors)
q = np.asarray([query_embedding], dtype="float32")
faiss.normalize_L2(q)
scores, ids = index.search(q, 10) # ids are row positions
The returned ids are positions in insertion order, not your own identifiers. Keeping a parallel list mapping position to record id is mandatory, and losing that mapping makes the index useless β which is why IndexIDMap exists:
index = faiss.IndexIDMap(faiss.IndexFlatIP(dim))
index.add_with_ids(vectors, np.asarray(record_ids, dtype="int64"))
3. The Index Types
| Index | Character |
|---|---|
IndexFlatIP / IndexFlatL2 |
Exact, no training, memory = vectors |
IndexHNSWFlat |
Graph-based ANN, fast, memory-hungry |
IndexIVFFlat |
Clustered ANN, needs training, tune nprobe |
IndexIVFPQ |
Clustered + quantised, very compact, lossy |
IndexScalarQuantizer |
8-bit compression, modest loss |
Start with IndexFlat. It is exact, needs no training, and on a few hundred thousand vectors it is fast enough that the complexity of an ANN index buys nothing.
4. Training Is Required for Some Types
IVF and PQ indexes learn from the data distribution before they can accept vectors:
index = faiss.IndexIVFFlat(faiss.IndexFlatIP(dim), dim, 256, faiss.METRIC_INNER_PRODUCT)
index.train(vectors) # must happen first, on a representative sample
index.add(vectors)
index.nprobe = 16 # candidates searched; raise for recall
Two failure modes here. Adding before training raises. And training on an unrepresentative sample gives poor clusters, which degrades recall permanently until retrained β so train on the real distribution, not the first thousand rows.
5. Persistence and Rebuilds
faiss.write_index(index, "chunks.faiss")
index = faiss.read_index("chunks.faiss")
Save the id mapping alongside it, in the same commit or the same directory. An index file without its mapping is unrecoverable.
Deletes are weakly supported β remove_ids works on some index types and not others. For a corpus that churns, periodic full rebuilds are simpler and more predictable than incremental deletion.
6. FAISS Versus a Vector Database
Choose FAISS when the index fits in one process, the data is mostly static, you already have a database for the payload, and you want no extra infrastructure. It is excellent for a batch pipeline or a single-node service.
Choose a vector database when you need filtered search as a first-class feature, concurrent writes, replication, multiple clients over a network, or metadata living beside the vectors.
Choose pgvector when you already run Postgres and want SQL filtering with the vectors β that combination removes the id-mapping problem entirely.
7. GPU Support
FAISS has GPU index variants that are dramatically faster for large batch searches, which matters for offline work: deduplicating a large corpus, or scoring every document against every other.
For interactive single-query search the CPU indexes are usually already fast enough, and the GPU adds operational cost for little gain.
8. Summary
FAISS is an in-process similarity-search library with exact and approximate index types, not a database β it stores no metadata, offers no filtering, and exposes no network API.
Start with an exact IndexFlat index, use IndexIDMap so results carry your own identifiers, train IVF/PQ indexes on a representative sample, persist the id mapping alongside the index file, and plan rebuilds rather than relying on deletes.