You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mute rules created via the GUI with Expires After: Never (permanent) are silently lost across application restarts. The
same behavior reproduces consistently — three independent samples observed over a 3-day window, each verified before and
after restart via the MCP server's get_mute_rules tool.
This affects any user who relies on mute rules to suppress recurring alerts: rules must be re-created after every restart,
even though the UI lets the user pick "Never" as the expiration.
Steps to Reproduce
Open PerformanceMonitorLite GUI.
Right-click an alert → Add Mute Rule (or use the Mute Rules dialog).
In Edit Mute Rule, fill in match criteria (e.g. server, metric, database) and select Expires After: Never (permanent).
Save the rule.
Verify the rule exists — either via the GUI's mute-rule list, or via the MCP get_mute_rules tool. Confirm expires_at_utc: null.
Close the application (Exit from system tray) and reopen it.
Query the mute rules again — the permanent rule is gone.
Expected Behavior
A mute rule with expires_at_utc = NULL should persist indefinitely, including across restarts. This is what the "Never
(permanent)" UI option implies.
Actual Behavior
The rule is missing after restart. This happens regardless of how recently the rule was created (we observed it for rules
that were minutes old, hours old, and 2 days old — all permanent, all gone after restart).
Error Messages / Log Output
## Evidence — 3 Independent Samples
All times below are Asia/Taipei (UTC+8). All `get_mute_rules` queries were issued via the bundled MCP server
(`http://localhost:5151/`).
| # | Rule | Created (TST) | Verified Existed (TST) | Restart(s) Between | Verified Missing (TST) |
|---|------|---------------|------------------------|---------------------|------------------------|
| 1 | server=`192.168.122.166`, metric=`Blocking Detected`, database≈`tempdb`, expires=NULL | 2026-05-04 13:25:49 |
2026-05-04 ~14:00 (`get_mute_rules` returned the rule) | At least 3 restarts | 2026-05-06 14:46 (`get_mute_rules` returned
`total_count: 0` for this rule) |
| 2 | server=`192.168.123.200`, metric=`Long-Running Job`, job≈`GOP2_DAILY`, expires=NULL | 2026-05-06 14:53:04 | 2026-05-06
~15:00 (`get_mute_rules` returned the rule) | 1 restart (associated with binary directory move from D:\ to C:\) | 2026-05-06
18:09 (`get_mute_rules` returned `total_count: 0`) |
| 3 | (new permanent rule, GUI screenshot taken before restart) | 2026-05-07 ~01:00 | Verified in GUI | 1 restart | Missing
immediately after restart |
In every case, `expires_at_utc` was explicitly `null` (verified in `get_mute_rules` JSON output for samples 1 and 2). These
were not 24-hour-default rules expiring naturally.
## Hypothesis
Each restart appears to perform a heavy `monitor.duckdb` operation. We observed:
- 2026-05-06 14:24 restart: `monitor.duckdb` shrank from 562 MB → 143 MB (-75%)
- 2026-05-06 18:07 restart (after binary move): shrank to 55 MB (-91% from peak)
This is consistent with a vacuum, schema rebuild, or table re-creation step on startup. The most plausible mechanism is that
the startup path (re)creates the `mute_rules` table or its parent without re-loading existing rows from a persistent source.
A simpler alternative — that mute rules are kept in memory and only lazily flushed — also fits the symptom but doesn't
explain rules surviving for hours/days before restart.
## Environment
- **PerformanceMonitorLite**: built from binaries dated 2026-04-29 to 2026-05-05 (file modification times in the install dir;
I don't see a version string surfaced in the GUI — please advise where to find one)
- **Bundled MCP server**: enabled, port 5151
- **OS**: Windows 11 Pro 10.0.26200
- **Install paths observed**:
- Original: `D:\PerformanceMonitorLite\` (HDD)
- After move: `C:\PerformanceMonitorLite\` (SSD)
- Behavior is identical at both paths.
- **Data dir**: `%LOCALAPPDATA%\PerformanceMonitorLite\` containing `monitor.duckdb`, `archive\`, `logs\`, `config\`,
`alert_state.json`
- **Monitored servers**: 8 SQL Server instances (mix of SQL 2008 R2, 2016, 2019, 2022)
Screenshots
Additional Context
Additional Notes
settings.json has mute_rule_default_expiration: "24 hours", but this only sets the GUI default — the bug reproduces
even when the user explicitly overrides this in the dialog.
alert_state.json contains SilencedServers and AcknowledgedAlerts but not the mute rules themselves, so they are not
stored as JSON.
None — every restart requires manually re-creating any mute rules. A possible workaround on the user side is backing up monitor.duckdb while the daemon is stopped and restoring after a known restart, but this is fragile and loses any data
collected between backup and restore.
Component
Lite
Performance Monitor Version
2.10
SQL Server Version
SQL Server 2019
Windows Version
Windows 11 25H2
Describe the Bug
Mute rules created via the GUI with
Expires After: Never (permanent)are silently lost across application restarts. Thesame behavior reproduces consistently — three independent samples observed over a 3-day window, each verified before and
after restart via the MCP server's
get_mute_rulestool.This affects any user who relies on mute rules to suppress recurring alerts: rules must be re-created after every restart,
even though the UI lets the user pick "Never" as the expiration.
Steps to Reproduce
Edit Mute Rule, fill in match criteria (e.g. server, metric, database) and selectExpires After: Never (permanent).get_mute_rulestool. Confirmexpires_at_utc: null.Expected Behavior
A mute rule with
expires_at_utc = NULLshould persist indefinitely, including across restarts. This is what the "Never(permanent)" UI option implies.
Actual Behavior
The rule is missing after restart. This happens regardless of how recently the rule was created (we observed it for rules
that were minutes old, hours old, and 2 days old — all permanent, all gone after restart).
Error Messages / Log Output
Screenshots
Additional Context
Additional Notes
settings.jsonhasmute_rule_default_expiration: "24 hours", but this only sets the GUI default — the bug reproduceseven when the user explicitly overrides this in the dialog.
alert_state.jsoncontainsSilencedServersandAcknowledgedAlertsbut not the mute rules themselves, so they are notstored as JSON.
Workaround Currently in Use
None — every restart requires manually re-creating any mute rules. A possible workaround on the user side is backing up
monitor.duckdbwhile the daemon is stopped and restoring after a known restart, but this is fragile and loses any datacollected between backup and restore.