Postgres as a Platform: Queues, Search, and Vectors Without Extra Infra
Before you add three new services to your architecture diagram, check whether the database you already run does the job.
The most underrated architecture decision of the decade: doing less. Postgres has quietly absorbed half the data infrastructure category, and most teams have not noticed because the marketing budget for "just use the database you already run" is zero. Before your next architecture review adds a queue, a search cluster, and a vector store to the diagram, here is what the boring option covers — and exactly where it stops.
1. Job queues with SKIP LOCKED
A worker queue in fifteen lines of SQL, with the exactly-once processing semantics your Redis setup never actually had. FOR UPDATE SKIP LOCKED lets any number of workers pull jobs concurrently without stepping on each other, and because the queue lives in the same database as your application data, enqueueing a job and committing the business change that caused it happen in one transaction. No outbox pattern, no dual-write bug, no reconciliation job to write later.
DELETE FROM queue
WHERE id = (
SELECT id FROM queue
ORDER BY created_at
FOR UPDATE SKIP LOCKED
LIMIT 1
)
RETURNING payload;The operational story is the part teams underrate: your queue now has backups, point-in-time recovery, and monitoring for free, because it is just a table. When a job misbehaves, you debug it with SELECT, not with a vendor dashboard.
2. Full-text search that is good enough
tsvector with a GIN index covers the search needs of most products: stemming, ranking, highlighting, multiple languages. You are not Google, and your forty thousand documents do not need a cluster with its own on-call rotation. The honest limitation is relevance tuning — Postgres gives you knobs, not machine-learned ranking. For a docs site, a product catalog, or an admin panel, nobody will ever notice.
SELECT title, ts_rank(search, query) AS rank
FROM posts, websearch_to_tsquery('english', 'edge rendering') query
WHERE search @@ query
ORDER BY rank DESC
LIMIT 10;3. Vectors next door to your data
pgvector puts embeddings in the same transaction as the rows they describe. When a document updates, its embedding updates in the same commit — no sync pipeline, no consistency drift between your database and your vector store, one backup story instead of two. With HNSW indexes, single-digit-millisecond similarity search holds comfortably into the millions of embeddings, which is more than most products will ever store.
The uncomfortable part: connection limits and vacuum
Postgres-as-a-platform has two failure modes worth respecting. High-churn tables — which is what a busy queue is — demand autovacuum tuning, or dead tuples will quietly degrade the very query keeping your workers fed. And every worker, cron job, and serverless function now wants a connection to the same database, so a pooler in front stops being optional. Neither issue is exotic; both have bitten teams that treated the database as infinitely elastic.
When to reach for real infra
| Workload | Stay in Postgres until | Then move to |
|---|---|---|
| Job queue | ~1,000 jobs/sec sustained | Dedicated broker |
| Full-text search | ~1M documents or relevance tuning needs | Search engine |
| Vector search | ~10M embeddings or heavy filtering | Dedicated vector store |
Past those lines, specialize without guilt — the migration is easier precisely because the workload is already well-defined in SQL. Before them, enjoy the architecture diagram that fits on a napkin, the single backup strategy, and the on-call rotation that only has one system to page you about.
Unlock Exclusive Tech & Creator Insights
Join thousands of readers. Get our latest deep-dives, guides, and tech analysis delivered straight to your inbox.
Discusión de los miembros
0 comentariosComienza la conversación
Hazte miembro de Vanta Tech & Creator para poder comentar.