The vvek blog
Databases, programming, AI and how teams get work done, written by the people building vvek.

Code review that helps: approve what improves the code, save the nitpicks for later
A practical code review standard for reviewers and authors: improve code health steadily, separate facts from taste, label nits and settle disagreements.

Rate limits from both sides: handling 429 responses and limiting your own API
What a 429 means, how to retry with backoff and jitter, how to smooth traffic with a token bucket, and what to tell clients when you limit them.

SQL window functions: per-group answers without losing your rows
A practical guide to Postgres window functions: OVER, PARTITION BY, ORDER BY, running totals, top-N per group and reusable WINDOW definitions.

A job queue in Postgres: how FOR UPDATE SKIP LOCKED lets workers share a table
Build a simple, safe job queue on Postgres: claiming rows with SKIP LOCKED, handling crashes with leases, retries, and the limits of the approach.

The transactional outbox: saving data and sending a message without losing either
How the outbox pattern keeps a database write and its message in step, why duplicates still happen, and how to build a small version on Postgres.

Blameless postmortems: how to learn from an incident without pointing fingers
When to write a postmortem, what goes in it, and how to keep it blameless so people report problems early. Practical notes based on Google's SRE book.

Trace sampling with OpenTelemetry: head or tail, and what each one costs you
Keeping every trace gets expensive. How head and tail sampling differ in OpenTelemetry, when to combine them, and when not to sample at all.

Evals for AI agents: start with twenty tasks, grade the outcome
How to test an AI agent before users do: tasks, trials, graders, pass@k versus pass^k, and a first eval set you can build in an afternoon.

Prompt caching for LLM apps: put the stable parts first and watch the usage fields
How prompt caching works, how to order a prompt so it hits, what breaks the cache, and how to verify savings from the usage fields.

Python 3.15 for working developers: lazy imports, a sampling profiler and UTF-8 by default
A practical look at Python 3.15: the lazy keyword, the Tachyon profiler, UTF-8 as the default encoding, frozendict and unpacking in comprehensions.

Kubernetes probes: what liveness, readiness and startup checks should (and should not) test
A practical guide to Kubernetes liveness, readiness and startup probes: what each one does, sensible settings, and the dependency-check mistake to avoid.

Connection pooling for Postgres: what PgBouncer's pool modes change
Why Postgres needs a pooler, how PgBouncer's session, transaction and statement modes differ, and which features stop working in transaction mode.

Schema changes without downtime in Postgres: locks, NOT VALID and safer migrations
Which ALTER TABLE changes block your app, and how NOT VALID, VALIDATE CONSTRAINT and a lock timeout let you change a live Postgres table safely.

Architecture decision records: write down why, not only what
A short, practical guide to architecture decision records: what to put in one, when to write it, and how a decision log saves your team repeated debates.

Giving an AI agent only the access it needs: a least-privilege checklist
Most agent mishaps come from too many tools, too many permissions or too much autonomy. A practical checklist for narrowing all three, based on OWASP guidance.

Go 1.27 in practice: generic methods, goroutine leak profiles and a UUID package
A working developer's tour of the Go 1.27 release notes: generic methods, the goroutineleak profile, a standard uuid package, json v2 and go fix updates.

Reading EXPLAIN ANALYZE: a practical guide to Postgres query plans
How to read EXPLAIN ANALYZE output in Postgres: costs, row estimates, scan types, buffers, and the habits that keep it safe to run.

PostgreSQL 19 release candidate: what to look at before the final release
A tour of the PostgreSQL 19 release notes: REPACK, parallel autovacuum, automatic I/O workers, sequence replication and the migration items to check.

MCP goes stateless: what the 2026-07-28 revision changes for server authors
The newest Model Context Protocol revision drops sessions and the initialize handshake. Here is what that means if you run or build an MCP server.

Row-level security in Postgres: a practical guide to isolating tenants
How Postgres row-level security works, the traps that catch people, and a small tenant isolation pattern you can try today.

Idempotency keys: making retries safe in any API
Networks fail halfway. Idempotency keys, backoff and jitter let clients retry without charging, creating or sending twice.

Workflow or agent? Choosing the simplest design that does the job
Fixed workflows and autonomous agents suit different tasks. Five workflow patterns, tool design tips and a way to decide which one you need.

How database indexes speed up reads, and when they slow down writes
Learn when to use indexes for faster queries and when they hurt write performance.
Introducing vvek: hire AI agents like employees
A Manager agent that plans and hires, agents that work in chat beside your people, and you in charge of anything risky.
Why every agent gets its own virtual machine
Agents that run code and browse the web need real computers. Here is how we give them one without risking yours.