Hanzo Skills Reference
Hanzo Database - PostgreSQL, Redis & Vector Storage
Hanzo Database covers the PostgreSQL (with pgvector), Redis/Valkey, MongoDB, and Hanzo S3 configurations used across the Hanzo ecosystem — all running in-cluster on K8s, no managed database services.
Overview
Hanzo Database covers the PostgreSQL (with pgvector), Redis, MongoDB, and Hanzo S3 configurations used across the Hanzo ecosystem. All databases run in-cluster on K8s — no managed database services (DO Managed DB decommissioned Feb 2026).
Why In-Cluster?
- Cost: 5-10x cheaper than managed DBs at scale
- Latency: Same-cluster networking, no external hops
- Control: Full PostgreSQL config, extensions, versions
- Consistency: Same setup across all environments
When to use
- Configuring PostgreSQL for Hanzo services
- Setting up pgvector for AI embeddings
- Redis caching, sessions, and job queues
- MongoDB for document storage (Chat)
- Database troubleshooting and maintenance
Quick reference
| Database | Port | Image | Use Case |
|---|---|---|---|
| PostgreSQL | 5432 | postgres:16 | Primary RDBMS, pgvector |
| Redis | 6379 | redis:7-alpine | Cache, sessions, BullMQ queues |
| MongoDB | 27017 | mongo:7 | Document storage (Chat) |
| Hanzo S3 | 9000 | ghcr.io/hanzoai/s3 | S3-compatible object storage |
Production Layout
hanzo-k8s Cluster
| Service | Database | Host |
|---|---|---|
postgres.hanzo.svc | — | Shared PostgreSQL instance |
| ↳ | iam | Hanzo IAM (hanzo.id) |
| ↳ | cloud | Cloud dashboard |
| ↳ | console | Observability |
| ↳ | hanzo_cloud | Cloud API |
| ↳ | kms | KMS/Hanzo KMS |
| ↳ | platform | PaaS platform |
lux-k8s Cluster
| Service | Database | Host |
|---|---|---|
postgres.hanzo.svc | — | Shared PostgreSQL instance |
| ↳ | cloud | Lux Cloud |
| ↳ | commerce | Commerce API |
| ↳ | console | Console |
| ↳ | gateway | API Gateway |
| ↳ | hanzo | Core Hanzo |
| ↳ | kms | KMS |
PostgreSQL + pgvector
Setup
-- Enable pgvector extension
CREATE EXTENSION IF NOT EXISTS vector;
-- Create embeddings table
CREATE TABLE embeddings (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
embedding vector(1536), -- OpenAI ada-002 dimensions
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- IVFFlat index (fast approximate search)
CREATE INDEX ON embeddings
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
-- HNSW index (better recall, more memory)
CREATE INDEX ON embeddings
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);Similarity Search
-- Cosine similarity (most common for embeddings)
SELECT content, 1 - (embedding <=> $1::vector) AS similarity
FROM embeddings
ORDER BY embedding <=> $1::vector
LIMIT 5;
-- L2 distance
SELECT content, embedding <-> $1::vector AS distance
FROM embeddings
ORDER BY embedding <-> $1::vector
LIMIT 5;
-- Inner product
SELECT content, embedding <#> $1::vector AS score
FROM embeddings
ORDER BY embedding <#> $1::vector
LIMIT 5;
-- With metadata filter
SELECT content, 1 - (embedding <=> $1::vector) AS similarity
FROM embeddings
WHERE metadata->>'source' = 'docs'
ORDER BY embedding <=> $1::vector
LIMIT 5;Python pgvector Usage
import psycopg2
from pgvector.psycopg2 import register_vector
import numpy as np
conn = psycopg2.connect(os.environ["DATABASE_URL"])
register_vector(conn)
cur = conn.cursor()
# Insert embedding
embedding = np.random.rand(1536).astype(np.float32) # Your actual embedding
cur.execute(
"INSERT INTO embeddings (content, embedding, metadata) VALUES (%s, %s, %s)",
("Hello world", embedding, '{"source": "docs"}')
)
# Similarity search
query_vec = np.random.rand(1536).astype(np.float32) # Your query embedding
cur.execute(
"SELECT content, 1 - (embedding <=> %s) AS similarity "
"FROM embeddings ORDER BY embedding <=> %s LIMIT 5",
(query_vec, query_vec)
)
for row in cur.fetchall():
print(f"{row[0]}: {row[1]:.3f}")
conn.commit()Go pgvector Usage
import (
"github.com/jackc/pgx/v5"
"github.com/pgvector/pgvector-go"
)
conn, _ := pgx.Connect(ctx, os.Getenv("DATABASE_URL"))
// Insert
embedding := pgvector.NewVector(floats)
conn.Exec(ctx,
"INSERT INTO embeddings (content, embedding) VALUES ($1, $2)",
"Hello world", embedding,
)
// Search
rows, _ := conn.Query(ctx,
"SELECT content, 1 - (embedding <=> $1) AS similarity "+
"FROM embeddings ORDER BY embedding <=> $1 LIMIT 5",
pgvector.NewVector(queryVec),
)Redis Patterns
# Connection
REDIS_URL=redis://redis.hanzo.svc:6379
# From K8s pod
redis-cli -h redis.hanzo.svcCommon Patterns
import redis
r = redis.from_url(os.environ["REDIS_URL"])
# Cache
r.setex("key", 3600, "value") # 1 hour TTL
value = r.get("key")
# Session
r.hset(f"session:{session_id}", mapping={"user_id": "123", "role": "admin"})
# Rate limiting
key = f"ratelimit:{user_id}:{minute}"
count = r.incr(key)
r.expire(key, 60)
if count > 100:
raise RateLimitExceeded()
# Job queue (BullMQ pattern)
r.xadd("jobs:inference", {"model": "zen-70b", "prompt": "Hello"})Local Development (compose.yml)
services:
postgres:
image: postgres:16
ports:
- "5432:5432"
environment:
POSTGRES_DB: hanzo
POSTGRES_USER: hanzo
POSTGRES_PASSWORD: "${DB_PASSWORD}"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
mongodb:
image: mongo:7
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: hanzo
MONGO_INITDB_ROOT_PASSWORD: "${MONGO_PASSWORD}"
volumes:
- mongo_data:/data/db
s3:
image: ghcr.io/hanzoai/s3:latest
ports:
- "9000:9000"
command: server -s3 -s3.port=9000 -s3.config=/etc/hanzo/s3.json -dir=/data
volumes:
- s3_data:/data
- ./s3.json:/etc/hanzo/s3.json:ro
volumes:
postgres_data:
redis_data:
mongo_data:
s3_data:Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Port conflict | Service already running | lsof -i :5432 && kill PID |
| Connection refused | DB not started | docker compose up -d postgres |
| pgvector not found | Extension not installed | CREATE EXTENSION vector; |
| Slow queries | Missing index | Add IVFFlat or HNSW index |
| OOM | Too many connections | Configure max_connections |
# Port conflicts
lsof -i :5432
# Full reset (destructive — loses all data)
docker compose down -v && docker system prune -a
# Connect to prod DB (from K8s pod)
kubectl exec -it postgres-0 -n hanzo -- psql -U hanzoRelated Skills
hanzo/hanzo-orm.md- Go ORM for database accesshanzo/hanzo-datastore.md- Vector database abstractionhanzo/hanzo-stack.md- Local stack with all DBshanzo/hanzo-kms.md- Secret management (DB credentials)
How is this guide?