Repository navigation
fix(performance): fit trends against time and treat idle caches as no data - #274
Conversation
… data Follow-ups from the review of #270/#272, now that history is live: - Trends regressed over the sample index, but snapshots are unevenly spaced (the analytics timer and every wp_performance_history call add one), and "one sample ahead" was labelled a 30-minute prediction; predictPerformance(timeframeMinutes) ignored its horizon. Trends now fit against timestamps and predict prediction.timeframe past the newest point; a direction needs a fitted change above the metric's noise floor (the fixed 0.1 slope meant ms for one metric and 10 percentage points for another). - A cache with no lookups is neutral, not 0%: idle points are left out of the hit-rate trend and of history's averageCacheHitRate (null if none had lookups), and hit-rate strings read "n/a (no lookups yet)" in wp_cache_stats, wp_cache_info and wp_performance_stats. - History windows are inclusive at both ends: pruning used ">" while getHistoricalData(start) used ">=". - History/export scope labels say the chart series are sampled to at most 100 points; downsample(items, 0) returns no items; the supported timeframes come from the parseTimeframe map instead of a second list. Tests: 18 new; suite 2778 passed before, 2796 after, 0 failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Reviewer's GuideUpdates performance analytics to use timestamp-based trend fitting and horizon-aware predictions, treats idle caches as having no hit-rate data, makes retention boundaries inclusive, and clarifies/enforces chart sampling and timeframe metadata across tools and documentation. Sequence diagram for timestamp-based performance trend predictionsequenceDiagram
participant Caller
participant PerformanceAnalytics
participant TrendAnalysis
Caller->>PerformanceAnalytics: predictPerformance(timeframeMinutes)
PerformanceAnalytics->>TrendAnalysis: analyzeTrends(timeframeMinutes * 60 * 1000)
TrendAnalysis->>TrendAnalysis: Fit points using timestamp
TrendAnalysis->>TrendAnalysis: Exclude idle cache points from cacheHitRate
TrendAnalysis->>TrendAnalysis: Compare observed change with anomalyNoiseFloor
TrendAnalysis-->>PerformanceAnalytics: PerformanceTrend with prediction.timeframe
PerformanceAnalytics-->>Caller: Predictions and alerts for requested horizon
Flow diagram for idle cache hit-rate handlingflowchart LR
Snapshot[Cache snapshot] --> Activity{hasCacheActivity}
Activity -->|No lookups| NoData[No hit-rate data]
Activity -->|Has lookups| Rate[Use hit rate]
NoData --> Format[formatHitRate]
Rate --> Format
Format --> Output["Percentage or n/a (no lookups yet)"]
NoData --> Average[Exclude from averageCacheHitRate]
Rate --> Average
Average --> Summary[Fraction or null]
Flow diagram for sampled historical chart outputflowchart LR
History[Historical snapshots] --> Metrics[All-snapshot metrics and summary]
History --> Downsample["downsample(items, MAX_HISTORY_POINTS)"]
Downsample --> Chart[Chart series at most 100 points]
Metrics --> Counts[dataPoints and historicalDataPoints count all snapshots]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
🟢 Approval recommended
The implementation consistently addresses the described analytics defects with focused regression coverage and matching documentation.
0 open findings
What changed in this PR
Corrects performance analytics for uneven sampling, idle caches, and inclusive history boundaries.
Changes:
- Regresses trends by timestamp and honors prediction horizons.
- Treats idle-cache hit rates as unavailable.
- Aligns retention boundaries, sampling labels, tests, and documentation.
| File | Description |
|---|---|
src/performance/PerformanceAnalytics.ts |
Adds time-based trends, horizon-aware predictions, and inclusive expiry. |
src/performance/PerformanceMonitor.ts |
Makes retention boundaries inclusive. |
src/tools/performance/PerformanceHelpers.ts |
Adds hit-rate formatting and improves timeframe/downsampling logic. |
src/tools/performance/PerformanceTools.ts |
Applies idle-cache semantics and sampling labels. |
src/tools/cache.ts |
Formats inactive cache hit rates as unavailable. |
src/performance/AGENTS.md |
Documents performance analytics contracts. |
docs/PERFORMANCE_MONITORING.md |
Updates user-facing behavior documentation. |
tests/performance/HistoryWindow.test.js |
Tests boundaries, trends, horizons, and idle caches. |
tests/performance/OutputScope.test.js |
Tests summaries and sampling scope labels. |
tests/tools/cache.test.js |
Tests idle-cache output. |
tests/tools/performance/PerformanceHelpers.test.js |
Tests helper edge cases and formatting. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 062b5330c1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Review follow-up (Codex on #274): wp_performance_stats showed the hit rate as "n/a (no lookups yet)" next to efficiency "Poor", because calculateCacheEfficiency() scored the undefined 0% hit rate. calculateCacheEfficiency() now returns "n/a (no lookups yet)" when the cache has had no lookups, like formatHitRate(). Tests: 1 new (failed before the fix); suite 2797 passed, 0 failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## [4.1.6](v4.1.5...v4.1.6) (2026-10-12) ### 🐛 Bug Fixes * **performance:** fit trends against time and treat idle caches as no data ([#274](#274)) ([2996b29](2996b29)), closes [270/#272](https://github.com/270/mcp-wordpress/issues/272)
|
🎉 This PR is included in version 4.1.6 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Pull Request
Description
Follow-ups from the review of #270 and #272. History is live now, so code that never received data before is running for the first time.
wp_performance_historycall add one. "One sample ahead" was labelled a 30-minute prediction, andpredictPerformance(timeframeMinutes)ignored its horizon, although its alerts say "in N minutes". The direction threshold was a fixed slope of0.1, which meant 0.1 ms per sample for response time but 10 percentage points for the hit rate.averageCacheHitRateaveraged them in;wp_cache_stats,wp_cache_infoandwp_performance_statsprinted"0.0%".>, whilegetHistoricalData(start)used>=.downsample(items, 0)returned one item, and the supported timeframes were a second hand-kept list next to theparseTimeframemap.Type of Change
Changes Made
timestamp, falling back to the index only when all points share one timestamp;prediction.timeframepast the newest point (30 min, orpredictPerformance's horizon);averageCacheHitRate(nullif no snapshot had lookups);"n/a (no lookups yet)"via the newformatHitRate().downsample(items, 0)returns[];SUPPORTED_TIMEFRAMESis derived from the map.src/performance/AGENTS.mdanddocs/PERFORMANCE_MONITORING.mdupdated.Related Issues
Related to #270 and #272 (review follow-ups).
Testing
Tests Performed
npm test): 2778 passed before, 2796 passed after, 0 failedbuild,typecheck,lint,format:check,security:scanmain, the 10 new behavioural tests and the 3 extended export-label cases failed. 8 guard cases pass both ways:downsamplewithin budget and keeping both ends, and every timeframe being known.Test Cases
predictPerformance(60)predicts 1300.stablehit-rate trend, notimproving.averageCacheHitRate= 0.85 over (idle, 0.8, 0.9), andnullfor idle-only history;hit_rateshowsn/a (no lookups yet).downsampleedge cases; everyparseTimeframekey is a supported timeframe.One mid-fix finding: a first version based "direction" on the prediction horizon. That broke an existing test, rightly so: a steady memory climb from 60% to 96% read as
stable. Direction now describes the observed span, so the same history can't change direction with the horizon.Breaking Changes
None in shape, apart from two narrowed values:
averageCacheHitRatecan benull, and hit-rate strings can readn/a (no lookups yet)before the first cache lookup.Documentation
🤖 Generated with Claude Code
Summary by Sourcery
Fix performance analytics to model uneven history accurately and represent idle caches as having no data.
Bug Fixes:
Enhancements:
Documentation:
Tests: