Repository navigation
Roadmap
PGTuned aims to become a practical, explainable and container-aware tuning tool for PostgreSQL and PostGIS.
The goal is not to provide magical performance optimization, but to generate safe and transparent baseline configurations based on the runtime environment, workload profile and deployment context.
PGTuned should help users answer a simple question:
“I am running PostgreSQL or PostGIS in Docker or Kubernetes with these CPU and memory limits. What is a reasonable configuration, why, and how should I apply it safely?”
PGTuned should evolve from a pre-tuned PostgreSQL Docker image into a broader tuning toolkit.
The project should support three main use cases:
-
Generate a PostgreSQL configuration
- From explicit parameters.
- From container or host resource detection.
- With clear workload profiles.
-
Explain generated settings
- Show how each value was computed.
- Highlight assumptions and risks.
- Warn about unsafe combinations.
-
Integrate cleanly with Docker and Kubernetes
- Respect container CPU and memory limits.
- Avoid destructive changes to existing PostgreSQL data directories.
- Provide deployment examples for common environments.
- Safe defaults first
- Explainability over magic
- Container and Kubernetes awareness
- PostGIS support as a first-class concern
- Compatibility with the official PostgreSQL Docker image
- No silent destructive behavior
- Benchmark-driven improvements
Make the current project safe, predictable and compatible with real Docker usage.
The current Docker integration should not rely only on docker-entrypoint-initdb.d, because that directory is only processed when a new database is initialized.
PGTuned should support existing PostgreSQL data directories and should be able to generate or refresh configuration at container startup.
Expected outcome:
- Tuning can be applied when a PostgreSQL data directory already exists.
- Migration from the official PostgreSQL image to PGTuned is documented and predictable.
- Users can choose whether tuning is applied once or on every startup.
Suggested modes:
PGTUNED_MODE=off
PGTUNED_MODE=init
PGTUNED_MODE=always
PGTUNED_MODE=print
PGTuned should remain compatible with the official PostgreSQL Docker image behavior.
Expected outcome:
- The original entrypoint logic is preserved as much as possible.
- PGTuned does not break initialization, permissions, authentication or upgrade behavior.
- Startup behavior remains understandable for users already familiar with the official image.
The current Docker image should avoid breaking common bind mount workflows.
Expected outcome:
- Bind mounts work consistently.
- Named volumes continue to work.
- The behavior remains aligned with the official PostgreSQL image.
- The documentation explains the recommended volume layout.
PGTuned should detect resources from cgroups before falling back to host-level values.
Expected outcome:
-
Support cgroups v2:
memory.maxcpu.maxcpuset.cpus.effective
-
Support cgroups v1:
memory.limit_in_bytescpu.cfs_quota_uscpu.cfs_period_uscpuset.cpus
-
Fallback to:
/proc/meminfonproc
The generated output should clearly show where each detected value came from.
Example:
Detected memory limit: 4096 MiB from cgroup v2 memory.max
Detected CPU limit: 2 cores from cgroup v2 cpu.max
Detected storage type: unknown, using conservative default
PGTuned should support current PostgreSQL versions and reduce emphasis on obsolete versions.
Recommended support policy:
Official support:
- PostgreSQL 14
- PostgreSQL 15
- PostgreSQL 16
- PostgreSQL 17
- PostgreSQL 18
Legacy support:
- Older versions may remain available but are not a priority.
The GitHub Actions workflow should be updated.
Expected outcome:
- Use current versions of GitHub Actions.
- Build images on pull requests without pushing them.
- Push images only from
main, tags or releases. - Add separate jobs for linting, testing and image builds.
- Fail fast on script or Docker regressions.
PGTuned needs tests covering the most important real-world scenarios.
Minimum test coverage:
- Shell linting with ShellCheck.
- Unit tests for tuning calculations.
- Docker smoke tests.
- Existing
PGDATAbehavior. - Empty
PGDATAbehavior. - Named volume behavior.
- Bind mount behavior.
- Explicit memory and CPU input.
- cgroup-based memory and CPU detection.
Turn PGTuned from a Docker image into a reusable tuning tool.
PGTuned should provide a command-line interface independent from the Docker image.
Example commands:
pgtuned render
pgtuned explain
pgtuned inspect
pgtuned diffThe render command should generate PostgreSQL configuration from explicit inputs.
Example:
pgtuned render \
--postgres-version 17 \
--profile web \
--memory 4Gi \
--cpu 2 \
--max-connections 100 \
--storage ssdSupported output formats:
postgresql.conf
json
yaml
markdown
The explain command should describe how each setting was calculated.
Example output:
shared_buffers = 1GB
Reason:
25% of available memory is assigned to shared_buffers for this workload profile.
Assumption:
The database is running inside a container with a 4GB memory limit.
Warning:
If the container memory limit is too close to this value, Linux page cache and other PostgreSQL memory usage may cause pressure.
PGTuned should be able to compare a current configuration with a recommended one.
Example:
pgtuned diff \
--current postgresql.conf \
--recommended pgtuned.confExpected outcome:
- Show changed values.
- Explain whether restart or reload is required.
- Highlight risky settings.
- Avoid overwriting user configuration blindly.
PostGIS should become a first-class use case.
Suggested profiles:
web
oltp
analytics
mixed
desktop
ci-small
postgis-web
postgis-analytics
postgis-bulk-load
PostGIS profiles should include guidance for:
- Spatial indexes.
- Large geometry tables.
- Bulk data loading.
-
CREATE INDEX USING GIST. -
ANALYZEafter imports. - Memory-heavy spatial queries.
- Conservative
work_memhandling. - Autovacuum considerations for large spatial tables.
Storage detection is often unreliable in containers and cloud environments.
PGTuned should support explicit storage profiles:
hdd
ssd
nvme
san
network
unknown
For unknown storage, PGTuned should use conservative defaults and explain the assumption.
PGTuned should document how to use generated configuration in Kubernetes.
Examples should include:
- ConfigMap generation.
- StatefulSet usage.
- Helm values example.
- Init container pattern.
- Sidecar or startup wrapper pattern.
- Resource requests and limits.
- Warning about tuning from node resources instead of container limits.
Example command:
pgtuned render \
--profile postgis-web \
--memory 8Gi \
--cpu 4 \
--format configmapMake PGTuned useful for existing PostgreSQL and PostGIS instances.
PGTuned should be able to connect to a running database and inspect current settings.
Example:
pgtuned inspect "$DATABASE_URL"Information to collect:
SHOW ALL;
SELECT * FROM pg_settings;
SELECT * FROM pg_stat_database;
SELECT * FROM pg_stat_bgwriter;Optional extensions:
SELECT * FROM pg_stat_statements;The advisor should compare current settings with recommended baseline values.
Expected output:
max_connections = 500
Warning:
This value is high for the detected memory limit.
Recommendation:
Consider using PgBouncer before increasing work_mem or allowing many concurrent queries.
PGTuned should warn about common configuration problems:
- Very high
max_connections. - High
work_memcombined with high connection count. - Low
maintenance_work_memfor large indexes. - Very low
shared_buffers. - Inconsistent memory assumptions.
- Over-tuning based on host memory instead of container memory.
- Missing
pg_stat_statementsfor performance analysis. - PostGIS workloads without appropriate indexes.
The advisor should indicate whether a setting requires:
reload
restart
no action
This makes the tool more operationally useful.
Make PGTuned recommendations evidence-based.
Provide reproducible benchmark scenarios using pgbench.
Suggested scenarios:
- Small container: 1 CPU, 1GB RAM.
- Medium container: 2 CPU, 4GB RAM.
- Larger container: 4 CPU, 16GB RAM.
- High connection count.
- Low connection count with PgBouncer-style assumptions.
Provide basic spatial benchmark datasets and queries.
Suggested scenarios:
- Spatial index creation.
- Bounding box queries.
- Intersections.
- Distance queries.
- Large geometry imports.
- Read-heavy spatial web workload.
- Analytical spatial workload.
Documentation should clearly state:
- Hardware or container limits.
- PostgreSQL version.
- PostGIS version.
- Dataset size.
- Query type.
- Baseline configuration.
- PGTuned configuration.
- Results.
- Limitations.
The goal is not to claim universal performance gains, but to validate that generated configurations are reasonable and safe.
Make PGTuned easier to trust, install and maintain.
Use semantic versioning:
v0.1.0
v0.2.0
v1.0.0
Each release should include:
- Changelog.
- Supported PostgreSQL versions.
- Supported PostGIS versions.
- Docker image tags.
- Known limitations.
Recommended image locations:
docker.io/esgn/pgtuned
ghcr.io/esgn/pgtuned
Recommended tags:
latest
17
17-postgis
18
18-postgis
Avoid maintaining too many obsolete image combinations unless there is a clear user need.
Possible improvements:
- SBOM generation.
- Image provenance.
- Signed images.
- Dependency scanning.
- Trivy or Grype scan in CI.
Suggested documentation pages:
docs/
getting-started.md
docker.md
docker-compose.md
kubernetes.md
postgis.md
profiles.md
configuration-reference.md
advisor-mode.md
limitations.md
migration-from-postgres-image.md
PGTuned should explicitly state what it does not do.
Example:
PGTuned does not guarantee better performance.
PGTuned does not replace workload-specific benchmarking.
PGTuned does not automatically solve slow queries.
PGTuned does not replace indexing, query analysis or schema design.
PGTuned generates a safe baseline configuration that should be reviewed and tested.
Focus:
- Fix startup behavior.
- Fix bind mount behavior.
- Preserve official PostgreSQL image compatibility.
- Add cgroup resource detection.
- Add basic Docker tests.
Outcome:
PGTuned becomes safe to use in Docker without surprising users.
Focus:
- Add CLI.
- Add render command.
- Add explain command.
- Add JSON/YAML output.
- Add better workload profiles.
Outcome:
PGTuned can be used without the Docker image.
Focus:
- Add PostGIS profiles.
- Add PostGIS documentation.
- Add examples for spatial workloads.
- Add bulk-load recommendations.
Outcome:
PGTuned becomes useful for geospatial PostgreSQL deployments.
Focus:
- Add Kubernetes documentation.
- Add ConfigMap output.
- Add examples for StatefulSet and Helm usage.
- Improve resource-limit detection.
Outcome:
PGTuned becomes practical for container orchestration environments.
Focus:
- Inspect a running database.
- Compare current configuration with recommendations.
- Warn about risky settings.
- Report restart and reload requirements.
Outcome:
PGTuned becomes useful for existing PostgreSQL instances.
Focus:
- Add pgbench scenarios.
- Add PostGIS benchmark scenarios.
- Publish versioned releases.
- Publish documented container images.
Outcome:
PGTuned becomes easier to trust and evaluate.
1. Fix init-only tuning behavior.
2. Fix bind mount permission issues.
3. Add cgroup-aware CPU and memory detection.
4. Modernize CI.
5. Add automated Docker smoke tests.
1. Add standalone CLI.
2. Add explainable output.
3. Add PostGIS profiles.
4. Add Kubernetes documentation.
5. Add configuration diffing.
1. Add live database advisor mode.
2. Add benchmarks.
3. Publish signed releases.
4. Add SBOM and provenance.
5. Build a stronger documentation site.
PGTuned should become a reliable baseline tuning assistant for PostgreSQL and PostGIS deployments, especially in Docker and Kubernetes environments.
Its main value should be:
- Detecting the real available resources.
- Generating reasonable PostgreSQL settings.
- Explaining every recommendation.
- Warning about dangerous assumptions.
- Integrating safely with existing deployments.
The project should remain modest in its promises but strong in its execution.