Tutorials
Practical tutorials for the work we actually do. Pick one, read it in order, and apply it.
Index only the rows that queries ask for, compare the size with a full index, and enforce a unique rule for active rows. After this, you know why a prepared statement can ignore a partial index, and how to avoid it.
Add a GIN index to a JSONB column, filter with the contains operator, and compare it with an expression index and jsonb_path_ops. After this, you can tell which JSONB filters use an index and which scan the table.
Read pg_stat_user_indexes to find indexes that were never scanned, find identical indexes in pg_index, and drop them with DROP INDEX CONCURRENTLY. After this, you can remove indexes that cost writes and give nothing back.
Reproduce a deadlock between two money transfers, read the message, and fix it by locking rows in the same order. After this, you can turn a deadlock detected error into a plain wait.
Let two workers take different jobs from one table with FOR UPDATE SKIP LOCKED, and see what happens to a job when a worker fails. After this, you can use a plain table as a safe queue.
Add a NOT NULL column to a big table with a constant default, or with a nullable column, a batch backfill, NOT VALID and VALIDATE. After this, you can tell a quick change from a table rewrite and avoid long locks.
Walk down an employee tree, walk up to the top, count each manager's team and guard the query against a loop with CYCLE. After this, you can query a parent-child table of any depth.
Take a pg_dump backup in Docker, restore it into a scratch database, compare the tables and see what a damaged backup looks like. After this, you have a short routine that proves your backup works.
Add a BuildKit cache mount to pip install so a changed requirements file downloads only the new packages. After this, a dependency change no longer means downloading everything again.
Build a Go service in a multi-stage Dockerfile and ship it in an image well under 50 MB, with a non-root user and a health check. After this, you know why Go gets that small and Node does not.
Add a user to an image, give it only the folder it writes to, and fix the two permission errors you will most likely hit. After this, your containers stop running as root.
Look up a base image digest, pin it in the FROM line, check the build used it and plan how to update it. After this, your builds are repeatable without missing security fixes.