Releases: railspulse-org/rails_pulse
Release list
v0.3.3
Release v0.3.3
Bug Fixes
- Dashboard "Throughput & Errors" chart now includes 4xx errors — Client errors (400–499) were previously excluded from the Errors series; they are now counted alongside 5xx errors, giving a more complete picture of request failures.
- Chart X-axis no longer shows duplicate timestamps — When switching time ranges or zooming, the X-axis could render the same time label more than once; this is now deduplicated.
- Chart tooltips no longer show
nullfor empty periods — Periods with no recorded data now display0in tooltips rather than a blank ornullvalue. - Chart tooltips format large numbers with thousands separators — Values such as
1234567now display as1,234,567, improving readability for high-traffic apps. - PostgreSQL aborted-transaction handling in tracker — When a PostgreSQL connection was left in an error state mid-transaction, the tracker would fail silently. It now detects
PQTRANS_INERRORand issues a rollback before attempting to persist tracking data. - Time change handling in test environments — The tracker and chart concern now correctly handle cases where
Time.currentchanges mid-request during tests (e.g. when usingtravel_to), preventing flaky test failures.
Improvements
- Operation suggestions consolidated — The five separate suggestion service classes (
SqlSuggestionsService,ViewSuggestionsService, etc.) have been merged into a singleRailsPulse::OperationSuggestionsclass, reducing complexity without changing the suggestions shown to users. - Chart/table concern refactored —
ChartTableConcerninternals reorganised for clarity and to support upcoming chart features; no change to dashboard behaviour.
Breaking Changes
- None
Upgrade Notes
- No database migrations in this release. No upgrade generator run is required.
V0.3.3.pre.4
Release v0.3.3.pre.4
New Features
- None
Improvements
- Automated changelog enforcement — A new
changelogCI job now runs on every pull request and fails if the[Unreleased]section ofCHANGELOG.mdis empty, ensuring contributors document their changes before merging (#161) - Release script changelog gate —
bin/releasenow checks the[Unreleased]section before proceeding and prompts the author to open the editor if it is empty, with an option to abort rather than ship an undocumented release
Bug Fixes
- None
Breaking Changes
- None
Upgrade Notes
- Run
rails generate rails_pulse:upgradeafter updating
v0.3.3.pre.2
Release v0.3.3.pre.2
New Features
- Response size on request detail pages — The request show page and index table now display response body size in a human-readable format (e.g.
12.4 KB). Previously this field was captured but not surfaced in the UI. - JavaScript test suite — Stimulus controllers now have a full unit test suite powered by Vitest + JSDOM, covering 12 controllers including
chart_switcher,collapsible,time_range,custom_range, and more. - Migration pathway tests — A new
upgrade_migration_test.rbvalidates that both fresh installs and upgrades from v0.2.7 and v0.3.1 produce a correct, consistent schema, preventing silent migration regressions.
Improvements
- Index query refactor — Routes, Queries, and Jobs index classes now share a common
Tables::Basesuperclass, eliminating significant duplication in tag filtering, sort handling, and aggregation logic. - Data saving reliability — Simplified how
Route,Operation, andJobRunrecords are persisted, reducing unnecessary complexity in the tracker and job run collector paths. - Dependency updates — Bumped gem dependencies across Rails 7.2, 8.0, and 8.1 gemfile lockfiles; updated npm packages including ESLint configuration.
Bug Fixes
- Bulk insert failures — Fixed broken bulk inserts caused by
cache_hitbeing non-nullable on theoperationstable. Added a migration to make the column nullable (cache hit is unknown for non-cacheable requests, notfalse). - Standalone server crashes — Fixed a
NoMethodErrorwhen running Rails Pulse as a standalone server against a Rails 8.1 app. Rails 8.1 addedsession.enabled?toActionDispatch::Flash, but Rack'sSessionHashdidn't implement it; a compatibility shim now bridges the gap. - Missing upgrade migration — The
create_rails_pulse_job_runsincremental migration was absent fromdb/rails_pulse_migrate/, meaning users runningrails generate rails_pulse:upgradewould not get the job runs table. Now included.
Breaking Changes
- None
Upgrade Notes
- Run
rails generate rails_pulse:upgradeafter updating to apply two new incremental migrations:20260517000001_create_rails_pulse_job_runs— creates the job runs table if it doesn't exist20260528000001_make_cache_hit_on_operations_nullable— makescache_hitnullable onrails_pulse_operations(required to fix bulk insert failures)
0.3.3.pre.1
Release v0.3.3.pre.1
Improvements
-
Significant reduction in database round-trips when recording operations. SQL operations are now bulk-inserted via
insert_all!rather than oneINSERTper operation. SQL normalization is performed once per unique query (not once per execution), and Query records are resolved with a singleSELECTplus oneinsert_allfor any missing entries — previously this was N individualcreate_or_find_bycalls. High-traffic requests with many repeated queries (classic N+1 patterns) will see the largest gains. -
Lower memory usage in summary aggregation.
SummaryServicenow usespluckto fetch only the columns needed for statistics (route_id,duration,status, etc.) instead of loading full ActiveRecord objects. This significantly reduces memory pressure during hourly/daily summary jobs on large datasets. -
Fixed SQL normalization of IN clauses containing nested parentheses. The
normalize_in_clausesmethod was rewritten using paren-depth tracking instead of a flat regex. The previous implementation stopped at the first)it encountered, which broke queries containing subqueries with nested function calls or clauses (e.g.,IN (SELECT id FROM ... HAVING COUNT(*) > 1)). -
Row count now captured for SQL operations. The operation subscriber records
row_countfrom ActiveRecord's notification payload for SQL events, making this data available for future analysis features. -
asyncdeclared as an explicit runtime dependency. Theasyncgem (used for non-blocking request tracking) is now listed in the gemspec rather than relying on it being available transitively.
Bug Fixes
- None
Breaking Changes
- None
Upgrade Notes
- Run
rails generate rails_pulse:upgradeafter updating (no schema changes in this release, but the generator is safe to run as a no-op).
v0.3.2
Release v0.3.2
New Features
- Deployment tracking — Record deployments via
POST /rails_pulse/deployments(with token auth) orrake rails_pulse:record_deployment[sha]. Deployments appear as vertical marker lines on performance charts so you can correlate releases with regressions deployment_api_tokenconfig option — Secure the deployments endpoint for CI/CD pipelines (set inconfig/initializers/rails_pulse.rb)
Improvements
- Native ECharts time axis — All multi-series charts now use
[timestamp_ms, value]pairs instead of separate labels arrays, enabling deployment markers and smoother zoom/pan behaviour - Timezone-aware x-axis labels — Charts with ≤25 hour ranges show
HH:MMformat; longer ranges show full dates actual_sqlmigration — Operations now store the full, unparameterized SQL string in a dedicatedactual_sqlcolumn (backfilled fromlabelfor existing records), improving query normalization and N+1 detection accuracy- N+1 detection via
query_id— N+1 detection now matches onquery_id(normalized SQL) instead of fragileLIKEpatterns on the first 3 words of the label - SQL analysis fallback chain — Analysis services now prefer
actual_sql, then fall back toquery.normalized_sql, thenlabel - Label truncation — Operation labels are now truncated to 255 characters to prevent MySQL index-size errors
- Error count accuracy — Summary service now counts 5xx statuses as errors (was 4xx), aligning with standard practice; 4xx client errors are now correctly tracked separately
- Authentication config clarity — The
authentication_enabledwarning only fires when the user explicitly sets it totruewithout configuring a method, not when the production default kicks in
Bug Fixes
- Missing migration fix — Fixed a deploy-time error where the install generator would fail on fresh setups (PR #144)
Breaking Changes
- Summary service error counting — The
error_countfield now counts only 5xx responses (was ≥400). 4xx responses continue to be tracked instatus_4xx. If your dashboards or alerts rely onerror_count, verify the threshold doesn't need updating Queries::Charts::AverageQueryTimesremoved — Superseded byQueries::Charts::DatabaseLoad
Upgrade Notes
- Run
rails generate rails_pulse:upgradeafter updating to apply migrations (addsrails_pulse_deploymentstable andactual_sqlcolumn torails_pulse_operations)
v0.3.1
Release v0.3.1
New Features
- None
Improvements
- Eager loading on request detail page: Operations and their associated queries are now eager-loaded when viewing an individual request, eliminating N+1 queries on the request show page (#121)
Bug Fixes
- Fixed broken install generator schema template: The
rails_pulse_schema.rbgenerator template was missing several columns added in recent releases. Fresh installs will now correctly create all columns includingresponse_size_byteson requests,row_count/cache_hit/repeated_query_group/repetition_counton operations, and a database index on thesummarizablepolymorphic association (#125) - Fixed logger initialization crash:
RailsPulse.loggernow safely falls back to$stdoutwhenRails.loggeris unavailable (e.g. during early boot or in non-Rails contexts), preventingNoMethodErroron startup (#126)
Breaking Changes
- None
Upgrade Notes
- If you installed Rails Pulse before v0.3.1, run
rails generate rails_pulse:upgradeto apply the missing schema columns (response_size_bytes,row_count,cache_hit,repeated_query_group,repetition_count) and add the missing index on the summaries polymorphic association. These columns were present in existing installs but absent from the generator template used for fresh installs.
v0.3.0
Release v0.3.0
New Features
- New chart types across all sections — Routes, queries, and jobs now have dedicated chart panels with switchable chart types (response time percentiles, request volume, error rate, execution volume, duration, failure rate)
- Dashboard health summary — New HealthSummary model surfaces an overall health status and highlights routes/queries/jobs that need attention
- Dashboard "Needs Attention" section — Automatically surfaces slow routes, high error rates, and problematic jobs without manual digging
- Storage pressure indicator — Tracks and displays database storage growth so you know when to adjust retention settings
- Flame graph view for requests — Request detail pages now include a flame graph visualisation of operation timing
- P95 duration tracking for jobs — Job runs now record and display p95 duration alongside average duration
- Database load metric for queries — New card and chart tracking cumulative database load (execution count × avg duration) over time
- Diagnostic fields for queries — Query show pages now surface diagnostic information alongside existing analysis
- Chart series toggle — Show/hide individual series on charts without leaving the page
- Performance status concern — Shared HasPerformanceStatus concern for models that report a health status
- Metric strip component — New compact summary strip component for displaying multiple metrics inline
- Setup banner — Onboarding banner shown to users who haven't completed setup
- Time range selector — Redesigned time range UI with a custom date range option
- Suggestions service — Query show pages surface optimisation suggestions (caching, controller, SQL, HTTP, view) via dedicated suggestion services
- Statistics module — New RailsPulse::Statistics module for shared statistical calculations
- Cleanup stats reporter — Detailed reporting on what the cleanup job removed each run
- Cleanup task runner — Extracted cleanup orchestration into CleanupTaskRunner for testability
- Config and migration installers — Extracted install/upgrade logic into ConfigInstaller and MigrationInstaller classes
- Schema parser — New SchemaParser for reading and diffing schema state during upgrades
- Icon helper — Centralised IconHelper for rendering SVG icons
- Route helper — Centralised RouteHelper for building internal dashboard links
- CSP helper — Dedicated CspHelper for content security policy nonce management
- Backfill summaries job — New job to backfill summary records for historical data
Bug Fixes
- Corrected the migration filename for expanding the normalized query column (#122).
Breaking Changes
- None
Upgrade Notes
- Run
rails generate rails_pulse:upgradeafter updating.
v0.3.0.pre.2
Release v0.3.0.pre.2
New Features
- Query diagnostic fields —
rails_pulse_operationsnow tracksrow_count,cache_hit,repeated_query_group, andrepetition_countto help identify N+1 queries, cache usage, and result set sizes - Response size tracking —
rails_pulse_requestsnow recordsresponse_size_bytesfor monitoring payload sizes - P95/P99 job duration percentiles —
rails_pulse_jobsnow storesp95_durationandp99_durationcolumns for tail-latency analysis of background jobs
Improvements
- Expanded
normalized_sqlcolumn — Thenormalized_sqlcolumn onrails_pulse_queriesis migrated from a 1000-character string totexton PostgreSQL and MySQL, preventing truncation of long queries. SQLite is unaffected (no length limits enforced). - Updated
browser-actions/setup-chromefrom v1 to v2 in CI
Bug Fixes
- Fixed migration file naming inconsistency for the P95/P99 jobs migration (#116, #117)
- Fixed install generator to correctly run new gem installations and migrations (#f3db89c)
- Corrected release script (#1e44b64)
Breaking Changes
- None
Upgrade Notes
- Run
rails generate rails_pulse:upgradeafter updating to apply the new migrations - The
normalized_sqlcolumn expansion (ExpandNormalizedSqlColumn) is safe to run on live databases — it checks the current column type before migrating and is a no-op on SQLite
v0.3.0.pre.1
Release v0.3.0.pre.1
New Features
- Dashboard enhancements: Health summary, needs attention monitoring, and storage pressure indicators
- New chart types: Percentile charts (p95, p99), response time percentiles, throughput and errors, execution volume, failure rate, database load, request volume, and error rate charts
- Time range selector: Global time range picker component with presets and custom range options
- Global filters: Session-based filtering system for persisting filter preferences across requests
- Flame graph visualization: Request flame graph display in the requests show page
- Query analysis suggestions: New suggestions service providing AI-powered recommendations for query optimization (cache, HTTP, SQL, controller, view suggestions)
- Zoom range functionality: Zoom into specific time ranges on charts
- Expandable rows: Table rows that expand to show additional details
- Jobs monitoring: Comprehensive job monitoring with duration metrics, execution volume, and failure rate tracking
- Cleanup task runner: New task runner for cleanup operations with statistics reporting
Improvements
- Route diagnostics: Expanded query diagnostics with table data and performance metrics
- Chart interactions: Chart switching, series toggles, and period selection controls
- Metric cards: Enhanced metric card framework with base classes for reusability
- Card components: New base card architecture for consistent metric display
- Table improvements: Better table sorting and pagination
- Tag filtering: Improved tag-based filtering service
- Pagination concerns: Reusable pagination controller concern
- Response range handling: Better handling of response time ranges
- CSS components: New dashboard, card, chart, menu, and setup banner styles
- Icon and helper improvements: New icon helper, breadcrumbs helper, route helper
Bug Fixes
- Various internal refactoring and fixes included throughout the codebase
Breaking Changes
- Some model and service refactoring; review configuration if upgrading from v0.2.x
Upgrade Notes
- Run
rails generate rails_pulse:upgradeafter updating to apply new migrations
v0.2.7
Release v0.2.7
New Features
- None
Improvements
- None
Bug Fixes
- Fixed race condition in
CleanupService— Queries, routes, and jobs are now deleted using atomic subqueries that exclude records with active associations, preventing foreign key violations or data loss when cleanup runs concurrently with active request/job recording. Previously, a two-step count-then-delete approach could delete parent records that gained child associations between the two operations.
Breaking Changes
- None
Upgrade Notes
- No schema changes in this release. A standard
bundle update rails_pulseis sufficient — no generator steps required.