Complete User Documentation

MageMonitor
Store Health Dashboard

Professional real-time monitoring, automated detection, and one-click fixes for your Magento 2 store. Know about problems before your customers do.

Magento 2.4.x PHP 8.1 – 8.5 by PointOfCode

What is MageMonitor?

MageMonitor is a comprehensive store health monitoring extension for Magento 2. It continuously scans your server, database, cron system, cache layer, frontend, and security posture — then surfaces actionable findings directly in your Magento admin panel with exact instructions to fix each issue.

Automated Detection
10 specialized detectors run on schedule, checking over 100 conditions across server, database, cache, cron, frontend, security, search, performance, extensions, and Magento core.
Real-Time Metrics
Live CPU, RAM, disk, Redis, database connections, slow queries, and Varnish hit rate — all auto-refreshing every 10 seconds without page reload.
Multi-Channel Alerts
Instant notifications via Email, Slack, and Webhook when critical issues are detected. Separate digest schedules per channel. Downtime alerts fire the moment your store goes unreachable.
One-Click Quick Fixes
Flush caches, reindex, clear generated code, optimize database tables, kill zombie crons, warm cache, and more — all from the dashboard with full audit logging.
Security Monitoring
A graded security audit of 39 checks — admin access and 2FA, patch level and PHP support dates, exposed secret files, security headers, web shells and injected skimmer scripts — plus file integrity, brute force detection, an admin account review and a login audit trail.
Traffic & Performance
Real request tracking via sampling, slow page identification, JS error collection from real visitors, CDN analytics, and uptime monitoring with history.

Requirements

ComponentRequirementNotes
Magento2.4.xCommunity and Commerce editions. Constraint: magento/framework ^103.0
PHP8.1 – 8.5CLI binary must be accessible to www-data. Constraint: ~8.1 || ~8.2 || ~8.3 || ~8.4 || ~8.5
DatabaseMySQL 5.7+ / MariaDB 10.4+InnoDB engine required
PointOfCode_CoreRequiredShared PointOfCode module (admin menu, licence validation). Composer pulls it in automatically as pointofcode/module-core ^1.2; for a manual install, upload it to app/code/PointOfCode/Core/ alongside MageMonitor
Magento CronMust be configuredRun as www-data user, not root
RedisOptionalRequired for session/cache monitoring
VarnishOptionalRequired for Varnish hit rate monitoring
AWS SDKOptionalRequired only for AWS Integration feature
Composer2.xFor installation
Cron Must Run as www-data
Magento cron must run as the www-data user (not root). Running as root creates permission issues with generated files and can prevent MageMonitor from reading certain system stats. Verify with: sudo crontab -u www-data -l

Installation

1

Upload the Module

Extract the MageMonitor zip file and upload the MageMonitor folder to your server at app/code/PointOfCode/MageMonitor/ using SFTP or SCP. MageMonitor depends on PointOfCode_Core: if app/code/PointOfCode/Core/ is not already on the server (it is shared by every PointOfCode extension), upload it the same way.

Installing with Composer instead? composer require pointofcode/module-mage-monitor installs both modules; then continue with step 2.

scp -r MageMonitor/ user@server:/var/www/magento/app/code/PointOfCode/
2

Enable the Module

SSH into your server and run these commands as the web user:

sudo -u www-data php bin/magento module:enable PointOfCode_Core PointOfCode_MageMonitor
sudo -u www-data php bin/magento setup:upgrade
sudo -u www-data php bin/magento setup:di:compile
sudo -u www-data php bin/magento setup:static-content:deploy -f
sudo -u www-data php bin/magento cache:flush
sudo systemctl reload php8.2-fpm  # use your PHP-FPM service name

Production mode: setup:upgrade empties pub/static, so always run setup:static-content:deploy in the same window — otherwise the Magento admin returns 500 errors while the storefront still looks fine behind full-page cache. Reloading PHP-FPM makes it drop the previously compiled code; without it the module can appear not to work. Both apply to every future update too.

3

Verify Installation

Check the module is active:

sudo -u www-data php bin/magento module:status PointOfCode_MageMonitor
# Expected output: Module is enabled
4

Enter Your License Key

In the Magento Admin go to Stores → Configuration → PointOfCode → MageMonitor → License and enter your license key. Then go to PointOfCode → MageMonitor in the admin menu to access the dashboard.

5

Optional: Enable Varnish Stats Access

If you use Varnish, add www-data to the varnish group for full statistics access:

sudo usermod -a -G varnish www-data
sudo systemctl restart php8.1-fpm  # or php8.2-fpm
Installation Complete
MageMonitor will begin collecting data immediately. The first full scan runs within 5 minutes via cron. The dashboard is accessible at Admin → PointOfCode → MageMonitor.

License Activation

MageMonitor uses domain-based license validation. Your license key is tied to the domain where it is installed and validated automatically on every scan.

1

Go to Configuration

Navigate to Stores → Configuration → PointOfCode → MageMonitor → License

2

Enter License Key

Paste your license key in the format POC-XXXX-XXXX-XXXX-XXXX. This key was emailed to you after purchase from store.pointofcode.com.

3

Save and Validate

Click Save Config. The domain is auto-detected from your Magento base URL. Validation runs automatically in the background every 30 minutes via cron.

Domain Detection
MageMonitor automatically reads your store's base URL for license validation. No manual domain entry is required. If you move the store to a new domain you can change it yourself from My Account › My Licenses on store.pointofcode.com — the old domain stops validating immediately. The number of self-service changes is limited (2 per year by default); contact support if you need more.

General Settings

Master controls for the entire MageMonitor module. Navigate to Stores → Configuration → PointOfCode → MageMonitor → General Settings.

Enable MageMonitor
Default: Yes
Master on/off switch for all MageMonitor monitoring and scanning. When set to No, all cron jobs, plugins, and data collection stop immediately. The dashboard remains accessible but shows no new data.

Performance Monitoring

Controls how MageMonitor tracks request performance and how frequently it scans your server and Magento health. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Performance Monitoring.

Sampling Rate (%)
Default: 10
Percentage of page requests that are tracked for performance analysis. At 10%, 1 in every 10 requests is measured for response time, route, and type. Tracked requests appear in the Slow Requests tab. Reduce to 5% on very high traffic stores (100k+ requests/day) to minimize overhead. Minimum: 1, Maximum: 100.
Slow Page Threshold (ms)
Default: 2000
Requests that take longer than this value (in milliseconds) are logged to the Slow Requests tab. Default is 2000ms (2 seconds). Lower this to 1000ms if you want to track moderately slow pages, or raise it on stores where complex pages naturally take longer.
Enable TTFB / FPC Check
Default: No
When enabled, manual scans (Run Full Scan button) send a self-HTTP request to measure homepage Time to First Byte (TTFB) and Full Page Cache status. Does NOT run during automatic cron scans to prevent performance impact. Adds 2–5 seconds to manual scan time. Enable only when troubleshooting FPC issues.
Server Scan Frequency
Default: Every 5 minutes
How often the server health cron runs. Checks PHP-FPM status, Redis health, OPcache, disk usage, and CPU load. Options: Every 1, 2, 5, 10, or 15 minutes.
Magento Scan Frequency
Default: Every 15 minutes
How often the Magento health cron runs. Checks cache status, indexer states, cron schedule, and Magento-specific configurations. Options: Every 5, 10, 15, or 30 minutes.
Analyse PHP Slow Log
Default: Yes
Reads the tail of PHP-FPM's slow log to identify which module and function slow requests are spending their time in, including N+1 query loops. Read-only. Produces nothing unless PHP-FPM is configured with request_slowlog_timeout and the web user can read the log file.
PHP Slow Log Path
Default: empty (auto-detect)
Leave empty to detect automatically from the PHP-FPM pool config, then from common locations. Set explicitly only if your slow log lives somewhere unusual. Example: /var/log/php-fpm/www-slow.log
Slow Log Lines To Read
Default: 500
How many lines to read from the end of the slow log per scan. Raise for a busier store where 500 lines covers only a few minutes; capped at 5000 so a scan can never read the whole file.
Log Directory Size Warning (MB)
Default: 500
Warn when var/log/*.log together exceed this many megabytes. This is really a statement about the disk — 500 MB is most of a small VPS partition and a rounding error on a large volume — so set it against the space you actually have.
Admin Grid Slow Query Threshold (seconds)
Default: 5
Report admin grid queries (Orders, Products, Customers) still running after this many seconds. Over 10s is reported as a warning and over 30s as high severity, regardless of this value.

Store Intelligence

Deep background analysis that runs every 3 hours and surfaces proactive recommendations about your database, cron system, and performance configuration. All checks are strictly read-only. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Store Intelligence.

Enable Background Scan
Default: Yes
Master switch for the Store Intelligence background cron which runs every 3 hours. The category toggles below apply to both background scans and manual scans via the Run Full Scan button.
Enable Database Intelligence
Default: Yes
Checks database storage capacity, oversized grid tables, async grid indexing status, known bloat tables (queues and logs with no retention), and missing database indexes that are causing slow queries.
Enable Cron Intelligence
Default: Yes
Checks that Magento cron is running at all (no job started for 15+ minutes), cron jobs failing on their latest run (with Magento's error message, the likely cause and the fix), cron backlog (pending jobs overdue by 30+ minutes), cron running as root (causes permission errors), schedule table bloat, and stuck cron jobs.
Enable Performance Intelligence
Default: Yes
Checks flat catalog configuration on large stores and Full Page Cache backend (recommends Varnish on large catalogs). OPcache, Redis memory, and InnoDB buffer pool are covered by Server Monitoring instead.

Database Thresholds

DB Total Storage (GB)
Default: 0 (auto-detect)
Total provisioned database volume size in GB. Used for the storage-full percentage calculation. Set this manually if using AWS RDS (e.g. 500 for a 500GB RDS instance) because MySQL cannot detect the RDS volume size. Leave 0 to auto-detect from the local filesystem (works on non-RDS installations).
DB Storage Critical (%)
Default: 90
Trigger a CRITICAL alert when database storage exceeds this percentage of total capacity. At 100% usage, MySQL becomes read-only and the store stops functioning. Keep this at 90% or lower.
DB Storage Warning (%)
Default: 80
Trigger a HIGH alert when database storage exceeds this percentage. Gives advance warning before reaching the critical threshold.

Cron Thresholds

Cron Backlog Maximum
Default: 100
Trigger a WARNING when more than this many cron jobs are pending and overdue by 30+ minutes. A large backlog indicates cron is not running or is severely behind. Increase on large stores where many jobs accumulate normally.
cron_schedule Max Rows
Default: 1,000,000
Warn when the cron_schedule table exceeds this many rows. An oversized cron_schedule table slows down cron dispatch. The daily cleanup cron automatically purges old success/missed/failed entries.

Performance Thresholds

Flat Catalog Product Threshold
Default: 50,000
Warn when flat catalog is enabled and product count exceeds this value. On large catalogs, flat catalog rebuild time often exceeds the benefit it provides. Recommendation: disable flat catalog on stores with more than 50,000 products.
Varnish-Required Product Threshold
Default: 10,000
Recommend Varnish as FPC backend when product count exceeds this value and the store is currently using built-in PHP cache. For stores with large catalogs, Varnish is essential for acceptable storefront performance.

Cache Health Monitoring

Read-only health checks for Varnish, Redis, Magento FPC, and OPcache. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Cache Health Monitoring.

Enable Cache Health Monitoring
Default: Yes
Master switch for the Cache Health detector. Each service (Varnish, Redis, FPC, OPcache) is probed only when present on the server — missing services are skipped silently without triggering alerts.
Varnish Hit Rate Critical Threshold (%)
Default: 20
Trigger a CRITICAL alert when the Varnish cache hit rate drops below this percentage. Important: stores with many logged-in customers typically achieve 35–45% hit rate, which is normal. Set this threshold lower (15–20%) for such stores to avoid false alerts.
Varnish Hit Rate Warning Threshold (%)
Default: 40
Trigger a WARNING when hit rate drops below this percentage. Use this to catch gradual degradation before it becomes critical. Adjust based on your store's typical hit rate pattern.
Redis Operations Warning (ops/sec)
Default: 10000
Raise a WARNING when Redis sustains more operations per second than this. A store serving cached pages sits far below this, so a high rate usually means traffic is reaching PHP that Varnish should have served. A HIGH alert fires at twice this value, capped at the critical threshold below.
Redis Operations Critical (ops/sec)
Default: 50000
Raise a CRITICAL alert at this operation rate. Raise both values on stores that legitimately run a high cache rate, to avoid recurring alerts.

Database Monitoring

Thresholds for the database checks: which tables appear under “Database Cleanup Opportunities” on the Database tab, plus concurrent slow queries, indexer changelog backlog and url_rewrite growth. MageMonitor never deletes data — it only provides copy-paste SQL suggestions. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Database Monitoring.

Table Size Threshold (MB)
Default: 100
Flag any table larger than this value (data + indexes combined, in MB). Increase this threshold on large production stores (e.g. 500MB) to reduce noise and show only significantly large tables.
Table Row-Count Threshold
Default: 500,000
Flag any table with more rows than this threshold. Large stores with millions of orders, customers, or log entries should increase this to 2,000,000 or more to avoid constant notifications about expected table sizes.
Slow Query Threshold (seconds)
Default: 10
A query running longer than this counts as slow. Checked every 2 minutes, because a query pile-up forms and clears within minutes.
Concurrent Slow Query Alert Count
Default: 3
Number of slow queries running at once before the finding escalates to HIGH. One slow query is survivable; several at once is what exhausts PHP-FPM workers and takes a store down. HIGH also needs one query running past 1.5× the threshold above, and CRITICAL needs half again as many queries with one past 3× it — so both gates move with the two values you set here rather than sitting at fixed seconds.
Changelog Warning Rows
Default: 50000
Flag an indexer changelog (*_cl) table holding more than this many undrained rows. Rows only accumulate when the indexer is not draining them, which is why product and price edits stop reaching the storefront.
Changelog Critical Rows
Default: 500000
Escalate the changelog finding to HIGH when any single table exceeds this. HIGH is also raised when all changelog tables together exceed 1,000,000 rows.
url_rewrite Row-Count Threshold
Default: 2000000
Warn when the url_rewrite table holds more than this many rows. Store views multiply this table, so a large catalogue across several store views can legitimately hold millions of rows — raise it rather than leaving the finding permanently open.

Server Load Monitoring

Thresholds for PHP-FPM worker saturation, unrecognised CPU consumers, disk headroom and Redis pressure. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Server Load Monitoring.

Saturation Is Measured Against Your Real Pool
PHP-FPM saturation is calculated against the pool’s actual pm.max_children, read from your pool configuration — not against a guessed number. A server with 10 workers and one with 200 are judged on the same scale.
PHP-FPM Saturation High (%)
Default: 80
Raise a HIGH alert when this percentage of the worker pool is busy. An earlier WARNING fires at three quarters of this value (60% at the default), so the early-warning band moves with whatever you set here.
PHP-FPM Saturation Critical (%)
Default: 95
Raise a CRITICAL alert at this saturation level. At 100% new visitor requests start failing outright with 502 and 503 errors, so leave room below that.
External Process CPU Warning (%)
Default: 30
Report a process that is neither the store, its services, nor a known security tool using at least this much CPU. Known agents such as CrowdStrike and ClamAV are recognised and excluded.
External Process CPU Critical (%)
Default: 50
Raise a CRITICAL alert when an unrecognised process reaches this share of CPU. Sustained unexplained CPU on a web server is also what a cryptominer looks like, which is why this is treated as urgent rather than as a performance note.
Low Disk Space Warning (% free)
Default: 15
Report a volume with less than this percentage free. Lower it on large volumes, where 15% is far more headroom than the store will ever use and the finding would otherwise stay open permanently.
Disk Space Critical (% free)
Default: 5
Raise a CRITICAL alert below this percentage free. When a Magento volume fills, the store stops taking orders rather than slowing down, so leave real margin here.
Redis Memory High (% of maxmemory)
Default: 80
Raise a HIGH alert when Redis reaches this share of its configured maxmemory. Only applies when a limit is set; with no limit there is no percentage to measure against.
Redis Connections High (% of maxclients)
Default: 80
Raise a HIGH alert when connected clients reach this share of the Redis maxclients limit. At the limit Redis refuses new connections outright, which reaches customers as error pages rather than slow ones.
Redis Client Count Warning
Default: 500
Warn when Redis holds more than this many connected clients regardless of its own limit. Roughly one connection per PHP worker is normal, so raise this if several application servers share one Redis instance.
Redis Fragmentation Ratio Warning
Default: 1.5
Warn when Redis holds this many times more memory from the operating system than the data it actually contains. Nothing is broken at this level — the cost is wasted RAM — so raise it on hosts with memory to spare.


Security Settings

Controls for file integrity monitoring sensitivity and brute force detection thresholds. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Security Settings.

File Integrity Chunk Size
Default: 200
Number of files to SHA-256 hash per cron run. The file integrity check runs every 4 hours, processing this many files per run in chunks to avoid server overload. Reduce on slower servers.
Brute Force Threshold
Default: 5
Number of failed admin login attempts within one hour that triggers a CRITICAL security alert. Default is 5 — set lower (3) for stricter security on stores with sensitive data.

Alert General Settings

Settings that apply to all alert channels (Email, Slack, and Webhook). Navigate to Stores → Configuration → PointOfCode → MageMonitor → Alert General Settings.

Alert Timezone
Default: UTC
Timezone used for timestamps in all alert channels. Set this to your local timezone so alert timestamps match your working hours. Example: Africa/Cairo for Egypt (UTC+2).
Store Name in Alerts
Default: empty (uses store name)
Override the store name shown in alert email subjects and Slack messages. Useful when managing multiple stores — set a short distinctive name like "Elaraby PROD" or "Store A". Leave empty to use the default Magento store name.
Email Subject Tag
Default: empty
Optional text placed at the front of every MageMonitor email subject — health reports, outage alerts and certificate alerts alike. Example: [Store Monitor]. Its purpose is filing: one constant string at the front of the subject is what lets you write a single Gmail or Outlook rule that labels, archives or routes every monitoring email. Leave empty for no tag.

Email Alerts

Configure email notifications for health issues, score drops, and downtime events. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Email Alerts.

Subject line format

Every alert subject opens with the severity, followed by your store name. Subjects are plain text with no emoji, so they survive strict spam filters and older mail clients — and so you can filter on them reliably.

SituationSubject
A critical findingCRITICAL: Your Store — Database Overloaded (5 slow queries)
A high-severity findingHIGH: Your Store — PHP-FPM Workers 92% Saturated
Warnings onlyWARNING: Your Store — 2 issues detected
A known finding got worseESCALATED to CRITICAL: Your Store — PHP-FPM Workers 96% Saturated
A finding cleared, others remainRESOLVED: Your Store — Redis Evicting Keys cleared, 2 still open
A finding cleared, nothing leftRESOLVED: Your Store — Redis Evicting Keys cleared, nothing open
Score improved since the last alertRECOVERED: Your Store — score improved to 88/100
Nothing outstandingALL CLEAR: Your Store — score 88/100
An endpoint stopped respondingOUTAGE ALERT: Checkout — Your Store
A test send[TEST] CRITICAL: Your Store — Sample: 5 Concurrent Slow DB Queries

Tip: because the severity is the first word, you can route alerts in your mail client without pattern-matching the whole subject — for example, send anything starting with CRITICAL: to your phone and leave the rest in your inbox.

Your store name comes from Stores → Configuration → General → Store Information → Store Name. If that is blank, alerts fall back to "Magento Store", so it is worth setting before you enable alerting.

Enable Email Alerts
Default: No
Master switch for all email notifications. Must be enabled for any email alerts to send.
Alert Recipients
Required when enabled
Comma-separated list of email addresses to receive alerts. Example: admin@store.com,tech@store.com. All listed addresses receive every alert — there is no per-recipient severity filtering.
Email Sender
Default: General Contact
Magento email sender identity to use for alert emails. Uses your existing Magento email sender configuration. Options: General Contact, Sales Representative, Customer Support, etc.
Health Score Threshold
Default: 70
Send an alert when the overall health score first drops below this value. It fires once on the way down, not repeatedly while the score sits there, and re-arms once the score recovers above it. Set 0 to switch this trigger off entirely and rely on the per-issue alerts alone.
Minimum Severity for Alert
Default: High & Above
Which findings are allowed into an alert at all. Anything below this level still appears on the dashboard, it is just not emailed. Only Critical and High findings ever interrupt you on their own — Warning and Info arrive with the scheduled report, so widening this makes alerts longer rather than more frequent.
Scheduled Report Frequency
Default: Once a day
How often to email the current state of the store, whether or not anything has changed. Choose Every 6 hours for a working picture four times a day, or Once a day for a morning summary. Set Off to receive nothing but the event alerts described above. Intervals available: hourly, 2, 3, 4, 6, 8, 12 and 24 hours.
Send the Scheduled Report
Default: When anything is open
What has to be true for the report to go out. When anything is open — the default — reports every finding at or above your Minimum Severity, which is the setting to choose if you want a regular picture of the store. Only when something urgent is open keeps the report for Critical and High and stays silent otherwise. Always sends on every slot even when nothing is wrong — the all-clear doubles as proof that scanning and delivery are both still working, which is worth the extra message on an unattended store.
First Report of the Day At
Default: 08:00
The hour the schedule is counted from, in your Alert Timezone. At 08:00 a 6-hourly report arrives at 08:00, 14:00, 20:00 and 02:00; a daily one arrives at 08:00. Choose the hour you start work, so the first report of the day is waiting for you rather than eight hours stale.
Send Email on Downtime / Recovery
Default: Yes
When enabled, an immediate email is sent the moment any monitored URL goes DOWN, and another email when it RECOVERS. These are separate from the regular health digest and fire within 3 minutes of detecting the outage (on the next uptime check cron run).
Test Your Email Setup
After configuring email alerts, use the Quick Fixes → Test Alert button in the MageMonitor dashboard to send a test notification and confirm delivery.

Slack Notifications

Receive MageMonitor alerts directly in your Slack workspace. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Slack Notifications.

1

Create a Slack App

Go to api.slack.com/apps, click Create New App → From Scratch, give it a name like "MageMonitor", and select your workspace.

2

Enable Incoming Webhooks

In your app settings, go to Incoming Webhooks, toggle it on, then click Add New Webhook to Workspace. Select the channel to post alerts to.

3

Copy the Webhook URL

Copy the generated webhook URL (format: https://hooks.slack.com/services/T.../B.../...) and paste it into the Slack Webhook URL field in MageMonitor configuration.

Enable Slack Notifications
Default: No
Requires the Incoming Webhook URL below. Slack alerts follow the same rules as email — new issue, escalation, recovery, scheduled report — on their own schedule.
Slack Webhook URL
Required when enabled
Full Incoming Webhook URL from your Slack App. Format: https://hooks.slack.com/services/TXXXXXXX/BXXXXXXX/XXXXXXXXX
Channel (optional)
Default: webhook default
Optional channel override. Example: #store-alerts. Leave empty to use the channel selected when creating the webhook.
Scheduled Report Frequency
Default: Once a day
How often to post the current state of the store to Slack, whether or not anything has changed. Independent from the email schedule — you can have a daily email and a 6-hourly Slack post. Off leaves Slack with event alerts only.
Post the Scheduled Report
Default: When anything is open
What has to be true for the Slack report to be posted. Always is the option that makes a quiet channel mean something, at the cost of a routine all-clear message.
First Report of the Day At
Default: 08:00
The hour the Slack schedule is counted from, in your Alert Timezone. A 6-hourly report anchored at 08:00 posts at 08:00, 14:00, 20:00 and 02:00.

Webhook Integration

Send MageMonitor health data to any HTTPS endpoint — useful for integrating with custom dashboards, PagerDuty, or other monitoring systems. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Webhook Integration.

Enable Webhooks
Default: No
Requires the endpoint URL below. The endpoint must be reachable from this server and must not resolve to a private or internal address — those are refused, so a webhook cannot be pointed at your own network.
Webhook URL
Required when enabled
HTTPS endpoint to receive POST requests. Must accept Content-Type: application/json. MageMonitor sends a JSON payload with all current detections and store health data.
Webhook Secret
Recommended: 32+ characters
A random secret string used to sign webhook payloads with HMAC-SHA256. The signature is sent in the X-MageMonitor-Signature HTTP header so your endpoint can verify the request authenticity. Use a random generator to create a strong secret.
Scheduled Report Frequency
Default: Once a day
How often to POST the current state of the store to your endpoint, whether or not anything has changed. Independent from the email schedule. Off leaves the endpoint with event alerts only.
Send the Scheduled Report
Default: When anything is open
What has to be true for the scheduled POST to be made. Always gives your endpoint a regular heartbeat it can alert on if it stops arriving — the standard dead-man’s-switch pattern.
First Report of the Day At
Default: 08:00
The hour the webhook schedule is counted from, in your Alert Timezone. A 6-hourly report anchored at 08:00 posts at 08:00, 14:00, 20:00 and 02:00.

Uptime Monitoring

MageMonitor checks your store's uptime every 3 minutes and sends immediate alerts on downtime and recovery. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Uptime Monitoring.

Enable Uptime Monitoring
Default: Yes
When enabled, the storefront homepage is checked every 3 minutes. Two consecutive failures are required before an alert is sent (to avoid false positives from transient errors).
Additional URLs to Monitor
Optional
One URL per line. The storefront homepage is always monitored automatically. Add other critical URLs such as your checkout page, API endpoints, or admin panel. Example:
https://www.store.com/checkout
https://api.store.com/health
Timeout (seconds)
Default: 10
Maximum seconds to wait for each URL check response. If the URL does not respond within this time, it is counted as a failure. Increase for slow APIs or geographically distant endpoints. Decrease for tighter SLA monitoring.
Failures Before Confirming Downtime
Default: 2
Consecutive failed checks before an outage is confirmed and the alert is sent. At the 3-minute check interval, 2 means an alert after roughly 6 minutes of real downtime. Raise it to 3 on a host that drops the occasional connection; lower it to 1 to hear sooner and accept the occasional false alarm.

File Integrity Monitoring

SHA-256 hash monitoring of critical Magento files. Any unexpected change triggers a HIGH severity security alert. Navigate to Stores → Configuration → PointOfCode → MageMonitor → File Integrity Monitoring.

Enable File Integrity Checks
Default: Yes
When enabled, MageMonitor creates SHA-256 hashes of monitored files and compares them against the stored baseline on every scan. Changed hashes trigger a HIGH security alert listing the modified files.
Paths to Monitor
Default: app/etc/env.php, index.php, pub/index.php
One file path per line, relative to the Magento root directory. Default paths cover the most critical files that should never change unexpectedly. You can add custom files such as app/etc/config.php or .htaccess. After adding new paths, the baseline is rebuilt on the next scan.

Frontend Monitoring & Headless Support

JavaScript error collection from real visitor browsers. Captured errors appear in the JS Errors tab. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Frontend Monitoring & Headless Support.

Enable JS Error Collector
Default: No
When enabled, a small JavaScript snippet is injected on every storefront page that catches uncaught JavaScript errors, unhandled Promise rejections, and RequireJS module load failures. Errors are batched and sent to MageMonitor every 3 seconds. The snippet itself is tiny and has negligible performance impact.

Headless / PWA stores: keep this enabled as well. It does more than inject the script — the /magemonitor/jserror/collect endpoint checks this setting on every request and rejects the payload while it is off, so disabling it would make the standalone snippet below collect nothing. Enabling it costs nothing on a headless store, because no Magento storefront pages are rendered to your customers.
JS Errors Per Session
Default: 20
Maximum JavaScript error events collected per visitor browser session. Prevents high-traffic stores from flooding the database when a noisy error fires thousands of times per session. Increase to 50 if you need more detailed JS debugging data for a specific issue.

This setting drives the cap on native Magento frontends only. The standalone snippet below cannot read Magento configuration, so headless stores set the same cap by editing its _max value directly.
JS Error Spike Threshold (distinct errors per hour)
Default: 50
Warn when more than this many distinct JavaScript errors are reported in an hour. This scales with traffic: a store serving a few hundred sessions an hour rarely reaches 50 even when something is genuinely broken, while a very busy store can pass it on browser noise alone. Known extension and browser-internal errors are excluded before counting.
Recurring JS Error Threshold (occurrences)
Default: 100
Report an individual JavaScript error once it has been seen this many times. Reported for the three most frequent errors above the threshold, not for every one.

Headless / PWA Compatibility

MageMonitor is fully compatible with headless and PWA storefronts. Almost all of its value — server health, database, cache, cron, security, uptime, CDN/WAF monitoring, Quick Fixes, and all alerts — runs entirely server-side and works identically regardless of how your storefront is built. The only feature that requires extra setup for headless stores is JS error collection.

Summary
If your store uses a native Magento Luma or Hyvä frontend, enable the toggle above and you are done. If your store uses a headless frontend (React, Vue, Next.js, Nuxt, PWA Studio, or any custom framework), leave the toggle enabled and add the standalone snippet to your frontend, as described below.

Full Compatibility Table

Feature Native Magento Frontend Headless / PWA Frontend
Server, Database, Cache, Cron, Security Monitoring ✓ Full ✓ Full
Quick Fixes ✓ Full ✓ Full
Uptime Monitoring ✓ Full ✓ Full
CDN / WAF Monitoring ✓ Full ✓ Full
Email / Slack / Webhook Alerts ✓ Full ✓ Full
SSL Certificate Monitoring ✓ Full ✓ Full
Traffic Sampling ✓ Full API/GraphQL only
JS Error Collection ✓ Automatic Manual snippet required
Full Page Cache (FPC) Monitoring ✓ Full N/A if FPC bypassed

Headless Setup: Manual JS Error Collection

Copy the snippet below into your frontend application's entry point — for example _app.js (Next.js), main.js (Vue/Nuxt), or your root layout.js. Replace YOUR_MAGENTO_DOMAIN with your store's actual domain.

(function(){
  var _q=[],_t=null,_sent=0,_max=20,_sk='mm_js_sent',
      _ep='https://YOUR_MAGENTO_DOMAIN/magemonitor/jserror/collect',
      _seen=new Set();
  try{_sent=parseInt(sessionStorage.getItem(_sk)||'0',10);}catch(e){}
  function send(errs){
    if(!errs.length||_sent>=_max)return;
    errs=errs.slice(0,_max-_sent);
    var x=new XMLHttpRequest();
    x.open('POST',_ep,true);
    x.setRequestHeader('Content-Type','application/json');
    x.send(JSON.stringify(errs));
    _sent+=errs.length;
    try{sessionStorage.setItem(_sk,String(_sent));}catch(e){}
  }
  function queue(e){
    var fp=e.message+':'+e.source+':'+e.line;
    if(_seen.has(fp)||_sent>=_max)return;
    _seen.add(fp);_q.push(e);
    clearTimeout(_t);
    _t=setTimeout(function(){send(_q.splice(0));},3000);
  }
  window.onerror=function(msg,src,line,col,err){
    queue({message:String(msg),source:String(src||''),
           line:line||0,
           stack:err?String(err.stack||'').substring(0,2000):'',
           url:location.href,ua:navigator.userAgent});
    return false;
  };
  window.addEventListener('unhandledrejection',function(e){
    var r=e.reason;
    queue({message:r?(r.message||String(r)):'Unhandled rejection',
           source:'',line:0,
           stack:r&&r.stack?String(r.stack).substring(0,2000):'',
           url:location.href,ua:navigator.userAgent});
  });
})();

What the Snippet Does

  • Catches uncaught JS errors via window.onerror
  • Catches unhandled Promise rejections via the unhandledrejection event
  • Batches errors with a 3-second debounce — never blocks your UI
  • Deduplicates by message + source + line fingerprint
  • Caps errors per browser session at its _max value. Edit that value to change the cap — the snippet runs outside Magento and cannot read the JS Errors Per Session setting
  • Uses sessionStorage to track the per-session cap across page navigations
  • All collected errors appear in the MageMonitor dashboard → JS Errors tab exactly the same as errors from a native Magento frontend

This is the same collector MageMonitor injects into native Magento pages, with the RequireJS hook removed — headless frontends do not use RequireJS.

Server-Side Collection Limits

The collector endpoint applies its own limits, to both native and headless stores. They are the usual explanation when an error you expected does not appear in the dashboard:

  • At most 10 errors are stored per request. Larger batches are truncated.
  • At most 50 errors and 5 requests per minute, per client IP address. Beyond that the endpoint returns HTTP 429.
  • The endpoint stops accepting new errors once the table holds 50,000 rows.
  • Repeats of an error already stored increment its counter instead of creating a new row.
Do not proxy the collector through your frontend server
Routing collector calls through your Next.js/Nuxt server instead of using CORS is tempting, but every error then reaches Magento from your frontend server's IP address rather than the visitor's. The per-IP limits above would then throttle collection for your entire store within seconds. Post directly from the browser to your Magento domain, as the snippet does. If a proxy is unavoidable, configure Magento to trust your proxy's X-Forwarded-For header first.

CORS Configuration

If your headless frontend is served from a different origin than your Magento backend — for example, your storefront is at shop.example.com and Magento at api.example.com — your web server must allow cross-origin requests to the collector endpoint.

Because the snippet sends Content-Type: application/json, this is not a CORS "simple" request: the browser first sends a preflight OPTIONS request. Magento does not answer OPTIONS on this route, so your web server must answer it. Both configurations below do this. Handling only the POST is the most common mistake — the browser blocks every request before Magento ever sees it.

Apache — add near the top of pub/.htaccess, above Magento's existing rewrite rules. Replace YOUR_FRONTEND_DOMAIN with your exact frontend origin.

# Answer the CORS preflight before Magento's front controller sees it
<IfModule mod_rewrite.c>
  RewriteCond %{REQUEST_METHOD} =OPTIONS
  RewriteCond %{REQUEST_URI} ^/magemonitor/jserror/collect
  RewriteRule ^ - [R=204,L]
</IfModule>

<IfModule mod_headers.c>
  SetEnvIf Request_URI "^/magemonitor/jserror/collect" MM_CORS=1
  Header always set Access-Control-Allow-Origin  "https://YOUR_FRONTEND_DOMAIN" env=MM_CORS
  Header always set Access-Control-Allow-Methods "POST, OPTIONS" env=MM_CORS
  Header always set Access-Control-Allow-Headers "Content-Type" env=MM_CORS
  Header always set Access-Control-Max-Age       "86400" env=MM_CORS
</IfModule>
Do not use <LocationMatch> in .htaccess
<Location> and <LocationMatch> are only valid in server or VirtualHost config. Placing either in an .htaccess file makes Apache fail with "LocationMatch not allowed here" and returns HTTP 500 for every page of your store. Use the SetEnvIf form above in .htaccess; if you are editing your VirtualHost directly, you may wrap the Header lines in <LocationMatch "^/magemonitor/jserror/collect"> instead of using SetEnvIf.

Nginx — this takes two pieces, because Magento serves the endpoint through an internal redirect to index.php, and Nginx applies add_header only in the location that finally generates the response.

# 1. In the http { } context (e.g. /etc/nginx/nginx.conf)
map $request_uri $mm_cors_origin {
    default                         "";
    ~^/magemonitor/jserror/collect  "https://YOUR_FRONTEND_DOMAIN";
}

# 2. In your Magento server { } block, above "location /".
#    Answers the preflight; passes the POST on to Magento.
location = /magemonitor/jserror/collect {
    if ($request_method = OPTIONS) {
        add_header Access-Control-Allow-Origin  "https://YOUR_FRONTEND_DOMAIN" always;
        add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type" always;
        add_header Access-Control-Max-Age       86400 always;
        return 204;
    }
    try_files $uri $uri/ /index.php$is_args$args;
}

# 3. Inside Magento's EXISTING PHP location — the one matching
#    ^/(index|get|static|errors/report|health_check)\.php$ — add:
add_header Access-Control-Allow-Origin  $mm_cors_origin always;
add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type" always;

The map in step 1 makes step 3 safe: $mm_cors_origin is empty for every other URL, and Nginx omits a header whose value is empty. Only the collector endpoint receives CORS headers. Reload with nginx -t && systemctl reload nginx.

Security note
Always name your exact frontend origin (e.g. https://shop.example.com). Never use * — a wildcard lets any website on the internet POST errors into your dashboard.

AWS Integration

Connect MageMonitor to AWS CloudFront, WAF, and CloudWatch for CDN analytics, WAF event monitoring, and infrastructure metrics. Navigate to Stores → Configuration → PointOfCode → MageMonitor → AWS Integration.

AWS SDK Required
The AWS SDK must be installed before enabling this integration. Run on your server: composer require aws/aws-sdk-php
Enable AWS Integration
Default: No
Turn this on only after the AWS SDK is installed and read-only credentials are in place. It unlocks the CloudFront and WAF dashboard tabs and the check for CloudFront serving a cached error page in place of your store.
AWS Access Key ID
Optional on EC2 with IAM role
IAM user Access Key ID with read-only permissions to CloudFront, WAF, and CloudWatch. Leave empty if your server runs on EC2 with an IAM Instance Role — credentials are detected automatically via instance metadata.
AWS Secret Access Key
Encrypted, write-only
The secret paired with the Access Key ID above. Stored encrypted and never displayed again after saving. Leave empty when using an EC2 IAM Instance Role.
AWS Region
Default: empty (auto-detect on EC2)
For example us-east-1. Leave empty for auto-detection on EC2.
CloudFront Distribution ID
Optional
Your CloudFront Distribution ID found in the AWS Console under CloudFront → Distributions. Example: E1ABCDEF123456. Leave empty if not using CloudFront.
WAF Web ACL Name
Optional
The exact name (not ARN) of your AWS WAF Web ACL. Found in AWS Console under WAF & Shield. Leave empty if not using AWS WAF.
WAF Scope
Default: Regional
CLOUDFRONT for WAF attached to a CloudFront distribution. REGIONAL for WAF attached to an ALB or API Gateway.

Cloudflare Integration

Connect to Cloudflare for CDN analytics, cache statistics, and WAF event monitoring. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Cloudflare Integration.

Enable Cloudflare Integration
Default: No
Requires the API token and Zone ID below. Adds CDN cache-hit ratio, bandwidth saved and WAF block activity to the dashboard. Read-only — MageMonitor never changes a Cloudflare setting.
Cloudflare API Token
Required when enabled
Create an API Token at dash.cloudflare.com with these permissions: Zone → Analytics:Read AND Zone → Firewall Services:Read. Do NOT use your Global API Key — use a scoped token for security.
Zone ID
Required when enabled
Found on your Cloudflare dashboard → select your domain → Overview page → right sidebar under "API". It is a 32-character hexadecimal string.

SSL Certificate Monitoring

Automatic SSL certificate expiry monitoring for all store domains. Navigate to Stores → Configuration → PointOfCode → MageMonitor → SSL Certificate Monitoring.

Enable SSL Monitoring
Default: Yes
When enabled, MageMonitor checks SSL certificates for all store domains every 6 hours. Certificate details (issuer, expiry date, days remaining) appear in the SSL Certs dashboard tab.
Additional Domains
Optional
One domain per line. Store domains from all active store views are checked automatically. Add any additional domains such as API subdomains or admin domains.
Warning Threshold (days)
Default: 30
Send a WARNING alert when any SSL certificate expires within this many days. A CRITICAL alert fires automatically at 7 days or fewer regardless of this setting — giving you 7 days of emergency warning even if you reduce the warning threshold.

Advanced Settings

Low-level controls for scanning behavior, HTTP monitoring, and data retention. Navigate to Stores → Configuration → PointOfCode → MageMonitor → Advanced Settings.

Automatic Cron Scanning
Default: Yes
When enabled, all MageMonitor detectors run automatically on their scheduled cron intervals. When disabled, detectors only run when you manually click Run Full Scan in the dashboard. Disable only in development environments or for troubleshooting.
Enable HTTP Client Monitor
Default: No
Disabled by default — this adds overhead to every outbound HTTP/HTTPS request made by Magento's Curl client. When enabled, slow calls (over 5 seconds) and errors are logged. Use only temporarily when troubleshooting third-party API integration issues. Disable immediately after debugging.
Data Retention (days)
Default: 30
Resolved detections older than this many days are automatically deleted by the daily cleanup cron. Open and acknowledged detections are not deleted. Minimum recommended: 14 days. Increase to 90 days if you need longer trend history.
Enable Privileged Quick Fixes
Default: No
Off by default, and safe to leave off. Two Quick Fixes act on system services rather than on Magento: Restart PHP-FPM and Fix Varnish Permissions. Both require that your web server user be granted passwordless sudo for systemctl and usermod.

Understand what that means before enabling it: any person or process able to reach an authenticated admin session gains the ability to restart system services on this host. If that is not a trade you want, leave this off — every other Quick Fix, and all detection, works normally without it. The two actions simply report that they are disabled, and their fix instructions give the command to run by hand instead.

User Roles & Permissions

Every dashboard tab, every tool and the settings screen is a separate permission. You can give an admin user exactly one tab and nothing else. Navigate to System → Permissions → User Roles, open a role, choose the Role Resources tab, set Resource Access to Custom, and tick what that role should see under MageMonitor.

Why This Matters
MageMonitor surfaces server internals, database table sizes, failed admin logins and visitor IP addresses. A marketing manager who needs the Uptime tab does not need any of that. Per-tab permissions let you hand out the one view somebody needs without exposing the rest of your infrastructure.

How Permissions Are Enforced

Each permission is checked in three places, so a hidden tab is genuinely inaccessible rather than merely invisible:

1
The sidebar link is not rendered, so the tab does not appear.
2
The panel markup is not sent to the browser, so the data never reaches the page even in view-source.
3
The AJAX endpoint behind the tab refuses the request, so it cannot be called directly by URL. Detection lists are additionally filtered row by row: a user with the Database tab but not Security never receives a security finding in any payload.

Available Permissions

All of these live under MageMonitor in the Role Resources tree.

Dashboard Tabs

PermissionGrants access toContains
OverviewOverview tabHealth score, category cards, critical and high issues
BacklogBacklog tab, and the Move to backlog / Restore buttons (together with Resolve / Acknowledge Issues)Findings deferred to later; they do not count in the score or alerts
TimelineTimeline tabHealth score trend, open issues over time, recurring findings and the detection/resolution history
Live MetricsLive Metrics tabCPU, RAM, disk, PHP-FPM workers, live slow queries
UptimeUptime tabAvailability, incidents, response times and SLA reports
ServerServer detection tabPHP, Redis, OPcache, disk, web server findings
Magento SystemMagento detection tabCache, indexer and configuration findings
DatabaseDatabase detection tabTable sizes, cleanup opportunities, slow queries
FrontendFrontend detection tabStorefront and JavaScript findings
ExtensionsExtensions tabThird-party module inventory, errors per extension and conflicts
Module Performance (under Extensions)Slowest Extensions section of the Extensions tabExtensions ranked by slow PHP time from the PHP-FPM slow log
PerformancePerformance detection tabMinification, FPC bypass, TTFB, log size
SearchSearch tabSearch engine health and query findings
SecuritySecurity tabSecurity audit and grade, admin accounts, failed logins, file integrity
Cron HealthCron Health tabCron heartbeat, failing jobs with their errors, every job's schedule and history
Cache HealthCache Health tabVarnish, Redis, FPC and OPcache health
Slow RequestsSlow Requests tabSlowest storefront and admin URLs
JS ErrorsJS Errors tabJavaScript errors collected from visitor browsers
CDNCDN tabCloudFront / Cloudflare cache statistics
WAFWAF tabFirewall block activity and blocked IP addresses
SSL CertificatesSSL Certs tabCertificate expiry per domain
InfrastructureInfrastructure tabInstance, region and hosting details
Live TrafficLive Traffic tabRequests in progress, visitor IP addresses, status codes
Server AdvisorServer Advisor tabSizing and tuning recommendations
Audit LogAudit Log tabRecord of who ran what and when

Actions and Tools

PermissionAllows the user toRecommended for
Run ScansTrigger a scan from the dashboard instead of waiting for cronAnyone who needs current data on demand
Resolve / Acknowledge IssuesMark a finding resolved, which hides it until a scan detects it again. With the Backlog permission as well, also move findings to the backlog and restore themWhoever owns triage — this changes what everyone else sees
Quick FixesRun the one-click fixes: flush cache, reindex, clear logs and the restTechnical staff only. These change the running store.
Health ReportGenerate and download the full health reportAnyone who reports to management or a client
SettingsOpen and change MageMonitor configurationAdministrators only. Includes alert recipients and API credentials.

Example Roles

RoleTick theseResult
Store Manager Overview, Uptime, SSL Certificates, Health Report Sees whether the store is healthy and online, and can send a report. No server internals, no visitor data, no fixes.
Developer Everything except Settings and Live Traffic Full diagnostic access including Quick Fixes, but cannot change alert recipients or API credentials, and cannot see visitor IP addresses.
Security Officer Overview, Security, WAF, Live Traffic, Audit Log Sees failed logins, file changes, firewall activity and who did what — and nothing about performance or the database.
External Agency Overview, Performance, Slow Requests, Extensions, Run Scans Enough to diagnose and prove a speed problem, with no access to security data, customer traffic or your configuration.
Roles Created Before You Upgraded
A role whose Resource Access is set to All automatically receives every new permission, including these. A role set to Custom keeps exactly what was ticked when it was last saved — Magento stores an explicit entry for every unticked resource, so newly added permissions are not granted silently. If an existing custom role should see the new tabs, open it, tick them and save. This is why an old role may show every tab while a new one can be narrowed down to a single tab.
If a Tab Does Not Appear
Check three things in order. First, that the role really has the resource ticked and was saved. Second, that the user was logged out and back in — Magento caches the permission set into the admin session. Third, flush the Magento cache. A tab that is still missing after all three is a genuine permission denial, not a bug.

Overview Tab

The landing page of the dashboard: the store’s health score and what is behind it, the health of each area, and every open finding, most serious first.

  • Health score: the score with its rating and change against yesterday’s average, a one-sentence verdict, the calculation (100 minus the points each open finding takes off), when the last full scan ran, and the score over the last 7 days. Gaps in the line are hours when no score was recorded.
  • Severity counts: open critical, high, warning and info findings. Click one to list only that severity.
  • Health by Area: one card per area the admin can open (Server, Magento, Database, Frontend, Extensions, Performance, Search, Security, Cron, Cache) with its status and open findings by severity. Click a card to open that tab.
  • Open Findings: critical, high and warning findings by default (switch to All to include info notes), each with its area, when it was detected and last confirmed, How to fix, Move to backlog and Resolve.

The top bar shows when the last full scan ran.

Health Score

The circular score (0–100) reflects the overall health of your store:

Score RangeColorMeaning
90–100GreenExcellent — no significant issues
70–89GreenGood — minor warnings present
50–69OrangeNeeds Attention — high-severity issues to address
30–49RedPoor — multiple serious issues
0–29RedCritical — requires immediate action

How the score is calculated

The score starts at 100 and each open finding subtracts points according to its severity. Resolved findings cost nothing.

SeverityPoints deducted per finding
Critical25
High10
Warning3
Info1

The score is floored at 0, so a store with many findings cannot go negative. A finding is counted once no matter how many times it has recurred — a warning seen 4,000 times still costs 3 points, not 12,000. The occurrence count tells you how persistent a problem is, not how much it costs.

Worked example: a store with 8 open warnings and 6 open informational findings has lost (8 × 3) + (6 × 1) = 30 points, giving a score of 70 — Good.

Health score on Magento's own dashboard

The score also appears as a compact widget at the top of Magento's built-in Dashboard (Dashboard in the admin menu), so you see it on login without opening MageMonitor. It shows the current score, the count of open findings by severity, and links straight through to the MageMonitor dashboard.

The widget is shown only to admin roles that hold the PointOfCode_MageMonitor::dashboard permission, and it disappears entirely when MageMonitor is switched off in configuration.

Category Cards

Each category card lists its open findings by severity (for example “2 high · 5 warning”) with a dot in the colour of the most severe one: red for critical, orange for high or warning, blue when only informational findings are open, and green when the category is clear. Clicking a card opens that tab. Categories: Server Health, Magento System, Database, Frontend/JS, Extensions, Performance, Security, Search, Cron Health and Cache Health.

Critical & High Issues

All detections with severity Critical or High are listed here with their problem description, how-to-fix instructions, and action buttons. Use Mark as resolved to hide an issue until a scan detects it again, or Move to backlog to defer it (see Backlog Tab).


Backlog Tab

Findings you have decided to deal with later — a PHP or Magento upgrade, a server change that needs a maintenance window. They stay tracked, but stop costing you health-score points and alert emails in the meantime.

  • Move to backlog appears next to Mark as resolved on every open finding, in the category tabs, on the Overview and in the How to fix window. The finding moves to this tab and the sidebar shows how many are waiting.
  • Restore puts a backlogged finding back on the open list, where it counts in the score and alerts again.

How a Backlogged Finding Behaves

QuestionAnswer
Does it lower the health score?No
Does it send alerts?No. Moving it to the backlog is not reported as “resolved” either
Is it still checked?Yes, on every scan, exactly like an open finding
What if the problem is fixed?It resolves on its own, silently
What if it gets worse?If its severity rises (for example Warning to Critical) it returns to the open list and alerts as an escalation
Is it deleted by the cleanup cron?No. Only resolved findings older than the retention period are deleted
Resolve or Backlog?
Mark as resolved is for something you have fixed, or believe is fixed: if the next scan still finds the problem it comes straight back. Move to backlog is for something you know is still there and have chosen to leave for now.

Access needs the Backlog permission under Dashboard Tabs plus Resolve / Acknowledge Issues to move findings in or out — see User Roles & Permissions. Every move is recorded in the Audit Log.


Timeline Tab

How store health changed over the last 24 hours, 7 days or 30 days: the health score, how many issues were open, every finding that was detected or resolved, and the findings that keep coming back.

SectionWhat it shows
SummaryThe health score now and how it moved since the start of the period, the lowest score and when it happened, issues open now by severity, and how many findings were detected and resolved (with the typical time to resolve)
Health ScoreThe score saved every hour (averaged per 3 hours on the 7-day view and per 12 hours on the 30-day view), drawn over the Good / Needs attention / Poor bands. Grey periods have no score because cron was not running
Open IssuesHow many issues were open at any time in each period, stacked by severity. A long-running issue counts in every period it was open, and one that opened and cleared within the hour still shows up
Recurring FindingsFindings detected more than once in the period, with how often, how long they were open in total and whether they are open now
ActivityEvery detection and resolution, newest first and grouped by day, filterable by event type and category. Each entry links to its tab and shows how long the issue was open
Recurring findings
A finding that is resolved and then detected again usually means a value hovering around its alert threshold, or a problem that was treated rather than fixed (for example a cache flush that only helps until the cache fills again). Every return sends a new alert, so these are worth fixing at the source.

The tab only shows categories your admin role can view. Resolved findings are deleted after the Data Retention period (Advanced settings, default 30 days); when the selected period is longer than that, the tab warns that older issue counts are incomplete. Times are shown in your browser’s time zone.


Live Metrics Tab

What the server is doing right now: CPU, memory, disk, PHP-FPM, OPcache and database activity, refreshed every 10 seconds while the tab is open. Use Pause to freeze the numbers; polling also stops while the browser tab is in the background.

A banner at the top lists every metric that needs attention, or confirms that everything is within normal range. Each card has a coloured top edge (green, amber, red) and CPU, memory, connections and response time draw a trend line from the samples taken while the tab is open.

CardWhat it showsFlagged when
CPU usageReal CPU usage measured over a quarter of a second, plus I/O wait, steal time and load average70% (warning), 90% (critical); I/O wait above 20% or steal above 10%
MemoryUsed and available RAM (available includes reclaimable page cache) and swap in use85% / 95% used
DiskOne card per filesystem holding the root, var/ and pub/media directoriesThe Server Health disk thresholds (default 15% / 5% free)
PHP-FPM workersBusy workers against pm.max_children. Without the FPM status page only running processes (busy and idle) can be counted, so the card is informational80% / 95% busy (status page only)
OPcacheMemory used, cached scripts, hit rate, wasted memory and restarts for the PHP-FPM poolDisabled or full (critical), 90% used (warning)
DB connectionsConnections against max_connections, queries running now, and the peak since the database started60% / 80%
DB response timeRound trip of a trivial query50 ms
Database sizeData and index size, InnoDB buffer pool size, and headroom when DB Total Storage (GB) is configured70% / 85% of allocated storage

Slow Queries Running Now

Client queries running longer than the Slow Query Threshold in the Database configuration (default 10 seconds), with user, database, state and SQL. Database background threads (the event scheduler, replication) are never counted. Admins with Quick Fixes access can kill them from here.

Top Processes

The processes using the most CPU at this moment (100% = one full core), with memory, owner and command line. Passwords, tokens and API keys in command lines are masked.

Host

Hostname, operating system, kernel, uptime, CPU model and cores, PHP version and memory limit, and the database version and uptime. On a multi-server setup the metrics describe the web server that answered the request, named in the banner. Configuration recommendations are in the Server Advisor.


Uptime Tab

Current status, 90-day availability, response times, incidents and a monthly SLA report for every monitored endpoint.

The uptime check runs every 3 minutes from Magento cron. A response below 500 counts as up (redirects, 401 and 403 mean the service answered); a 5xx error, timeout or no connection counts as down. An outage is confirmed after the configured number of consecutive failures (default 2), and an email is sent on DOWN and RECOVERY when downtime notifications are enabled. All times are shown in the Alert Timezone.

SectionWhat it shows
Status bannerAll systems operational, degraded (a check failed but is not yet confirmed), partial or major outage — or Monitoring has stopped when no check has run recently because cron is not running
Summary30-day uptime, confirmed incidents, total downtime and monitoring coverage (how much of the period was actually checked)
EndpointsPer endpoint: current status and last result, a 90-day daily availability bar, uptime for 24 hours / 7 / 30 / 90 days, incidents and downtime, average, p95 and slowest response, and a 24-hour response-time chart
IncidentsConsecutive failed checks grouped into incidents with start, duration, cause and recovery. Single failed checks that recover immediately are listed as blips (hidden by default). When monitoring stopped after a failure, the duration shows the observed minimum (≥) instead of counting the unmonitored time as downtime
Monitoring gapsPeriods with no checks at all. Uptime percentages only count checks that ran, so gaps are listed separately rather than hidden
Monthly SLA reportPer month: uptime, pass/fail against a selectable SLA target (99.99% – 99%), downtime, incidents, average response and coverage, with CSV export of every check
Internal checks
Checks run from the store's own server. They detect application, database and PHP failures, but not DNS, CDN, firewall or network problems between customers and the server. Use an external monitor alongside MageMonitor for those.

Detection Tabs

Each detection category has its own tab in the sidebar. Every tab (including Security and Cron Health) opens with a count of open findings by severity and a What this tab checks list, followed by one card per open finding.

Each card shows the problem in plain language, when it was first detected and when a scan last confirmed it, and a How to fix button with step-by-step instructions. Mark as resolved hides a finding until a scan detects the problem again; findings also resolve on their own once the check passes. Move to backlog defers a finding you plan to handle later (see Backlog Tab). A check that cannot be completed (for example when the storefront cannot be reached from cron) leaves its findings unchanged rather than resolving them.

TabWhat It MonitorsScan Frequency
ServerPHP version and extensions, PHP memory limit, PHP-FPM worker saturation and log warnings, free disk space (one finding per disk), Redis version, fragmentation, connections and restarts, session Redis, Varnish reachability, web server configuration (nginx upload size, Apache modules), MySQL version and buffer pool, health check endpoint, CloudFront errors, unexplained CPU-heavy processesEvery 5 min (configurable)
MagentoDeploy mode (developer and default mode), disabled or invalidated cache types, every indexer (reindex required, stuck in processing for over two hours, scheduled backlog that stopped moving), file-based sessions, and order confirmation emails that were never sent. Below the findings the tab shows the deploy mode, every indexer with its mode and queued changes, every cache type, and errors from exception.log and system.log over the last 7 days grouped by message with counts and stack tracesEvery 15 min (configurable)
DatabaseConcurrent slow queries (same threshold as the live list), deadlocks in the last 7 days (needs the MySQL PROCESS privilege), connection pool usage, tables with 200 MB+ reclaimable space (only with innodb_file_per_table), database volume or configured storage close to full, changelog and log-table growth, missing indexes. Below the findings: database size, estimated rows, reclaimable space and buffer pool coverage, slow queries running now, the 20 largest tables with a copyable OPTIMIZE TABLE where a rebuild is worthwhile, and cleanup opportunitiesEvery 30 min
FrontendJavaScript errors on checkout pages in the last 24 hours (high from 3 occurrences, critical from 10), spikes in distinct errors within an hour, and errors still occurring that exceed the recurring-error threshold. Browser-extension and autofill noise is ignoredEvery 15 min
ExtensionsExtensions that logged 10 or more errors in the last 7 days and are still failing (each error is attributed to the first third-party extension in its stack trace, or to the class named in the message, never to Magento core), known conflicting pairs, and empty generated PHP files. Below the findings: every installed extension with status, version, how it was installed, its error count and, when the PHP-FPM slow log is enabled, its slow requests and PHP time. Under that, Slowest Extensions ranks extensions by the PHP time they caused over the last 7 days (see below)Every 10 min
PerformanceHomepage time to first byte (median of three requests after a warm-up, when TTFB checks are enabled), full page cache misses where Magento exposes them, JS/CSS minification, debug logging (as Magento actually applies it: from app/etc/env.php, on by default outside production mode), log directory size, PHP-FPM slow log, slow admin grid queries, flat catalog and Varnish recommendations for large catalogsEvery 20 min
SearchWhether the configured search engine answers, tested with Magento’s own search client (same host, port, HTTPS and credentials as the storefront), OpenSearch cluster status (YELLOW is informational on a single node, where replica shards can never be placed), popular search terms from the last 90 days with no results, and search term table bloatEvery 6 hours
Security39-check security audit: admin access, patching, web exposure, malware indicators, storefront, API, live threatsEvery 15 min (exposure & malware scans every 6 hours)
Cron HealthCron not running, failing jobs (with cause and fix), backlog, stuck jobs, schedule bloat, root ownership. The tab also shows a live heartbeat, 24-hour failure trend, every failure grouped by job and cause (still failing or recovered), and a searchable table of every cron job with its schedule, last run, last success, next run, run time and error/missed countsEvery 10 min
Cache HealthVarnish status and hit rate; Redis reachability, keys evicted since the previous scan (the Redis counter itself only resets on restart), memory against maxmemory (threshold set by Redis Memory High), eviction policy, and a page cache database that is still empty after MageMonitor requests the homepage; full page cache state and backend (Varnish recommended only for large catalogs); OPcache memory, file count and hit rate as the web server’s PHP sees them, with the hit rate judged only once OPcache has been warm for an hour after a PHP-FPM reloadEvery scan

Slowest Extensions (Extensions tab)

PHP-FPM writes a stack trace for every request that runs longer than request_slowlog_timeout. Each trace is blamed on the first third-party extension found walking out from the code that was executing, because the innermost frame is almost always Magento’s database or cache layer: where the time was spent, not who asked for it. A request that never touches an extension is blamed on the Magento core module. Each row shows total and average slow time (durations come from the PHP-FPM error log), the number of slow requests, the file and function where the extension was executing, and advice for that kind of code (plugin, observer, block or model). It has its own Module Performance permission, nested under Extensions in the role tree.

When the slow log is not enabled the section shows the two pool settings to add:

request_slowlog_timeout = 5s
slowlog = /var/log/php8.2-fpm.slow.log

Reload PHP-FPM afterwards and make sure the web server user can read the file. A different location can be set under Performance Monitoring › PHP Slow Log Path.

Detection Severity Levels

CRITICAL
Site down or revenue loss happening right now
Examples: Varnish not running, checkout JS errors, database refusing connections, health check failing, SSL certificate expired.
HIGH
Will cause real problems within hours if not addressed
Examples: SSL expiring in 7 days, Redis evicting keys, DB connections near limit, Varnish backend failures, cron backlog exceeding threshold.
WARNING
Should be fixed but not immediately urgent
Examples: Varnish hit rate below threshold, missing database indexes, table fragmentation, slow query log disabled, JS error spike.
INFO
Good to know for planning purposes
Examples: PHP EOL version, MySQL slow log disabled, Magento version available for upgrade, OPcache files threshold low.

Slow Requests Tab

Storefront and admin pages, REST calls and GraphQL resolvers that took longer than the Slow Page Threshold (ms) (Performance Monitoring, default 2000).

Every request is timed, including the time Magento spends rendering the page after the controller runs, so pages that are slow to render are caught. Timing is never sampled; the Sampling Rate setting only limits how many requests are written to the Live Traffic log. Only requests over the threshold are stored, one row per route, with the average and slowest time of those slow hits, how many times it happened and when it last did. Rows are kept for 30 days.

The tab shows a summary, the requests that were slow in the last 24 hours, and earlier ones. Admin secret keys and query strings are removed from the sample URLs shown.


JS Errors Tab

Real JavaScript errors collected from real visitors' browsers. The collector catches window.onerror, unhandledrejection, and require.onError events, batches them client-side, and sends them to MageMonitor every 3 seconds.

Stat Cards

  • Occurrences — How many times errors occurred over the retained 14 days (click to show all errors)
  • Distinct Errors — Number of different errors (same message, file and line) (click to show all errors)
  • On Checkout — Occurrences on checkout, onepage and payment pages (click to filter to checkout only)
  • Active in Last Hour — Distinct errors that occurred in the last 60 minutes (click to filter to recent)

Browser-extension, autofill and ResizeObserver noise is excluded from every card and from the list. Open an error to see the browsers and operating systems it occurred in, when it was first seen, the exact file and line, and the stack trace the browser sent. When the collector is switched off the tab says so, since no new errors can arrive.

Filtering

  • Search box — Filter by error message, source file, or page URL in real time
  • Page filter dropdown — Filter to a specific page or all pages
  • Card click — Click any stat card to filter the table

Error Table

Errors are grouped by message + source file combination. Each row shows: error message, source filename, pages affected (with page count badge if multiple pages), total count, and last seen timestamp. The page column color-codes checkout (red), customer account (orange), and homepage (blue) for quick identification.

Checkout Errors = Revenue Loss
JavaScript errors on checkout pages directly prevent customers from completing purchases. Any non-zero count in the ON CHECKOUT card should be investigated immediately.

CDN Tab

CDN analytics from AWS CloudFront or Cloudflare. Shows cache hit rate, bandwidth, request volume, top cached URLs, and error rates. Requires AWS or Cloudflare integration to be configured.

WAF Tab

Web Application Firewall events from AWS WAF or Cloudflare. Shows blocked requests, triggered rules, and top blocked IPs. Requires AWS or Cloudflare integration to be configured.

SSL Certs Tab

Certificate status for every store view domain and any extra domains you configure: expiry, issuer, whether browsers trust it, whether it covers the domain name, and the HTTP protocol served.

MageMonitor reads the certificate first and verifies it separately, so an expired, self-signed, wrong-hostname or incomplete-chain certificate is reported with the reason (for example “The certificate expired 2026-01-12”) and raises a critical alert, instead of appearing only as a connection error. A domain that cannot be reached over TLS at all is also critical.

Days RemainingStatusAlert Sent
30+ daysValidNo alert
7–29 daysWarningWARNING alert
1–6 daysCriticalCRITICAL alert
0 or expiredExpiredCRITICAL alert

Infrastructure Tab

The server, services and software the store runs on, detected automatically. Use Refresh to read it again.

  • Resources: CPU load as a share of the CPU cores (with the 1, 5 and 15 minute load averages), memory, swap and the fullest disk. Cards turn amber or red as they fill. The history of these values is on the Live Metrics tab.
  • Server: whether it is a virtual machine, container or physical server, the provider when it can be identified, hostname, IP address, operating system and uptime.
  • Magento: version and edition, deploy mode, where sessions and cache are stored, and the store URLs.
  • Services: MySQL/MariaDB (with database size), Redis, the search engine and PHP-FPM, each with its status, version and address.
  • Storage: every filesystem Magento uses with used, free and total space, plus the size of Magento’s log and cache files.
  • PHP: the settings of the PHP that serves the store (version, memory limit, execution time, upload size, display errors, OPcache and its hit rate), every extension Magento 2.4 requires with any missing ones listed first, and optional extensions (redis, imagick) that make Magento faster but are not required.

Live Traffic Tab

Who is on the store right now. The tab refreshes every 2 minutes; Refresh reloads it immediately.

  • Summary: active visitors (distinct real browsers in the last 30 minutes), storefront and API requests in the last 30 minutes with their average response time, and the share of traffic from bots over the last 2 hours.
  • Recent Visitors: one row per visitor (IP address and browser) seen in the last 30 minutes, with device, whether it is a bot, how many requests it made, the last page, average response time and when it was last seen.
  • Top Requests: the most requested storefront pages and REST/GraphQL endpoints over the last 2 hours. The same page with different query strings counts as one.
  • Bots: real browsers versus bots, grouped into search engines, AI crawlers, SEO tools, scrapers and scanners, and monitoring services, with each bot’s requests.
  • Admin Activity: the admin pages opened in the last 2 hours (background calls such as grid data and dashboard refreshes are left out, and secret keys are removed from URLs) and the admins signed in during the last 15 minutes.

Requests are logged as Magento serves them, so pages served entirely by Varnish or a CDN are not counted. Below 1,000 requests an hour every request is logged; above that only the Sampling Rate share is, and the tab says the counts are a sample. MageMonitor’s own checks (uptime, security audit, cache and performance probes) are not logged. Anything that is not a real browser counts as a bot.


Quick Fixes

Maintenance actions you can run from the dashboard. Each action shows what it affects before you run it, and every run is recorded in the Audit Log with your username and the result.

Actions that do not apply to the store are shown disabled with the reason: code and static-file clearing in production mode, PHP-FPM and Varnish actions when Privileged Quick Fixes are off, and CloudFront invalidation without the AWS Integration. Actions that delete data or lock tables ask for confirmation first.

GroupActionWhat it doesImpact
CacheFlush all cachesClears every Magento cache type. Pages load more slowly for a few minutes while the cache refills.Briefly slower
CacheEnable all cache typesTurns back on any cache type that was switched off.No downtime
CacheWarm the page cacheRequests the homepage and top category pages of every active store view.No downtime
CacheClear generated codeDeletes generated/code. Not available in production mode, where bin/magento setup:di:compile must be run instead.Briefly slower
CacheClear static filesDeletes generated CSS, JavaScript and images. Not available in production mode, where static content must be deployed instead.Briefly slower
IndexingReindex invalid indexersRebuilds only the indexers Magento has marked as needing a reindex.Briefly slower
IndexingReindex everythingRebuilds every indexer in the background; View reindex progress shows its log.Stale data until done
IndexingTruncate changelog tablesEmpties indexer changelog (*_cl) tables above the configured size threshold, then reindexes what they fed.Stale data until done
DatabaseOptimize fragmented tablesRebuilds up to 5 tables with over 100 MB, and over 30% of their size, reclaimable.Locks tables briefly
DatabaseKill slow queriesStops queries still running past the slow-query threshold; their transactions are rolled back.Rolls back queries
DatabaseRemove old inactive cartsDeletes carts converted to orders or closed and not updated for over a year. Orders keep their own copy.Deletes data
DatabaseClean cron historyDeletes finished, missed and failed cron entries older than 7 days.Deletes data
ServerMaintenance modeShows its current state and turns it on or off. Your IP address stays allowed while it is on.Store briefly offline
ServerClear stuck cron jobsRemoves schedule entries left “running” for over 3 hours so those jobs can run again.No downtime
ServerEmpty large log filesEmpties every file in var/log larger than 10 MB.Deletes data
ServerRestart PHP-FPMFrees workers stuck on slow requests. Needs Privileged Quick Fixes (Advanced Settings) and sudo access for the web server user.Store briefly offline
ServerAllow reading Varnish statisticsShown only when Varnish is running and MageMonitor cannot read its statistics. Needs Privileged Quick Fixes.Store briefly offline
ServerInvalidate CloudFront cacheAsks CloudFront to fetch the paths from the CloudFront finding again. Needs the AWS Integration.Briefly slower
MageMonitorSend a test emailSends a sample alert to the first address in Email Alerts › Alert Recipients, to confirm delivery.No downtime
MageMonitorSend a test Slack messagePosts a sample message to the configured Slack webhook.No downtime
MageMonitorRun alert check nowSends alerts for findings that are new or changed since the last alert, without waiting for the schedule. Nothing is sent when nothing changed.No downtime
MageMonitorClear findings historyDeletes every finding after showing how many there are. Traffic, uptime history and settings are kept.Deletes data
MageMonitorReset all MageMonitor dataDeletes everything MageMonitor has collected after showing record counts per table; type RESET to confirm. The license and settings are kept.Deletes data

Server Advisor

Compares the server’s PHP, OPcache, database, Redis, web server and hardware settings with what a store of this size needs.

Store size is small, medium or large, set by product count, orders in the last 30 days and database size; recommendations such as memory limits, buffer pool size, CPU cores and RAM scale with it. The page opens with counts of settings needing action, recommended improvements and passing checks, then lists the recommendations most important first, each with the current and recommended value and a copyable fix. All Checks lists every setting by area.

  • PHP: version and end of security support, memory limit, execution time, form field limit (max_input_vars), upload size, realpath cache and every extension Magento 2.4 requires.
  • OPcache: enabled, hit rate (judged once OPcache has run for an hour after a restart), memory, file slots and timestamp validation.
  • Database: version, InnoDB buffer pool against database size, connection use, slow query log, query cache and how often the table cache misses.
  • Redis: read directly from Redis (no PHP extension needed): version, whether a memory limit is set, and the eviction policy.
  • Web server: server software, HTTPS, compression and HTTP/2 measured on a real storefront request, and Varnish for larger stores.
  • Server: free disk space, CPU cores, RAM and deploy mode.

Audit Log

Who changed what through MageMonitor, and when: quick fixes, settings changes, findings marked resolved, acknowledged or reopened, scans, health reports and file-baseline resets, plus the alert emails MageMonitor sent.

  • Summary: actions in the selected period, the admins who made them, disruptive actions (ones that deleted data or interrupted the store) and alert emails sent.
  • Filters: period (24 hours to 90 days), type (disruptive, maintenance, findings, settings, scans and reports, alert emails), admin and a text search. Alert emails are left out unless chosen, so they do not bury admin actions.
  • Entries are grouped by day, newest first, 100 at a time, each coloured by type.
  • Settings changes list which MageMonitor settings were changed, never their values, because several are secrets (webhook URLs, API tokens, AWS keys).
  • Export CSV downloads the entries matching the current filters, with times in the alert timezone.

Actions run by cron or the command line show as System. Entries are kept for 90 days.


Health Report

A complete store health report as a printable page. Click Report in the MageMonitor header to open it, then Save as PDF to keep or share it (A4, page breaks between sections).

  • Cover: store name and URL, when the report was generated (in the alert timezone), Magento version, edition and deploy mode, PHP and MageMonitor versions, and the health score with its rating and change against yesterday’s average.
  • 1. Summary: a one-sentence verdict, open findings by severity, key indicators (7-day uptime, security grade, cron status and SSL expiry), the health of each area, and up to five priority actions linked to their findings.
  • 2. Findings: every open finding once, most serious first, with what is wrong, how to fix it (commands shown as copyable code), and when it was first and last detected.
  • 3. Details by Area: server resources and PHP, database size, connections and largest tables, cache (page cache, Varnish, Redis, OPcache), cron status and jobs still failing, uptime per endpoint with recent incidents, SSL certificates, the slowest requests, JavaScript errors (browser-extension noise excluded) and the security audit by area.

Figures come from the same data as the matching dashboard tabs. An admin sees only the areas their role can open, and generating a report is recorded in the Audit Log.


All Detectors

MageMonitor includes 10 specialized detectors. Each detector runs independently with its own try/catch error handling — a failure in one detector never affects others.

Server Detector

Runs every 5 minutes (configurable). Checks the PHP version and extensions and the PHP memory limit, PHP-FPM worker saturation, free disk space (the root disk, var/ and pub/media, reported once per physical disk), Redis version, fragmentation, connections and restarts, session Redis reachability, Varnish reachability, web server configuration, MySQL version and buffer pool sizing, the health check endpoint, CloudFront errors and unexplained processes using sustained CPU.

Scheduled scans and PHP settings. Scheduled scans run in PHP's command-line interpreter, which has its own php.ini, usually no OPcache and no memory limit. So that PHP findings describe the PHP that actually serves your store, MageMonitor reads PHP-FPM's settings through its token-protected health endpoint (/magemonitor/health/). If the storefront cannot be reached from the server (for example behind HTTP authentication), these checks are skipped and their findings stay as they were. OPcache and Redis cache memory are reported under Cache Health, the search engine under Search, and cron under Cron Health, so no problem is reported twice.

Magento Detector

Runs every 15 minutes (configurable). Checks the deploy mode, every cache type (disabled or left invalidated), every indexer (reindex required, stuck in processing, scheduled backlog not moving), file-based session storage, and order confirmation emails that were due but not sent (orders with confirmations enabled whose email was never marked sent, including failed asynchronous sends). Asynchronous grid indexing is checked by the Database detector.

Database Detector

Runs every 30 minutes. Checks database storage utilization, live slow queries from PROCESSLIST, missing indexes on high-impact tables (url_rewrite, sales_order_address), table fragmentation (>30% waste AND >200MB recoverable), async grid indexing, and orders grid size.

Frontend Detector

Runs every 15 minutes. Analyzes the JS error log for checkout errors, error spikes (unusual increase in error volume), and recurring high-frequency errors that degrade user experience.

Extensions Detector

Runs every 10 minutes. Checks for disabled modules that other modules depend on, known conflicting extension combinations, and modules with known performance issues.

Performance Detector

Runs every 20 minutes. Checks flat catalog configuration vs product count, Full Page Cache backend (recommends Varnish at scale), Redis maxmemory configuration, InnoDB buffer pool vs available RAM, and OPcache sizing.

Search Detector

Runs every 6 hours. Checks Elasticsearch/OpenSearch cluster health (yellow/red status), shard assignment, and search query table growth with intelligent junk ratio analysis (flags only when >40% of rows are one-time queries older than 90 days).

Security Detector (Security Center audit)

Runs every 15 minutes. Web exposure probes and the malware file scan reuse their result for 6 hours (use Re-run Full Audit in the Security tab to refresh them immediately). The audit produces a 0–100 score and A–F grade, and every failed check becomes a finding with evidence, why it matters, the exact fix and the matching standard (PCI DSS v4.0, OWASP).

AreaChecks
Active ThreatsBrute force / failed admin logins, admin accounts created in the last 7 days, critical file integrity, cron jobs pointing at unknown code
Malware IndicatorsExecutable scripts in pub/media and pub/static, unexpected PHP files in the web root, obfuscated or unknown-domain JavaScript in design configuration and CMS content, exploit directives in email templates
Web ExposureDownloadable secrets (env.php backups, auth.json, .git, .env, SQL dumps, logs, phpinfo), HSTS / X-Frame-Options / X-Content-Type-Options headers, HTTP→HTTPS redirect, /magento_version disclosure
Admin AccessTwo-factor authentication, guessable admin path, admin URL secret key, lockout, idle session timeout, account sharing, login CAPTCHA, password rotation, account hygiene (generic, abandoned or placeholder-email accounts), full-access roles
Platform & PatchingMagento patch level and release-line end of support, PHP end of security support, error details shown to visitors (display_errors overrides in entry points, pub/errors/local.xml print action, developer mode), database user privileges, Redis authentication, env.php and entry-point permissions
Storefront & CustomersHTTPS on every store view, HttpOnly cookies, checkout Content Security Policy enforcement, reCAPTCHA on login / registration / password reset / checkout, customer lockout, customer password rules, template hints and symlinks
API & IntegrationsAnonymous REST access, integration tokens as bearer tokens, token expiry, integrations with full API access

Cron Health Detector

Runs every 10 minutes. Checks whether cron is running at all, jobs failing on their latest run (with Magento's recorded error, the likely cause and fix), cron backlog count, stuck running jobs, cron_schedule table size, and whether cron is running as root.

Cache Detector

Runs every 10 minutes. Checks Varnish running status and hit rate (via varnishstat with layered fallback), Redis running status, memory usage, eviction policy, evicted keys count, and per-database key counts. Also checks Magento FPC backend configuration and OPcache hit rate and file count.


Background Jobs

MageMonitor registers 24 cron jobs that run automatically via Magento's cron system. All jobs are prefixed with poc_magemonitor_ and belong to the default cron group; the job code under each name is what you will see in cron_schedule and on the Cron Health tab. Each detection category has its own schedule, so a slow check never delays a fast one.

JobScheduleWhat It Does
ServerHealth
poc_magemonitor_server
Configurable (default: */5)PHP-FPM, OPcache, disk, Redis health scan
MagentoHealth
poc_magemonitor_magento
Configurable (default: */15)Cache, indexers, Magento config scan
DatabaseHealth
poc_magemonitor_database
*/30 * * * *DB storage, indexes, slow queries, fragmentation
PerformanceCheck
poc_magemonitor_perf
*/20 * * * *FPC, flat catalog, Redis config checks
FrontendHealth
poc_magemonitor_frontend
*/15 * * * *JS error analysis, checkout error detection
SecurityCheck
poc_magemonitor_security
*/15 * * * *Security audit (brute force, file integrity, admin access, patching, exposure, malware indicators)
CacheHealth
poc_magemonitor_cache
*/10 * * * *Varnish, Redis, Magento FPC and OPcache health
CronHealth
poc_magemonitor_cronhealth
*/10 * * * *Stuck jobs, queue backlog, cron schedule table growth
UptimeCheck
poc_magemonitor_uptime
*/3 * * * *HTTP health check of all monitored URLs
AlertProcessor
poc_magemonitor_alerts
*/5 * * * *Sends email/Slack/webhook alerts for new detections
FlushTrafficQueue
poc_magemonitor_flush_traffic
* * * * *Writes queued traffic data from Redis/files to DB
CleanTrafficData
poc_magemonitor_clean_traffic
*/5 * * * *Removes traffic data older than 2 hours
LogParser
poc_magemonitor_logparser
*/10 * * * *Runs the Extensions detector: attributes exception.log / system.log errors to the extension that caused them, and checks module conflicts
SslCheck
poc_magemonitor_sslcheck
0 */6 * * *Checks SSL certificate validity and expiry
SearchCheck
poc_magemonitor_search
0 */6 * * *Elasticsearch/OpenSearch health check
HealthScoreSnapshot
poc_magemonitor_healthscore
0 * * * *Calculates and saves hourly health score
FileIntegrity
poc_magemonitor_filecheck
0 */4 * * *SHA-256 hash comparison for monitored files
LicenseCheck
poc_magemonitor_license_check
*/30 * * * *Validates license key against registered domain
StoreIntelligenceScan
poc_magemonitor_store_intelligence
0 */3 * * *Deep database/cron/performance intelligence scan
Cleanup
poc_magemonitor_cleanup
0 2 * * *Daily cleanup of old data per retention policy
Probe: SlowQueries
poc_magemonitor_probe_slow_queries
*/2 * * * *Samples database queries running right now
Probe: FpmSaturation
poc_magemonitor_probe_fpm_saturation
*/3 * * * *Samples PHP-FPM worker saturation
Probe: AdminGrid
poc_magemonitor_probe_admin_grid
*/3 * * * *Detects admin grid queries stuck behind a slow JOIN
Probe: RedisLoad
poc_magemonitor_probe_redis_load
*/5 * * * *Samples Redis operations per second
Cron Must Be Running
All MageMonitor features depend on Magento cron running as www-data. Verify your cron is configured: sudo crontab -u www-data -l. If cron is not installed, run: sudo -u www-data php bin/magento cron:install

Notifications

MageMonitor supports three notification channels, each configurable independently with their own digest schedule.

When an Alert Is Sent

The alert processor runs every 5 minutes. It does not send a message every time it runs — it sends one only when something about your store has genuinely changed. A finding has an identity (which problem it is) and a state (how severe it is), and those two things are the only reasons a message is ever sent.

TriggerWhat it meansTiming
New issueA problem was detected that you have not been told aboutImmediately, if it is Critical or High
EscalationA problem you already know about has become more severe — a Warning that is now CriticalImmediately, if the new level is Critical or High
ResolvedA problem has clearedAfter it has been absent from two consecutive checks
Health score dropThe score fell below your configured thresholdOnce, on the way down — it re-arms when the score recovers
Scheduled reportThe current state of the store, whether or not anything has changedAt fixed times of day — see below
Downtime / RecoveryA monitored URL stopped or started respondingImmediately, after the configured number of confirmations

When an Alert Is Not Sent

This is the more important half, and it is a guarantee rather than a best effort.

Changing Numbers Never Cause an Email
A finding’s wording is rewritten on every scan because it quotes live measurements — a cache age, a query count, a percentage, a list of affected URLs. None of that can trigger a message. If the same problem is still open at the same severity, you will not hear about it again, no matter how much the text inside it moves. The alert rule is never given the wording at all, so there is no path by which it could.

