Conversation
Postgres tuning on production lived in two files inside the pgdata Docker volume, neither in version control: shared_buffers=128MB pgdata/postgresql.conf (initdb default) statement_timeout=30s pgdata/postgresql.auto.conf (ALTER SYSTEM) log_autovacuum_min_duration=0 pgdata/postgresql.auto.conf (ALTER SYSTEM) A fresh environment built from the repo would not have reproduced production. Command-line `-c` outranks both postgresql.conf and postgresql.auto.conf, so declaring them here makes the repo the single source of truth. Memory settings are env-driven because compose.prod.yml is shared by production and staging, which are not the same size -- a hardcoded shared_buffers=2GB could stop postgres starting on a smaller box. Defaults are the stock PostgreSQL values, so any environment that sets nothing behaves exactly as it does today. Production sets the tuned values in its .env. statement_timeout and log_autovacuum_min_duration are not size-dependent and are pinned for every deployed environment. Verified locally: rendered config substitutes correctly with and without the env vars set, and postgres boots with all five reporting `source = command line`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Postgres tuning on production lived in two files inside the pgdata Docker volume, neither in version control:
shared_bufferspgdata/postgresql.conf— initdb default, nobody set itstatement_timeoutpgdata/postgresql.auto.conf—ALTER SYSTEMlog_autovacuum_min_durationpgdata/postgresql.auto.conf—ALTER SYSTEMA fresh environment built from this repo would not have reproduced production. Command-line
-coutranks bothpostgresql.confandpostgresql.auto.conf, so declaring them in compose makes the repo the single source of truth.Why the memory settings are env-driven
compose.prod.ymlis shared by production and staging, which are not the same size. A hardcodedshared_buffers=2GBcould stop Postgres starting on a smaller box.Defaults are the stock PostgreSQL values, so any environment that sets nothing behaves exactly as it does today — no surprise for staging. Production sets the tuned values in its
.env:statement_timeoutandlog_autovacuum_min_durationare not size-dependent, so they're pinned for every deployed environment.Why 2GB
Production is 8 GiB with a 3.4 GB database (
named_areaalone is 1.8 GB of PostGIS geometry). At 128MB, Postgres was caching almost nothing itself and leaning entirely on the OS page cache. Rule of thumb applied:shared_buffers~25% of RAM,effective_cache_size~75%.Verification
Rendered config substitutes correctly both ways:
shared_buffers=2GB,effective_cache_size=6GB,maintenance_work_mem=256MB128MB/4GB/64MB(stock defaults)Booted locally with the production values; all five report the highest-precedence source:
Follow-up after merge
.env(per-host config, like the existing secrets)ALTER SYSTEMentries frompostgresql.auto.confso there is one source of truth rather than two silently competingAlso left alone deliberately: the inert
docker/postgresql.confmount. Uncommenting itsconfig_fileline would replace the image's entire default config and droplisten_addresses, breaking networking. Itspg_stat_statementssettings could be moved onto this command line as a separate change.🤖 Generated with Claude Code