Deskbell

Vector store

Choose where Deskbell keeps its search index, pgvector inside Postgres by default or a Weaviate cluster you already run, and how to move between them.

Deskbell stores each chunk's vector in exactly one place: the vector store you configure. DESKBELL_VECTOR_STORE selects it. Choose before you add your first source: changing it later means re-embedding everything (see Switch vector stores).

VariableDefaultDescription
DESKBELL_VECTOR_STOREpgvectorWhich store holds the chunk index. pgvector uses the Postgres database Deskbell already runs on; weaviate uses a Weaviate cluster you operate. Set the same value on the web app and the worker.

Whichever store you choose, Postgres keeps every chunk's text, position and state and records which store holds its vector. The pgvector extension stays installed on both drivers: gap clustering keeps its own embeddings in Postgres.

Backends

Switch vector stores

Vectors are not copied between stores. Switching re-embeds every chunk into the new one, with the embedding model you have configured.

Configure the new store

Set DESKBELL_VECTOR_STORE and the store's variables on the web app and the worker, then restart both. In Docker Compose that is .env plus docker compose up -d.

Re-embed

Open Sources. A notice reports how many chunks are still indexed in the previous store. Press Re-embed all content. The job reads every chunk's text from Postgres, embeds it and writes the configured store. It resumes after a restart; a second press is harmless.

Drop the old index

When the notice is gone, the previous index holds nothing Deskbell reads. Delete the Weaviate collection if you left Weaviate; if you left pgvector there is nothing to do, because each row's vector was cleared as it moved.

Warning: until the job finishes, retrieval searches the new store, which fills as chunks move; questions about content that has not moved yet are refused. Switch outside busy hours. The job costs embedding tokens for the whole corpus, cents to a few dollars at the sizes Deskbell indexes, with the default model.

Tested: pgvector → Weaviate and Weaviate → pgvector.

Check and repair

pnpm vector-store:prune [--org <id>] [--dry-run]

Compares a Weaviate collection with the chunk rows. Objects whose chunk no longer exists are deleted. Rows that claim an object the collection does not have (after a Weaviate restore from an older backup, for example) are reported; Re-embed on the Sources page repairs them. Safe to run at any time; it never writes to Postgres.

Run Weaviate locally

One container is enough to try the driver:

docker run -d --name weaviate -p 8080:8080 -p 50051:50051 \
  -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
  -e PERSISTENCE_DATA_PATH=/var/lib/weaviate \
  semitechnologies/weaviate:1.32.0

Set DESKBELL_VECTOR_STORE=weaviate and WEAVIATE_URL=http://localhost:8080 for pnpm dev and the worker, re-embed if the database already has content, and ask the widget something. The evaluation harness runs against whichever store is configured, which is how to confirm a switch changed nothing about answer quality.

How retrieval uses the store

The store answers one question: which chunks are nearest to this vector, and, in hybrid mode, which match these words. Deskbell then reads the winning rows from Postgres for titles, URLs and text, and cites them. Scores are cosine similarity on both drivers, so every threshold on the configuration page keeps its meaning whichever store you run.

On this page