Skip to content

Optimize Budget model performance by preventing N+1 queries #2504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

SyedaAnshrahGillani
Copy link

Problem

The Budget model was suffering from N+1 query issues, leading to excessive database calls and performance degradation when rendering budget donut charts.

Before Optimization

  • to_donut_segments_json method was causing N+1 queries due to:
    • Loading each budget_category and its category separately
    • Repeated lookup calls for category expenses

Solution

  • Pre-computed category totals using an index_by for O(1) lookup.
  • Applied includes(:category) explicitly to ensure categories are preloaded, reducing query count.
  • Same optimization was applied to allocated_spending method.

After Optimization

  • Fixed to avoid repeated and expensive lookups per budget_category
  • Now only 2 queries total: preload + expense totals

Impact

This optimization is expected to significantly improve performance for users with many budget categories by reducing:

  • Response time for rendering budget sections
  • Database load on budget-related pages

Testing

Added comprehensive test coverage to validate no regression in behavior and verified query count reduction.

- Fixed N+1 query issue in  method that was causing excessive database calls
- Optimized category lookups by pre-computing category totals with  for O(1) lookup
- Added explicit  to prevent redundant category association loads
- Applied same optimization to  method
- Added comprehensive test coverage to verify performance improvements
- These changes significantly reduce database queries when rendering budget donut charts

Performance Impact:
- Before: N budget_categories × 2 queries (category + expense lookup) = 2N queries per chart
- After: 2 total queries (1 preload + 1 expense totals) regardless of category count

This optimization is especially impactful for users with many budget categories,
reducing response time and database load on budget-related pages.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant