Back to Course

rails/learn

Databases in Production

Eight lessons on running Postgres under a Rails app. The first four build the foundations: reading query plans, the planner's statistics, indexing beyond btree, and the SQL constructs seniors reach for that mid-level devs rewrite in Ruby. The last four cover live operations: vacuum and bloat, transaction isolation, zero-downtime migrations, and read replicas.

Read the first two in order. The rest stand alone and can be taken in any order. If your app has a single database and a single server, focus on lessons 1 to 6. If you are running multiple environments, replicas, or larger volumes, lessons 7 and 8 are where seniors spend their time during incidents.

Lesson 1

Walkthrough

EXPLAIN ANALYZE for Rails developers

Reading query plans beyond "is it using the index?" Cost vs actual time, rows estimated vs actual, the grammar of plan nodes, and the one number seniors check first.

Lesson 2

Walkthrough

The planner and its statistics

Why a query goes from 5ms to 800ms after a release without the SQL changing. Stats freshness, ANALYZE, pg_stat_user_tables, and the slow-query log. Where to look first.

Lesson 3

Walkthrough

Indexing beyond btree

Partial indexes, expression indexes, GIN/GIST for JSONB and full-text, BRIN for time-series, covering indexes with INCLUDE. When each is the right tool and when an extra index hurts.

Lesson 4

Walkthrough

Window functions and CTEs without the foot-gun

Running totals, top-N per group, gap detection, deduplication. Replacing 50 lines of Ruby with 4 lines of SQL. CTE materialization changes in PG12+ and when they bite.

Lesson 5

Walkthrough

MVCC, vacuum, and bloat

What UPDATE actually does. Why a 10GB table can hold 200MB of live data. When autovacuum is enough, when to intervene, and the VACUUM FULL vs pg_repack call.

Lesson 6

Walkthrough

Transaction isolation and locking

Read committed's lost-update problem, when SELECT FOR UPDATE is correct, advisory locks, reading pg_locks during an incident, and Rails's with_lock semantics.

Lesson 7

Walkthrough

Zero-downtime migrations

Add column with default in two steps. Add index concurrently. Rename column via shadow column. The patterns strong_migrations enforces and the table-size reflex.

Lesson 8

Walkthrough

Read replicas and multi-DB in Rails

When replicas help, when they do not, what replication lag breaks, Rails 6+ multi-database role API. Includes the "we added a replica and the app got slower" failure mode.

← Back to Course rails/learn · Databases in Production · 8 lessons