# ============================================================================= # postgres/fhir/postgresql.conf # PostgreSQL 15 configuration tuned for HAPI FHIR JPA workload. # Container memory limit: 2GB (set in docker-compose deploy.resources). # # Tuning methodology: # shared_buffers = 25% of container RAM # effective_cache = 75% of container RAM # work_mem = (RAM - shared_buffers) / (max_connections * 2) # maintenance_work_mem = 10% of RAM # # For 2GB container: # shared_buffers = 512MB # effective_cache_size = 1536MB # work_mem = 8MB (conservative — many parallel queries) # maintenance_work_mem = 200MB # ============================================================================= # Connection settings # max_connections must be > pgBouncer pool_size to leave headroom for # superuser connections (Flyway, maintenance). # pgBouncer pool_size=20 + 5 superuser = 25 total. max_connections = 30 superuser_reserved_connections = 3 # Memory shared_buffers = 512MB effective_cache_size = 1536MB work_mem = 8MB maintenance_work_mem = 200MB # Write performance # wal_buffers: 16MB is good for write-heavy workloads wal_buffers = 16MB checkpoint_completion_target = 0.9 # synchronous_commit=on: do not disable — data integrity is non-negotiable # for a national health record system. synchronous_commit = on # Query planner # random_page_cost=1.1: appropriate for SSD storage (not spinning disk). # If storage is HDD, set to 4.0. random_page_cost = 1.1 effective_io_concurrency = 200 # Logging — errors and slow queries only # log_min_duration_statement: log queries taking >500ms. # Adjust down to 100ms if you want more visibility during initial deployment. log_destination = stderr logging_collector = off # Docker captures stderr directly log_min_messages = WARNING log_min_error_statement = ERROR log_min_duration_statement = 500 log_line_prefix = '%t [%p] %u@%d ' log_checkpoints = on log_connections = off # pgBouncer already logs connections log_disconnections = off log_lock_waits = on log_temp_files = 0 # Autovacuum — keep defaults but tune for HAPI's high-write token tables autovacuum = on autovacuum_max_workers = 3 autovacuum_naptime = 30s # HFJ_SPIDX_TOKEN is written heavily — lower threshold for autovacuum autovacuum_vacuum_scale_factor = 0.02 autovacuum_analyze_scale_factor = 0.01 # Timezone — all timestamps in UTC timezone = 'UTC' log_timezone = 'UTC' # Locale lc_messages = 'en_US.UTF-8' lc_monetary = 'en_US.UTF-8' lc_numeric = 'en_US.UTF-8' lc_time = 'en_US.UTF-8' # Statistics track_io_timing = on track_counts = on