Specifically, none of the following sends anything:

The measurements inside a finding changed
Cache age went from 7591 seconds to 3099 seconds, slow queries went from 5 to 8, disk went from 12% free to 11%. The problem is the same problem.
The title or description was reworded
Titles embed live values, so they change constantly. The dashboard always shows the current wording; the alert channel ignores it.
A finding became less severe
Critical dropping to High is good news, not urgent news. It is reflected on the dashboard immediately and mentioned in the next digest.
A check could not run
If a check cannot reach what it measures — a network timeout talking to your CDN, for instance — it reports nothing rather than reporting “fixed”. An open finding is never resolved on the strength of a check that failed to complete.
A short load spike
PHP-FPM worker saturation, high Redis load and concurrent slow queries measure a single moment, so a burst of traffic can cross the line for one sample and fall back on the next. These three alert only once the finding has stayed open for 10 minutes. The dashboard and health score still show them immediately.
A finding was moved to the backlog
Backlogged findings send nothing while they sit there — not even a “resolved” notice for leaving the open list. If one later becomes more severe it returns to the open list and alerts as an escalation. See Backlog Tab.
Anything, within 5 minutes of the last alert on that channel
Each channel enforces a five-minute minimum gap between event alerts. Nothing is lost — a suppressed alert is sent on the next cycle. Scheduled reports are exempt: they are already spaced by their own schedule.

