The WordPress change log that catches what hooks miss.
WP Change Ledger tracks every plugin, theme, and core update — including changes made outside WordPress via FTP, SSH, deployment pipelines, and hosting panel restores.
Hooks + daily cron
No telemetry, no tracking
No SaaS fees, no premium wall
Built different.
Every other hook-based tracker produces a clean log when your deployment pipeline rsyncs files. This one doesn't.
Real-time hook detection.
Captures changes the moment they happen through WordPress — plugin installs, updates, activations, deactivations, theme switches, core updates. Includes who made the change and whether it was automatic or manual.
Daily filesystem checks.
Once a day, a background check compares the current state of plugins, themes, and core against a stored snapshot. This is the layer that catches changes made outside WordPress — FTP uploads, SSH edits, deployment pipeline file copies, hosting panel restores. Every other hook-based tracker misses these entirely.
The source column tells you where to look.
Every log entry carries a source field: hook means WordPress caught it in real time; cron means it was found by the daily check — look outside WordPress first. One field, clear diagnosis.
Previous version on every update.
All update events record what version was running before the change. No need to piece it together from memory.
Read-only and passive by design.
WP Change Ledger never modifies update behaviour, never sends alerts, never touches your site's functionality. It observes and records. That's it.
Dedicated database table.
Log entries live in a proper indexed table — not a serialized option. Paginated, filterable, and built to handle long-running sites without memory bloat.
How WP Change Ledger compares.
Focused on update and change tracking only.
| Feature | WP Change Ledger | WP Activity Log | Simple History | Stream |
|---|---|---|---|---|
| Hook-detected updates | Yes ✓ | Yes | Yes | Yes |
| Filesystem/FTP changes | Yes ✓ | No | No | No |
| Previous version logged | Yes ✓ | Partial | No | No |
| Source field (hook/cron) | Yes ✓ | No | No | No |
| Dedicated DB table | Yes ✓ | Yes | Yes | Yes |
| External requests | 0 ✓ | 0 | 0 | 0 |
| Price | Free ✓ | Free + paid | Free | Free + paid |
| Source code | GitHub GPL ✓ | WordPress.org | WordPress.org | WordPress.org |
Comparison based on publicly documented features. Focus is on update/change tracking only.
Up and running in minutes.
No configuration hell. No API keys. No account required.
Install
Upload via WordPress → Plugins → Add New → Upload Plugin.
Done
Find the log under Tools → Change Ledger. A "Change Log" link also appears in the plugin row on the Plugins screen.
Frequently Asked Questions
What does the Source column mean?
hook — change was detected in real time by a WordPress hook.
cron — change was detected by the daily background check. This is the expected source for filesystem-level changes (FTP, SSH, deployment pipelines, hosting restores, etc.).
A cron-only entry for a change you expected to see as hook is a signal worth investigating.
The log shows a change I didn't expect. What does that mean?
If the entry is source: cron, the change happened outside WordPress. Common causes: a deployment pipeline that copies files directly, a hosting backup restore, a manual file edit over FTP/SSH, or a staging push.
If the entry is source: hook, the change went through WordPress. Check the user_login column and the WordPress admin action log if you have one.
Does it support Multisite?
What happens to data when I deactivate the plugin?
What happens to data when I delete the plugin?
{prefix}change_ledger_log table and the wp_change_ledger_* options from the database.Is there a log size limit?
0 to keep entries indefinitely. Pruning runs automatically as part of the daily background check.I run WP cron from the command line (DISABLE_WP_CRON). Will this work?
wp cron event run --due-now (or hits wp-cron.php), the plugin's scheduled events will fire normally. The admin notice about cron health respects DISABLE_WP_CRON and will not nag you about timing — it will only alert if the events are not registered in WordPress at all.Why daily checks instead of more frequent?
Daily is the right default balance between coverage and performance. The wp_options table is not a queue — running snapshot diffs every few minutes on a large plugin list would add meaningful overhead. For most real-world debugging scenarios ("what changed this week?"), daily resolution is sufficient.
If you need sub-daily resolution for a specific investigation, you can trigger the cron events manually: wp cron event run wp_change_ledger_check_plugins.
What is the 24-hour blind spot?
Should I use this or build something similar myself?
Know what changed. Even when WordPress didn't.
Download WP Change Ledger — free, open source, and passive by design.