DEV Community
Follow
Django 6.1's FETCH_PEERS collapses a 2,001-query loop into 2
Django 6.1 introduced fetch_mode to address the N+1 query problem without requiring explicit select_related or prefetch_related calls. The fetch_mode setting, particularly FETCH_PEERS, significantly reduces query counts and execution time for foreign key lookups. Testing demonstrated that FETCH_PEERS transformed a loop of 2,001 queries into just 2, an improvement of approximately 87 times. This performance gain is comparable to using select_related, achieving efficient batch fetching. However, FETCH_PEERS does not apply to the reverse side of a relation, meaning prefetch_related is still necessary for "many" side N+1 issues. The FETCH_RAISE mode is designed to prevent accidental lazy loading by blocking field access. A crucial gotcha exists when combining FETCH_PEERS with QuerySet.iterator(), as it reverts to the N+1 pattern due to how peer tracking operates. FETCH_PEERS also eagerly batches all related data for the queryset, even if only a subset is accessed, which might be less efficient than select_related in some scenarios. Memory overhead from materializing querysets and fetching related data was noted as small at the tested scale. Concurrent threads running FETCH_PEERS independently maintained the 2-query count, indicating robustness under load. Debugging query counting requires careful attention to buffer limits, as exceeding them can lead to silently incorrect results.