The Scheduled Report

Event alerts tell you what changed. The scheduled report tells you where the store stands — the full current picture, sent on a fixed clock whether or not anything has happened. It is configured separately for each channel, under Scheduled Report Frequency, Send the Scheduled Report and First Report of the Day At.

Fixed Times of Day, Not “Six Hours After the Last One”
The schedule is anchored to real times in your Alert Timezone. Every 6 hours starting at 08:00 means 08:00, 14:00, 20:00 and 02:00 — the same four times tomorrow, and the same four after a week of incidents. Event alerts never push it later, and it never drifts. Every report also prints when the next one is due, so you can tell a quiet store from a channel that has stopped working.

Three choices of when it is worth sending:

When anything is open — the default
Every finding at or above your Minimum Severity, on every slot. This is the setting to choose if what you want is a regular picture of your store: “email me the current issues every 6 hours”.
Only when something urgent is open
The report is kept for Critical and High findings and stays silent otherwise. Choose this if you want the schedule to be a safety net rather than a routine.
Always, even when the store is clean
Sends on every slot regardless, with an all-clear when there is nothing to report. Recommended for an unattended store: the all-clear is itself the useful fact, because it proves that scanning and mail delivery are both still working. Without it, a healthy store and a stopped cron produce exactly the same empty inbox. On a webhook endpoint this gives you a heartbeat you can alarm on when it stops arriving.

If a report is missed — cron was down, mail was refused — it costs you one report, not a backlog. The next run sends the current picture rather than replaying every window that went by. Setting the frequency to Off leaves the channel with event alerts only.

Subject Lines

The two kinds of email deliberately read differently, because you do different things with them.

KindSubjectWhy
Event alert CRITICAL: Acme — 5 Concurrent Slow Queries (worst: 42s) It is announcing one specific thing that just happened. Naming it lets you decide whether to act straight from the phone notification, without opening the mail.
Scheduled report MageMonitor Report: Acme — 12 open issues, 2 critical (health 58/100) It is not announcing anything — it arrives on a clock and describes the whole store. The shape is fixed so it is instantly recognisable and an inbox rule has something constant to match.
The Report Never Quotes a Measurement in Its Subject
Finding titles carry live numbers — a cache age, a percentage, a query count — and they are rewritten on every scan. If the scheduled report put one of those in its subject, four identical reports a day would arrive looking like four different incidents, differing only by a decimal you would have to read carefully to notice. The report names no finding and quotes no measurement; a count and the health score are the only numbers in it.

Set an Email Subject Tag under Alert General Settings to put your own string in front of every MageMonitor email — for example [Store Monitor], giving subjects like [Store Monitor] MageMonitor Report: Acme — all clear (health 100/100). One rule on that tag then catches every monitoring email you receive, whatever it is about.

What an Alert Contains

Every alert shows the current health score and its movement since the last message you received. Below that:

New or escalated findings — in full
Severity, what happened, why it matters to customers, and the numbered steps to fix it. An escalated finding is labelled with what changed, for example “Escalated from WARNING to CRITICAL”.
Still open — one line each
Findings you have already been told about are listed so nothing is hidden, but without repeating the full card. This is what stops consecutive alerts looking identical.
Resolved since the last alert
What cleared, by name. A resolution message leads with the good news rather than reusing the alarm subject line.

The scheduled report is the exception: it prints everything in full, because it is the complete picture you asked for on a schedule rather than a notification about a change.

Each Channel Keeps Its Own History
Email, Slack and webhooks track what they have sent independently and have their own report schedule. Turning Slack on does not change what arrives by email, and a delivery failure on one channel never suppresses another. A message that fails to send is retried on the next cycle rather than being silently dropped.

Webhook Payload Format

{
  "event": "detection_alert",
  "store": "My Store",
  "health_score": 72,
  "timestamp": "2026-06-13T10:00:00+02:00",
  "detections": [
    {
      "code": "VARNISH_HIT_RATE_CRITICAL",
      "severity": "critical",
      "category": "cache",
      "title": "Varnish Hit Rate Critical (18%)",
      "problem": "Varnish cache hit rate is 18%...",
      "how_to_fix": "Check VCL cookie stripping..."
    }
  ]
}

Webhook payloads are signed with HMAC-SHA256 using your configured secret. Verify the signature on your endpoint by comparing the X-MageMonitor-Signature header against HMAC-SHA256(secret, payload_body).


Frequently Asked Questions

Does MageMonitor impact store performance?

MageMonitor is designed for minimal overhead. The traffic sampling plugin runs on a configurable percentage of requests (default 10%) with a cache-backed enablement check on every request. All heavy analysis runs via background cron, not during customer page loads. The JS collector snippet is under 2KB and uses a 3-second batch delay before sending.

Does MageMonitor modify any store data?

No. All detectors are strictly read-only — they only run SELECT queries against your database. The only writes MageMonitor performs are to its own tables (prefixed poc_magemonitor_). Quick Fix actions that modify data (cache flush, reindex) run standard Magento CLI commands and are explicitly triggered by admin users.

The health score is 0 but my store is working fine. Why?

This can happen immediately after installation, before the first cron scan completes — wait 5–10 minutes for the initial scans to run. If the score stays low after that, it is arithmetic rather than a fault: each open finding subtracts points by severity (see How the score is calculated above), and a store with many low-severity findings can score poorly while trading perfectly well. Open the category tabs to see what is counted. Informational findings cost 1 point each and are often safe to leave.

I see a false positive detection. How do I stop it?

Use Mark as resolved if you believe it is fixed (it comes back if the next scan still finds it), or Move to backlog to keep it out of the score and alerts while it stays tracked. For persistent false positives (e.g. Varnish hit rate warning on a store with many logged-in customers), adjust the relevant threshold in Configuration — for example, lower the Varnish Hit Rate Warning Threshold from 40% to 25%.

Can I install MageMonitor on multiple stores with one license?

Each license key is tied to one domain. For multiple stores (different domains), purchase a separate license for each. Multi-domain licenses are available — contact support at store.pointofcode.com.

Varnish stats show 0% hit rate but Varnish is running.

The www-data user does not have permission to read Varnish shared memory. Fix using the Quick Fix button: Quick Fixes → Fix Varnish Permissions. Or run manually: sudo usermod -a -G varnish www-data && sudo systemctl restart php-fpm

The "On Checkout" filter shows no errors but the count is non-zero.

Checkout errors are matched against URLs containing "checkout", "onepage", or "payment". If your store uses a custom checkout URL, the filter may not match. Search for the checkout URL pattern manually using the search box in the JS Errors tab.

The admin returns 500 errors after installing or updating.

setup:upgrade emptied pub/static and no setup:static-content:deploy followed. Run sudo -u www-data php bin/magento setup:static-content:deploy -f, then cache:flush. The storefront usually keeps working in the meantime because it is served from full-page cache.

Changes or an update have no effect.

PHP-FPM is still serving the previously compiled code. Run setup:di:compile, then reload PHP-FPM (for example sudo systemctl reload php8.2-fpm).

The dashboard never updates.

Almost always a stopped cron. sudo -u www-data php bin/magento cron:run should produce output, and the Cron Health tab shows when a job last started. Check also that Automatic Cron Scanning (Advanced Settings) and the module itself (General Settings) are enabled.

How do I uninstall MageMonitor?

Installed with Composer:

sudo -u www-data php bin/magento module:uninstall PointOfCode_MageMonitor --remove-data
sudo -u www-data php bin/magento cache:flush

This runs MageMonitor’s uninstall script, which drops all of its poc_magemonitor_* tables, deletes its magemonitor/* configuration rows and its licence record, and clears its entry from app/etc/env.php — including the magemonitor/health_secret key, so no credential is left behind. If env.php is not writable at the time, the uninstall still completes and the entry to remove by hand is written to the Magento log.

Installed manually in app/code: Magento runs uninstall scripts only for Composer packages, so remove the module and then its data yourself:

sudo -u www-data php bin/magento module:disable PointOfCode_MageMonitor
rm -rf app/code/PointOfCode/MageMonitor/
sudo -u www-data php bin/magento setup:upgrade
sudo -u www-data php bin/magento cache:flush
-- then, in MySQL (add your table prefix if you use one)
DROP TABLE IF EXISTS poc_magemonitor_detections, poc_magemonitor_js_errors,
  poc_magemonitor_health_snapshots, poc_magemonitor_uptime, poc_magemonitor_admin_logins,
  poc_magemonitor_file_hashes, poc_magemonitor_slow_pages, poc_magemonitor_maintenance_log,
  poc_magemonitor_ssl_certs, poc_magemonitor_traffic;
DELETE FROM core_config_data WHERE path LIKE 'magemonitor/%';
DELETE FROM poc_core_license WHERE product_sku = 'POC-MAGEMONITOR-M2';

Finally remove the 'magemonitor' block from app/etc/env.php. Leave PointOfCode_Core installed if you use any other PointOfCode extension.