Skip to main content

Database query paths are analyzed and transformed into an efficient index tree

PostgreSQL Index Advisor for Django

A workload-driven PostgreSQL Index Advisor for Django.

PyPI version Monthly downloads Python 3.10+ Django 5.2–6.1 BSD 2-Clause license Status alpha

PostgreSQL Index Advisor for Django learns from PostgreSQL's pg_stat_statements data. It identifies repeated query patterns, compares them with existing indexes, and produces recommendations that a developer can understand before changing the database.

The project is distributed on PyPI as django-index-optimizer and installed as the Django app optimizer. Those technical names remain stable for existing users.

Version 0.2.0 is preview-only: it produces evidence and safely quoted SQL for review but never changes the database.

How it works

pg_stat_statements
        │
        ▼
 recurring query patterns
        │
        ▼
 existing-index comparison
        │
        ▼
 explained recommendations
        │
        ▼
 review first ──► migration or database change process

The 0.2.0 workflow:

  1. collects slow or frequently executed PostgreSQL statements;
  2. parses PostgreSQL filter predicates into schema, table, and column evidence;
  3. ignores recommendations already covered by an index prefix;
  4. explains the evidence behind each candidate;
  5. generates reviewable, safely quoted SQL;
  6. never changes the database.

Correctness and database safety take priority over generating a large number of suggestions.

Installation

python -m pip install django-index-optimizer

Add the app:

INSTALLED_APPS = [
    # ...
    "optimizer",
]

Enable pg_stat_statements in PostgreSQL:

shared_preload_libraries = 'pg_stat_statements'
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

Preview recommendations:

python manage.py optimize_indexes
python manage.py optimize_indexes --limit 100 --min-calls 10

For setup and troubleshooting, see the pg_stat_statements guide.

Each recommendation includes the affected table and columns, workload calls, total execution time, the reason it was selected, and safely quoted CREATE INDEX CONCURRENTLY SQL. The SQL is printed for review and is never executed.

For CI, scripts, or a review artifact:

python manage.py optimize_indexes --limit 100 --min-calls 10 --format json \
  > index-recommendations.json

To make recommendations fail an opt-in CI policy check while preserving the complete report:

python manage.py optimize_indexes --format json --fail-on-recommendations \
  > index-recommendations.json

The command exits successfully when the report is empty and unsuccessfully when it contains one or more candidates. Recommendations remain review artifacts: this option does not mean every suggestion should become a migration or be applied automatically.

Normalized SQL text from pg_stat_statements is parsed in memory but is not included in reports. Query IDs are included so a recommendation can be traced back without copying potentially sensitive literals into an artifact.

See Understanding recommendations for the evidence model, existing-index rules, JSON fields, and the checks to perform before using a SQL preview.

Current conservative limits

  • Only filter predicates that can be mapped unambiguously to one table are considered.
  • Recommendations are currently single-column B-tree candidates.
  • PostgreSQL system catalogs and the advisor's own queries are ignored.
  • Planner validation, write-overhead scoring, joins, ordering, partial indexes, and multi-column candidates are planned rather than guessed prematurely.

Supported combinations follow Django: Django 5.2 supports PostgreSQL 14+, and Django 6.1 supports PostgreSQL 15+. Python 3.10–3.14 is supported where the selected Django release supports it. PostgreSQL 14–17 are covered by the project's integration-test matrix.

Download statistics

django-index-optimizer monthly downloads

PyPI download counts include automated environments such as CI and are not a count of unique users. View the current breakdown on PyPI Stats.

Contributing

New contributors are welcome, including developers who are still learning Django or PostgreSQL internals.

  1. Choose an unassigned good first issue.
  2. Comment with the approach you want to take and wait for confirmation.
  3. Follow the environment, test, and pull-request steps in CONTRIBUTING.md.

Most beginner issues use unit tests and do not require a local PostgreSQL server unless the issue explicitly says otherwise.

Security

Report database-safety or SQL-injection concerns privately through GitHub security advisories. Never include credentials or sensitive production queries in a public issue.

License

BSD 2-Clause. See LICENSE.

Release files for django-index-optimizer 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-index-optimizer 0.2.1
File Size Uploaded
django_index_optimizer-0.2.1.tar.gz 13.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-index-optimizer 0.2.1
File Interpreter ABI Platform
django_index_optimizer-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 25.0 kB

Release files / django_index_optimizer-0.2.1.tar.gz

Download URL django_index_optimizer-0.2.1.tar.gz
Size 13.4 kB
Tags Source
SHA-256 checksum
How to use checksums
834688968e4deaea32419a30bf4375c8448aac6a8f0b88ad8397339c83cf10e2
BLAKE2b-256 checksum
How to use checksums
f4f6547b6656f61aa9cc614c937533969efd9ee331eb340f0d19b2e5274f2c13
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / django_index_optimizer-0.2.1-py3-none-any.whl

Download URL django_index_optimizer-0.2.1-py3-none-any.whl
Size 11.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd1046968dae3c5c3930bd4cb85c2db374fe8a750f2ed286e514091fa27c1566
BLAKE2b-256 checksum
How to use checksums
de6b15ef767a285d58414f58807cae7f3daef6b845e4a7719bf0bb17fadc033d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page