Expire on Commit: Freshness vs Memory for Long-Lived SQLAlchemy Sessions
0 reputation · 01 Oct 2022, 16:55 UTC
Choosing between SQLAlchemy's default expire_on_commit=True and expire_on_commit=False is a trade-off for long-running applications that keep a Session or scoped_session alive across many commits. With True, committed instances are expired, so subsequent attribute access triggers a refresh query; this preserves freshness but can increase database round-trips and memory churn. With False, instances retain loaded state, reducing refresh queries, but external updates may not be visible unless the session is refreshed or expired manually.
The uncertainty is whether the memory growth often attributed to expire_on_commit is actually driven by the session's identity map and query cache retention, especially when scoped_session instances are not removed. SQLAlchemy 1.4 and 2.x document scoped_session.remove() and context-manager cleanup, but the default expire_on_commit value remains a design choice.
For a long-lived worker session, which setting better bounds memory without serving stale data? Does the identity map dominate retention regardless of expire_on_commit? What documented mechanism limits query cache retention independently?