diff --git a/CHANGELOG.md b/CHANGELOG.md
index 715e3f9b..1f999e77 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,83 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.3.0] - 2026-02-20
+
+### Important
+
+- **Schema upgrade**: The `collect.memory_stats` table gains two new columns (`total_physical_memory_mb`, `committed_target_memory_mb`). The upgrade script runs automatically via the CLI/GUI installer and uses `IF NOT EXISTS` checks, so it is safe to re-run. On servers with very large `memory_stats` tables this ALTER may take a moment.
+
+### Added
+
+- Physical Memory, SQL Server Memory, and Target Memory columns in Memory Overview ([#140])
+- Current Configuration view (Server Config, Database Config, Trace Flags) in Dashboard Overview ([#143])
+- Popup column filters and right-click context menus in all drill-down history windows ([#206])
+- Consistent popup column filters across all Dashboard grids — replaced remaining TextBox-in-header filters and added filters to Trace Flags ([#200])
+- 7-day time filter option in drill-down queries ([#165])
+- Alert badge/count on sidebar Alerts button ([#109])
+- Missing poison wait defaults in wait stats picker ([#188])
+
+### Changed
+
+- Default Trace tabs moved from Resource Metrics to Overview section ([#169])
+- Trends tab shown first in Locking section ([#171])
+- Wait stats cap raised from 20 to 30 (Dashboard) / 50 (Lite) so poison waits are never dropped ([#139])
+- Settings time range dropdown now matches dashboard button options ([#210])
+- "Total Executions" label in drill-down summaries renamed to clarify meaning ([#194])
+- WAITFOR sessions excluded from long-running query alerts ([#151])
+
+### Fixed
+
+- Deadlock XML processor timezone mismatch — sp_BlitzLock returning 0 results because UTC dates were passed instead of local time
+- Sidebar alert badge not updating when alerts dismissed from server sub-tabs ([#214])
+- Sidebar alert badge not clearing on acknowledge ([#186])
+- NOC deadlock/blocking showing "just now" for stale events instead of actual timestamp ([#187])
+- NOC deadlock severity using extended events timestamp ([#170])
+- Newly added servers not appearing on Overview until app restart ([#199])
+- Double-click on column header incorrectly triggering row drill-down ([#195])
+- Squished drill-down charts — now use proportional sizing ([#166])
+- Unreliable chart tooltips — now use X-axis proximity matching ([#167])
+- Query Trace Patterns showing empty despite data existing ([#168])
+- Drill-down windows: removed inline plan XML, added time range filtering, aggregated by collection_time ([#189])
+- Row clipping in Default Trace and Current Configuration grids ([#183], [#184])
+- Numeric filter negative range parsing ([#113])
+- MCP shutdown deadlock risk ([#112])
+- Lite DBNull cast error in database_config collector on SQL 2016 Express ([#192])
+- DuckDB concurrent file access IO errors ([#164])
+
+## [1.2.0] - 2026-02-15
+
+### Added
+
+- Alert types, alerts history view, column filtering, and dismiss/hide for alerts ([#52], [#56])
+- Average ms per wait chart toggle in both apps ([#22])
+- Collection Health tab in Lite UI ([#39])
+- Collector performance diagnostics in Lite UI ([#40])
+- Hover tooltips on all Dashboard charts ([#70])
+- Minimize-to-tray setting added to Lite ([#53])
+- Persist dismissed alerts across app restarts ([#44])
+- Locale-aware date/time formatting throughout UI ([#41])
+- 24-hour format in time range picker ([#41])
+- CI pipelines for build validation, SQL install testing, and DuckDB schema tests
+- Expanded Lite database config collector to 28 sys.databases columns ([#142])
+- Parquet archive visibility and scheduled DuckDB database compaction ([#160], [#161])
+- DuckDB checkpoint optimization and collection timing accuracy
+- Installer `--reset-schedule` flag to reset collection schedule on re-install
+
+### Fixed
+
+- Deadlock charts not populating data ([#73])
+- Chart X-axis double-converting custom range to server time ([#49])
+- query_cost overflow in memory grant collector ([#47])
+- XE ring buffer query timeouts on large buffers ([#37])
+- Dashboard sub-tab badge state and DuckDB migration for dismissed column
+- Lite duplicate blocking/deadlock events from missing WHERE clause ([#61])
+- Procedure_stats_collector truncation on DDL triggers ([#69])
+- DataGrid row height increased from 25 to 28 to fix text clipping
+- Skip offline servers during Lite collection and reduce connection timeout ([#90])
+- Mutex crash on Lite app exit ([#89])
+- Permission denied errors handled gracefully in collector health ([#150])
+
## [1.1.0] - 2026-02-13
### Added
@@ -42,6 +119,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Delta normalization for per-second rate calculations
- Dark theme UI
+[1.3.0]: https://github.com/erikdarlingdata/PerformanceMonitor/compare/v1.2.0...v1.3.0
+[1.2.0]: https://github.com/erikdarlingdata/PerformanceMonitor/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/erikdarlingdata/PerformanceMonitor/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/erikdarlingdata/PerformanceMonitor/releases/tag/v1.0.0
[#1]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/1
@@ -54,5 +133,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#18]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/18
[#20]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/20
[#21]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/21
+[#22]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/22
[#23]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/23
[#25]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/25
+[#37]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/37
+[#39]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/39
+[#40]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/40
+[#41]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/41
+[#44]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/44
+[#47]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/47
+[#49]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/49
+[#52]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/52
+[#53]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/53
+[#56]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/56
+[#61]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/61
+[#69]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/69
+[#70]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/70
+[#73]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/73
+[#85]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/85
+[#86]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/86
+[#89]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/89
+[#90]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/90
+[#109]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/109
+[#112]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/112
+[#113]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/113
+[#139]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/139
+[#140]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/140
+[#142]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/142
+[#143]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/143
+[#150]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/150
+[#151]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/151
+[#160]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/160
+[#161]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/161
+[#164]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/164
+[#165]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/165
+[#166]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/166
+[#167]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/167
+[#168]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/168
+[#169]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/169
+[#170]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/170
+[#171]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/171
+[#183]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/183
+[#184]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/184
+[#186]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/186
+[#187]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/187
+[#188]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/188
+[#189]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/189
+[#192]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/192
+[#194]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/194
+[#195]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/195
+[#199]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/199
+[#200]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/200
+[#206]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/206
+[#210]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/210
+[#214]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/214
diff --git a/Dashboard/Dashboard.csproj b/Dashboard/Dashboard.csproj
index 8de16fa1..4f568c24 100644
--- a/Dashboard/Dashboard.csproj
+++ b/Dashboard/Dashboard.csproj
@@ -6,7 +6,7 @@
true
PerformanceMonitorDashboard
SQL Server Performance Monitor Dashboard
- 1.2.0
+ 1.3.0
Darling Data, LLC
Copyright © 2026 Darling Data, LLC
EDD.ico
diff --git a/Installer/PerformanceMonitorInstaller.csproj b/Installer/PerformanceMonitorInstaller.csproj
index 07e9c964..a5091055 100644
--- a/Installer/PerformanceMonitorInstaller.csproj
+++ b/Installer/PerformanceMonitorInstaller.csproj
@@ -20,10 +20,10 @@
PerformanceMonitorInstaller
SQL Server Performance Monitor Installer
- 1.2.0
- 1.2.0.0
- 1.2.0.0
- 1.2.0
+ 1.3.0
+ 1.3.0.0
+ 1.3.0.0
+ 1.3.0
Darling Data, LLC
Copyright © 2026 Darling Data, LLC
Installation utility for SQL Server Performance Monitor - Supports SQL Server 2016-2025
diff --git a/InstallerGui/InstallerGui.csproj b/InstallerGui/InstallerGui.csproj
index 2e41cf44..c9d3797a 100644
--- a/InstallerGui/InstallerGui.csproj
+++ b/InstallerGui/InstallerGui.csproj
@@ -8,7 +8,7 @@
PerformanceMonitorInstallerGui
PerformanceMonitorInstallerGui
SQL Server Performance Monitor Installer
- 1.2.0
+ 1.3.0
Darling Data, LLC
Copyright © 2026 Darling Data, LLC
EDD.ico
diff --git a/Lite/PerformanceMonitorLite.csproj b/Lite/PerformanceMonitorLite.csproj
index 6b51c5fa..5bc6031c 100644
--- a/Lite/PerformanceMonitorLite.csproj
+++ b/Lite/PerformanceMonitorLite.csproj
@@ -7,7 +7,7 @@
PerformanceMonitorLite
PerformanceMonitorLite
SQL Server Performance Monitor Lite
- 1.2.0
+ 1.3.0
Darling Data, LLC
Copyright © 2026 Darling Data, LLC
Lightweight SQL Server performance monitoring - no installation required on target servers
diff --git a/install/25_process_deadlock_xml.sql b/install/25_process_deadlock_xml.sql
index b7e75850..74067fdf 100644
--- a/install/25_process_deadlock_xml.sql
+++ b/install/25_process_deadlock_xml.sql
@@ -55,7 +55,10 @@ BEGIN
@error_number integer,
@blitzlock_database sysname = NULL,
@sql nvarchar(max) = N'',
- @debug_msg nvarchar(500) = N'';
+ @debug_msg nvarchar(500) = N'',
+ @utc_offset_minutes integer = DATEDIFF(MINUTE, SYSUTCDATETIME(), SYSDATETIME()),
+ @start_date_local datetime2(7) = NULL,
+ @end_date_local datetime2(7) = NULL;
BEGIN TRY
BEGIN TRANSACTION;
@@ -142,16 +145,33 @@ BEGIN
END;
END;
+ /*
+ Convert UTC dates to local time for sp_BlitzLock and comparison
+ with collect.deadlocks.event_date (which sp_BlitzLock stores in local time).
+ event_time in collect.deadlock_xml stores UTC (from XE timestamps).
+ sp_BlitzLock converts @StartDate/@EndDate from local time to UTC internally.
+ */
+ SELECT
+ @start_date_local = DATEADD(MINUTE, @utc_offset_minutes, @start_date),
+ @end_date_local = DATEADD(MINUTE, @utc_offset_minutes, @end_date);
+
+ IF @debug = 1
+ BEGIN
+ SET @debug_msg = N'UTC offset: ' + CAST(@utc_offset_minutes AS nvarchar(10)) + N' minutes. Local dates: ' + ISNULL(CONVERT(nvarchar(30), @start_date_local, 121), N'NULL') + N' to ' + ISNULL(CONVERT(nvarchar(30), @end_date_local, 121), N'NULL');
+ RAISERROR(@debug_msg, 0, 1) WITH NOWAIT;
+ END;
+
/*
Delete existing parsed deadlocks for the time range to prevent duplicates
sp_BlitzLock will re-insert fresh parsed data
+ Uses local-time dates because sp_BlitzLock stores event_date in local time
*/
IF @start_date IS NOT NULL AND @end_date IS NOT NULL
BEGIN
DELETE d
FROM collect.deadlocks AS d
- WHERE d.event_date >= @start_date
- AND d.event_date <= @end_date;
+ WHERE d.event_date >= @start_date_local
+ AND d.event_date <= @end_date_local;
SELECT
@rows_deleted = ROWCOUNT_BIG();
@@ -175,8 +195,8 @@ BEGIN
@TargetTableName = N''deadlock_xml'',
@TargetColumnName = N''deadlock_xml'',
@TargetTimestampColumnName = N''event_time'',
- @StartDate = @start_date,
- @EndDate = @end_date,
+ @StartDate = @start_date_local,
+ @EndDate = @end_date_local,
@OutputDatabaseName = N''PerformanceMonitor'',
@OutputSchemaName = N''collect'',
@OutputTableName = N''deadlocks'',
@@ -184,20 +204,21 @@ BEGIN
EXECUTE sys.sp_executesql
@sql,
- N'@start_date datetime2(7), @end_date datetime2(7), @debug bit',
- @start_date = @start_date,
- @end_date = @end_date,
+ N'@start_date_local datetime2(7), @end_date_local datetime2(7), @debug bit',
+ @start_date_local = @start_date_local,
+ @end_date_local = @end_date_local,
@debug = @debug;
/*
Verify sp_BlitzLock produced parsed results before marking rows as processed
If no results were inserted, leave rows unprocessed so they are retried next run
+ Uses local-time dates because sp_BlitzLock stores event_date in local time
*/
SELECT
@rows_parsed = COUNT_BIG(*)
FROM collect.deadlocks AS d
- WHERE d.event_date >= @start_date
- AND d.event_date <= @end_date
+ WHERE d.event_date >= @start_date_local
+ AND d.event_date <= @end_date_local
OPTION(RECOMPILE);
IF @rows_parsed > 0