Merged
Conversation
Replace COUNT(*) queries on solid_queue_jobs with counts from ready_executions, scheduled_executions, claimed_executions, and failed_executions. Replaces "Total Jobs" and "Completed" dashboard stats with "Active Jobs" (sum of ready + scheduled + in-progress + failed). Resolves gateway timeouts on overview page with millions of rows. Fixes #27
- Change .pluck(:job_id) to .select(:job_id) in all filter methods to keep filtering as DB subqueries instead of loading IDs into memory - Pre-aggregate queue stats with 3 GROUP BY queries, eliminating per-queue COUNT queries in QueuesPresenter - Add spec to prevent unbounded pluck regression
Replace in-memory timestamp bucketing (pluck all timestamps, iterate in Ruby) with SQL GROUP BY using computed bucket index. Works on both PostgreSQL and SQLite with adapter-aware expressions.
When show_chart is false, ChartDataService is not instantiated and the chart section is not rendered, eliminating chart queries entirely for users who don't need the visualization.
- Add "Performance at Scale" section to README - Add [Unreleased] section to CHANGELOG with breaking change note - Add Large Dataset Performance to ROADMAP as done - Include implementation plan in docs/plans/
Bump version to 1.2.0, set CHANGELOG release date, update README gem version reference.
- Fix RSpec/MessageSpies: use have_received instead of receive - Fix Layout/HashAlignment, Layout/ArgumentAlignment auto-corrections - Fix Style/ConditionalAssignment in base_controller - Disable false-positive Style/HashTransformKeys (pluck returns Array) - Disable RSpec/DescribeClass for source-scanning spec - Update Gemfile.lock with version 1.2.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
solid_queue_jobs)config.show_charttoggle to optionally disable chart queriesProblem
Issue #27 — Users with ~4M rows in
solid_queue_jobsexperienced gateway timeouts (502/504) when loading the overview page. Root causes:COUNT(*)onsolid_queue_jobstaking 52+ seconds each.pluck(:job_id)loading millions of IDs into Ruby arrays forWHERE INSolution
1. Stats from execution tables only
Replaced
COUNT(*)onsolid_queue_jobswith counts from small execution tables (ready_executions,scheduled_executions,claimed_executions,failed_executions). Dashboard now shows "Active Jobs" instead of "Total Jobs" and "Completed".2. SQL GROUP BY chart bucketing
Replaced in-memory timestamp bucketing with SQL
GROUP BYusing computed bucket index. Cross-DB compatible (PostgreSQL + SQLite).3. Subquery filters
Changed all
.pluck(:job_id)to.select(:job_id)so filtering stays as a DB subquery instead of loading arrays into memory.4. Pre-aggregated queue stats
Replaced per-queue COUNT queries with 3
GROUP BY queue_namequeries in the controller, passed to presenter.5.
config.show_charttoggleNew configuration option to disable chart queries entirely for users who don't need the visualization.
Benchmark Results (100,000 jobs on PostgreSQL)
Changes
app/services/solid_queue_monitor/stats_calculator.rb— Rewritten to use execution tables onlyapp/presenters/solid_queue_monitor/stats_presenter.rb— "Active Jobs" replaces "Total Jobs"/"Completed"app/controllers/solid_queue_monitor/base_controller.rb— All.pluck(:job_id)→.select(:job_id)app/controllers/solid_queue_monitor/queues_controller.rb— Pre-aggregate queue stats with GROUP BYapp/controllers/solid_queue_monitor/in_progress_jobs_controller.rb— Fix pluck in filtersapp/presenters/solid_queue_monitor/queues_presenter.rb— Use pre-aggregated stats hashapp/services/solid_queue_monitor/chart_data_service.rb— SQL GROUP BY bucketing (cross-DB)app/controllers/solid_queue_monitor/overview_controller.rb— Conditional chart loadinglib/solid_queue_monitor.rb— Addshow_chartconfig attributelib/generators/solid_queue_monitor/templates/initializer.rb— Addshow_chartconfig optionBreaking Change
Dashboard "Total Jobs" and "Completed" stats are replaced with "Active Jobs" (sum of ready + scheduled + in-progress + failed). This avoids expensive
COUNT(*)on the jobs table that caused timeouts at scale.Testing
no_unbounded_pluck_spec.rb— source-code scanning test preventing pluck regressionchart_data_service_spec.rb— behaviour-based tests on SQLitestats_calculator_spec.rb— verifiesSolidQueue::Jobnever receives:countoverview_spec.rb— testsshow_chart = falseskips chart queriesChecklist
Closes #27