Railway pgvector Runtime
Railway’s standard PostgreSQL service image does not include pgvector. Railway’s docs direct teams to use a pgvector-capable template or custom database image when an extension is not available in the standard Postgres image:
- https://docs.railway.com/databases/postgresql
- https://docs.railway.com/databases/database-view
- https://docs.railway.com/guides/rag-pipeline-pgvector
The platform expects PostgreSQL 16 plus pgvector for vector-backed candidate embedding search. The local Docker runtime is pgvector/pgvector:pg16 to match that requirement. Candidate semantic search currently stores durable vectors in CandidateProfileEmbedding.vectorJson and uses the pgvector column only as a rebuildable acceleration path for provider embeddings at 768 dimensions, including Gemini gemini-embedding-2 and Ollama nomic-embed-text.
Safe Runtime Change
Section titled “Safe Runtime Change”Do not delete the Railway database volume, reset the database, or recreate rows manually.
-
Confirm the current Railway database major version is PostgreSQL 16. If it is not PostgreSQL 16, take a Railway backup/snapshot and use a normal PostgreSQL backup/restore or major-version upgrade path instead of reusing the volume directly.
-
Capture a Railway backup or snapshot and keep it until the application is healthy after deployment.
-
Capture a data baseline against the existing Railway database:
Terminal window DATABASE_URL="$RAILWAY_DATABASE_URL" pnpm --filter @repo/database validate:pgvector -- --mode=baseline --output=railway-pgvector-baseline.json -
Change the Railway database service source to a pgvector-capable PostgreSQL 16 runtime, preferably
pgvector/pgvector:pg16or the Railway-supported pgvector template equivalent. Keep the existing volume mounted at/var/lib/postgresql/data. -
Redeploy the database service and wait for it to accept connections.
-
Enable and verify pgvector while comparing existing data to the baseline:
Terminal window DATABASE_URL="$RAILWAY_DATABASE_URL" pnpm --filter @repo/database validate:pgvector -- --mode=post-change --compare=railway-pgvector-baseline.json --output=railway-pgvector-post-change.json -
Run deploy migrations:
Terminal window DATABASE_URL="$RAILWAY_DATABASE_URL" pnpm run db:migrate -
Smoke-test API reads for existing candidates and job postings before removing the backup/snapshot.
Railway Gemini Embeddings
Section titled “Railway Gemini Embeddings”Use the existing API GOOGLE_GENAI_API_KEY for Gemini embeddings. Configure staging first:
GOOGLE_GENAI_API_KEY=<google-genai-api-key>EMBEDDING_PROVIDER=geminiEMBEDDING_MODEL=gemini-embedding-2EMBEDDING_DIMENSIONS=768Deploy the API/config update, then regenerate existing Pool candidate embeddings in Railway:
railway ssh --service api --environment prod -- pnpm --filter api candidate-embeddings:backfillRun the same sequence in staging before production. Existing candidate embeddings from another provider are not comparable with Gemini embeddings, so the backfill must complete before judging suggestion quality.
Railway Ollama Embeddings
Section titled “Railway Ollama Embeddings”Run Ollama as a separate Railway service rather than inside the API container.
-
Add an
ollamaservice in the same Railway project and environment as the API. -
Configure the service to run Ollama on port
11434with persistent storage for pulled models. -
Pull
nomic-embed-textbefore enabling the API provider, for example from a Railway shell on the Ollama service:Terminal window ollama pull nomic-embed-text -
Confirm the API service can reach the private Railway service URL from inside Railway networking.
-
Configure optional API variables in staging first:
Terminal window EMBEDDING_PROVIDER=ollamaEMBEDDING_MODEL=nomic-embed-textEMBEDDING_DIMENSIONS=768OLLAMA_BASE_URL=http://ollama.railway.internal:11434Use the actual private Railway DNS name if it differs.
-
Deploy the API and database migrations, then regenerate embeddings:
Terminal window railway ssh --service api --environment prod -- pnpm --filter api candidate-embeddings:backfill
Run the same sequence in staging before production. For production, take a Railway Postgres backup or snapshot before the pgvector dimension migration, keep it through API health checks, candidate reads, job-posting reads, and suggestion refresh verification, then remove it only after the rollout is stable.
Validation Evidence
Section titled “Validation Evidence”The validation report records:
- PostgreSQL server version and current schema.
- Whether
CREATE EXTENSION IF NOT EXISTS vectorsucceeded. - Whether
pg_extensioncontainsvector. - Row counts for critical platform tables.
- A full-table checksum for each critical table.
- Five sampled primary keys per table.
For the runtime change to pass, the post-change report must show vectorExtension.enabled: true, no comparison mismatches, and unchanged row counts/checksums for the baseline tables.