Connect PostgreSQL
A cluster in remote mode talks to postvec-server. It needs two endpoint lists: gRPC for inference, HTTP for discovery. The database host installs the extension and the CLI. Engine assets go on postvec-server.
1. Install on the database host
sudo apt install ./postvec-cli_*.deb ./postgresql-18-postvec_*.debThe engine-asset packages (postvec-onnxruntime, postvec-model-minilm-l6-v2) go on the node. Full download and verification steps: packages.
2. Point the cluster at the node
sudo postvec setup --database app \
--grpc 10.0.0.20:33333 \
--http https://10.0.0.20:22222That writes conf.d/99-postvec.conf, merges shared_preload_libraries, creates the extension and restarts. The three settings it records are:
postvec.mode = grpc
postvec.grpc_endpoints = '10.0.0.20:33333'
postvec.http_endpoints = 'https://10.0.0.20:22222'With several nodes, give the cluster all of them as comma-separated lists. postvec round-robins the gRPC list itself:
sudo postvec setup --database app \
--grpc 10.0.0.20:33333,10.0.0.21:33333,10.0.0.22:33333 \
--http https://10.0.0.20:22222,https://10.0.0.21:22222,https://10.0.0.22:22222--allow-unreachable stages the configuration before a node exists. The worker starts. Inference waits until a node answers.
3. Models
SELECT name, model_type, target_dim FROM postvec.models ORDER BY name;An empty result means the worker has not refreshed the model cache yet, or the node serves nothing. The worker refreshes on the postvec.model_refresh_interval_ms cadence (60 s by default). postvec.refresh_models() forces a refresh now and is revoked from PUBLIC: grant EXECUTE on it to the calling role, or run it as a superuser.
Optional
sudo postvec doctor --database app --deepremote.grpc.connect, remote.http.health and remote.http.config report the pairing. If those fail: the node's /ready, the gRPC port through a firewall, then whether the HTTP endpoint matches the scheme the node serves (https unless --insecure). Verify artifacts.
4. SQL
SQL is unchanged:
SELECT postvec.enable('docs', 'body', model => 'baai-bge-m3');The model name must be one the node serves. postvec.models is the list.
Containers
The image reads the same two endpoint lists from the environment. Quick start remote starts both containers on one network, already pointed at each other.
docker run -d --name postvec \
-e POSTGRES_PASSWORD=demo \
-e POSTGRES_DB=app \
-e POSTVEC_GRPC_ENDPOINTS=10.0.0.20:33333 \
-e POSTVEC_HTTP_ENDPOINTS=https://10.0.0.20:22222 \
-v postvec-data:/var/lib/postgresql \
-p 127.0.0.1:5432:5432 \
ghcr.io/univec-ai/postvec:0.5.0-2-pg18-remoteThe base tag pins POSTVEC_MODE=grpc and carries no engine assets, so it is the right image for remote mode. Docker has the volume paths and the full environment table.
Switching an existing cluster
Mode is cluster-wide, so switching needs a restart, the --switch-mode flag and every configured database named in one command:
sudo postvec setup --database app --database analytics \
--grpc 10.0.0.20:33333 \
--http https://10.0.0.20:22222 \
--switch-modeStored vectors are unaffected by the switch. A column keeps its model name and its dimension, so the node has to serve that model or the column has no embedding route. List what the cluster needs before switching:
SELECT DISTINCT model FROM postvec.status();