Skip to content

Allow scoped deferral of Apps registry cache invalidation #189

Description

@haucros

Code of Conduct

  • I agree to follow Django's Code of Conduct.

Feature Description

Provide a minimal, public, registry-scoped context manager that can defer compatible Apps registry cache invalidations within an explicit bounded operation, while preserving today’s behavior outside the context and guaranteeing invalidation when the context exits.

Problem

Django migration state operations may invoke Apps.clear_cache() repeatedly during a bounded sequence of related model-state changes. In a reproducible application migration graph, controlled A/B/A2 experiments found that grouping compatible invalidations reduced median wall time by about 32% and CPU time by about 34%, while schema, migration graph, ProjectState, StateApps, ModelState, Apps registry, data, side effects, permissions, tenant boundaries, audit state, and rollback remained equivalent.

There is currently no documented public extension point for this use case. Applications cannot safely evaluate or adopt the behavior without relying on Django internals or a monkeypatch. The request is for an explicit supported contract, not a silent change to existing invalidation semantics.

Request or proposal

request

Additional Details

The evidence package is public and fixed at this immutable Gist revision:

https://gist.github.com/haucros/38199514f19ff0cd252c56ac19f21554/d2d41421bfe2828038fa1a8c032e2ab2fc82686c

Documentation bundle SHA-256: 6c96aa469b78ecefc2d7f003708355d1b78d0107d2837f645088d92b29122f93

Evidence bundle SHA-256: c0869610f628f9f21a0694c9281abca8bc37bf48aa26ffbe42ea8ecc8f6cc168

The package includes the problem statement, compatibility and risk analysis, public API summary, governance record, and machine-readable SHA-256 manifests. It contains no production data or credentials.

The proposed behavior is opt-in. Existing callers and default cache invalidation behavior would remain unchanged. Open design questions include nesting, exception handling, thread/async boundaries, registry ownership, and whether the capability should be limited to Django-managed internal scopes.

Implementation Suggestions

Conceptually only (not an implementation):

with apps.defer_cache_invalidation(reason="migration state update"):
    # Existing operations continue to request invalidation.
    # Compatible requests may be coalesced within this explicit scope.
    ...
# The registry is invalidated before control returns to the caller.

A possible discussion signature is:

Apps.defer_cache_invalidation(*, reason: str | None = None) -> ContextManager[None]

Required guarantees would include backward compatibility, invalidation on normal and exceptional exit, deterministic nesting semantics, no additional SQL, and no observable stale registry state outside the scope. The exact API and ownership belong to upstream discussion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Idea

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions