Production-ready starter template for PostgreSQL + pgvector + Redis — the standard stack for AI-powered applications.
Built by polyglotstack.dev — the definitive resource for polyglot persistence.
- PostgreSQL + pgvector — vector storage and similarity search built into your existing database
- Redis — embedding cache and search result cache to reduce OpenAI API costs
- Docker Compose — one command to start everything locally
- Embedding helpers —
getEmbedding,indexDocument,similaritySearch - Cache-aside pattern — embeddings cached in Redis for 24 hours
- Express API — ready-to-use routes for indexing and searching documents
Use PostgreSQL + pgvector + Redis when:
- You're building a RAG (Retrieval Augmented Generation) application
- You need semantic search — find content by meaning, not just keywords
- You're building AI-powered recommendations
- You want to reduce OpenAI embedding API costs with caching
1. Clone the repo
git clone https://github.com/polyglotstack-dev/postgres-vector-starter.git
cd postgres-vector-starter2. Install dependencies
npm install3. Set up environment
cp .env.example .env
# Add your OPENAI_API_KEY to .env4. Start the databases
docker compose up -d5. Run the app
npm run devVisit http://localhost:3000/health — you should see PostgreSQL, pgvector, and Redis all connected.
Index a document:
curl -X POST http://localhost:3000/api/documents \
-H "Content-Type: application/json" \
-d '{"title": "My Document", "content": "This is the content to embed and search"}'Semantic search:
curl "http://localhost:3000/api/search?q=your+search+query"├── src/
│ ├── db/
│ │ ├── postgres.js # Connection pool + query helper
│ │ └── init.sql # Schema with pgvector setup
│ ├── cache/
│ │ └── redis.js # Redis client + cache helpers
│ ├── embeddings/
│ │ └── embed.js # OpenAI embeddings + similarity search
│ ├── routes/
│ │ └── search.js # API routes
│ └── index.js # Express app
├── docker-compose.yml # PostgreSQL (pgvector) + Redis
├── .env.example
└── README.md
const { similaritySearch } = require('./embeddings/embed');
// Find the 5 most semantically similar documents
const results = await similaritySearch('how does caching work', 5);
// results[0] = { title, content, similarity: 0.94 }Every embedding is cached in Redis for 24 hours using the MD5 hash of the text as the key. If the same text is embedded again, Redis returns the cached vector instantly — no OpenAI API call needed.
const { getEmbedding } = require('./embeddings/embed');
// First call — hits OpenAI API (~200ms)
const embedding = await getEmbedding('some text');
// Second call — hits Redis cache (~1ms)
const embedding2 = await getEmbedding('some text');| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
Yes | Your OpenAI API key |
POSTGRES_HOST |
No | Default: localhost |
POSTGRES_PORT |
No | Default: 5432 |
POSTGRES_DB |
No | Default: myapp |
POSTGRES_USER |
No | Default: postgres |
POSTGRES_PASSWORD |
No | Default: postgres |
REDIS_HOST |
No | Default: localhost |
REDIS_PORT |
No | Default: 6379 |
postgres-redis-starter— PostgreSQL + Redis for standard web appsmongo-elasticsearch-starter— MongoDB + Elasticsearch for search-heavy apps
Full guides and architecture explanations at polyglotstack.dev/guides.
MIT