PostgreSQL — Checklist¶
OWNER: boris, yoanna ALSO_USED_BY: urszula, maxim, piotr, ashley, floris LAST_VERIFIED: 2026-03-26 GE_STACK_VERSION: PostgreSQL 16.x
NEW PROJECT CHECKLIST (database setup)¶
- [ ] CHECK: PostgreSQL 16.x is the database IF_SKIPPED: Wrong version causes extension incompatibilities
- [ ] CHECK: SSL enabled with
sslmode=requirein connection string IF_SKIPPED: Unencrypted connections violate ISO 27001 - [ ] CHECK:
pg_stat_statementsextension enabled IF_SKIPPED: No query performance monitoring capability - [ ] CHECK:
pgcryptoextension enabled IF_SKIPPED: UUID generation and encryption unavailable - [ ] CHECK: Database timezone set to UTC IF_SKIPPED: Timestamp interpretation varies by server locale
- [ ] CHECK: All timestamps use
timestamptz(with time zone) IF_SKIPPED: Timezone data silently dropped - [ ] CHECK: Application connects as
app_role, not superuser IF_SKIPPED: Principle of least privilege violated - [ ] CHECK: Credentials stored in k8s secrets or Vault IF_SKIPPED: Credentials in source code — security incident
- [ ] CHECK:
idle_in_transaction_session_timeoutconfigured IF_SKIPPED: Idle transactions block autovacuum indefinitely - [ ] CHECK: Database hosted in EU (UpCloud Frankfurt) IF_SKIPPED: GDPR and EU data sovereignty violation
MULTI-TENANT CHECKLIST (per tenant-scoped table)¶
- [ ] CHECK: Table has
tenant_idcolumn with foreign key to tenants IF_SKIPPED: No tenant isolation possible - [ ] CHECK: RLS enabled AND forced on the table IF_SKIPPED: Table owner bypasses all tenant isolation
- [ ] CHECK: RLS policies exist for SELECT, INSERT, UPDATE, DELETE IF_SKIPPED: Some operations bypass tenant isolation
- [ ] CHECK:
tenant_idis the first column in composite indexes IF_SKIPPED: Queries scan ALL tenants before filtering — O(N) per tenant - [ ] CHECK: Application sets
SET LOCAL app.current_tenantin transaction IF_SKIPPED: RLS returns empty results or throws ADDED_FROM: admin-ui-2026-02, multi-tenant implementation
SCHEMA CHANGE CHECKLIST (before any migration)¶
- [ ] CHECK: New columns are nullable or have defaults IF_SKIPPED: Table rewrite locks all rows — downtime
- [ ] CHECK: New indexes use
CREATE INDEX CONCURRENTLYIF_SKIPPED: Table locked for duration of index build - [ ] CHECK: Enum changes are additive only (no removes, no renames) IF_SKIPPED: Running application instances break during rolling deploy
- [ ] CHECK: Column renames use add-backfill-drop pattern IF_SKIPPED: Running instances query old column name — errors
- [ ] CHECK: Rollback SQL file exists for destructive changes IF_SKIPPED: No recovery path if migration causes issues
- [ ] CHECK: Boris has reviewed the migration IF_SKIPPED: Schema changes without DBA review violate GE process
SECURITY CHECKLIST (per database)¶
- [ ] CHECK:
pg_hba.confrestricts connections to known CIDR ranges IF_SKIPPED: Database accessible from unauthorized networks - [ ] CHECK: No
trustauthentication entries inpg_hba.confIF_SKIPPED: Authentication bypassed entirely - [ ] CHECK:
hostnossllines reject non-SSL connections IF_SKIPPED: Unencrypted connections possible - [ ] CHECK: Audit triggers exist on tables with PII or financial data IF_SKIPPED: No tamper trail — ISO 27001 non-compliance
- [ ] CHECK:
audit_logis append-only (RLS enforced) IF_SKIPPED: Audit trail can be tampered with - [ ] CHECK: PII columns evaluated for column-level encryption IF_SKIPPED: Data breach exposes plaintext PII
- [ ] CHECK: Password length >= 24 characters, randomly generated IF_SKIPPED: Weak credentials enable brute force
PERFORMANCE CHECKLIST (quarterly review)¶
- [ ] CHECK: Cache hit ratio > 99% IF_SKIPPED: Excessive disk I/O degrades all queries
- [ ] CHECK: No tables with > 20% dead row percentage IF_SKIPPED: Table bloat wastes storage and slows sequential scans
- [ ] CHECK: No queries > 1s mean execution time in pg_stat_statements IF_SKIPPED: Slow queries degrade user experience
- [ ] CHECK: No idle-in-transaction connections > 30s IF_SKIPPED: Lock contention and autovacuum blocking
- [ ] CHECK: Unused indexes identified and dropped IF_SKIPPED: Unused indexes slow writes and waste storage
- [ ] CHECK: PgBouncer in transaction mode for production IF_SKIPPED: Connection exhaustion under load ADDED_FROM: admin-ui-2026-02, connection pooling audit
Cross-References¶
READ_ALSO: wiki/docs/stack/postgresql/index.md READ_ALSO: wiki/docs/stack/postgresql/security.md READ_ALSO: wiki/docs/stack/postgresql/performance.md READ_ALSO: wiki/docs/stack/postgresql/multi-tenant.md READ_ALSO: wiki/docs/stack/postgresql/pitfalls.md READ_ALSO: wiki/docs/stack/drizzle/checklist.md