background update(GeoIP, incomplete source channels) never start
-
My WordPress site’s statistics appear to be functioning normally now, but whenever I open the WP Statistics page, it still shows a message saying that some data is being updated.
- Update GeoIP for visitors without location data: 0% complete (0/5).
- Update incomplete source channels: 0% complete (0/663).
- Refresh Summary Totals: 0% complete (0/365).
However, even after several months, these notifications are still there with no progress at all.
How should I resolve this issue?WordPress 6.9.4 + WP Statistics 14.16.6
-
Hi @kheresy,
Thanks for the detailed report. The pattern you’re describing, three separate jobs all queued but stuck at 0/N for months, is almost always a WordPress-level scheduling issue rather than a plugin bug. Those jobs run on top of
WP_Background_Process, which depends on two things being healthy on your site:- WP-Cron firing regularly.
- Loopback HTTP requests working (your site being able to call its own
wp-admin/admin-ajax.php).
If either is broken, the queue fills up but batches never execute, which matches exactly what you’re seeing (totals populated, processed = 0).
Please check these three things in order:
- Is WP-Cron disabled? Open your
wp-config.phpand look for:
define( 'DISABLE_WP_CRON', true );If that line exists, either remove it, or make sure you (or your host) have a real system cron job hitting
wp-cron.phpat least every 5 minutes.- Run Site Health: go to Tools → Site Health in your WordPress admin. Look for any warning about “The loopback request to your site failed” or “A scheduled event has failed“. If Site Health reports loopback failures, that’s the smoking gun. Common causes are basic auth / HTTP auth on the site, a firewall or security plugin blocking
admin-ajax.phpfrom the server’s own IP, or a self-signed SSL certificate. The Site Health message usually tells you which of those it is. - Install the free WP Crontrol plugin, open Tools → Cron Events, and look for events starting with
wp_background_process_cron_orwp_statistics_. If they’re all overdue, your cron isn’t running at all. If specific ones are missing, the job lost its scheduled event.
Once cron/loopback are healthy, the three queues should start draining on their own without any action from you. If you want to force a restart of the Summary Totals job specifically, go to Statistics → Optimization → Data Migrations and click the Run Migration button next to it.
The GeoIP (5 rows) and Source Channels (663 rows) queues are small and will complete in one or two batches once cron resumes, so fixing the cron/loopback side of things should clear all three notices.
If after verifying cron and loopback are working the jobs are still stuck, please reply here with:
- Whether
DISABLE_WP_CRONis defined inwp-config.php - A screenshot of the Site Health page
- Your hosting environment (shared host, VPS, WP Engine, Kinsta, etc.) and we’ll dig further.
Hope that helps!
Thank you for your response. Here’s what I’ve confirmed on my side:
- I did not find any
DISABLE_WP_CRONinwp-config.php. - Under Tools → Site Health, it shows “Your site can perform loopback requests”.
- In the Cron Events list, everything appears to be running normally and there are no overdue tasks. However, the actions for
wp_statistics_dbmaint_hookandwp_statistics_referrals_db_hookare shown as “none”.
All cron events with
wp_statisticsprefix(and its action):wp_statistics_update_visitors_source_channel_cron:WP_Statistics\Service\Database\Migrations\BackgroundProcess\Jobs\SourceChannelUpdater->handle_cron_healthcheck()
wp_statistics_update_unknown_visitor_geoip_cron:WP_Statistics\Service\Database\Migrations\BackgroundProcess\Jobs\IncompleteGeoIpUpdater->handle_cron_healthcheck()
wp_statistics_dbmaint_hook:- None
wp_statistics_daily_cron_hook:WP_Statistics\Service\CronEventManager->handleDailyTasks()
wp_statistics_record_daily_summary:WP_Statistics\Service\Summary\SummaryEvents->recordSummaryTotalsData()
wp_statistics_referrals_db_hook:- None
wp_statistics_check_licenses_status:WP_STATISTICS\Schedule->check_licenses_status()
wp_statistics_geoip_hook:WP_STATISTICS\Schedule->geoip_event()
My environment is a self‑hosted Ubuntu 24.04 VM, running
wordpress:fpm-alpinevia Docker, and the database is MySQLBy the way, after I click Run Migration under Statistics → Optimization → Plugin Maintenance → Data Migrations, a new background task appeared: “Migrate Visitor Data Columns: 0% complete (0/133607).”
However, it doesn’t seem to be doing anything.-
This reply was modified 1 month, 2 weeks ago by
kheresy.
Hi @kheresy,
Thanks for the thorough follow-up. Two notes and two tests.
Notes:
- The
wp_statistics_dbmaint_hookandwp_statistics_referrals_db_hookentries with no action are harmless leftovers, not the cause. Safe to delete from WP Crontrol. - Site Health’s loopback test is a GET request. Background jobs dispatch a non-blocking POST to
wp-admin/admin-ajax.php. On Docker (especiallyfpm-alpinebehind a public hostname), it is common for the GET test to pass while the POST silently fails, which matches what you are seeing.
Please try:
A. Enable debug logging in
wp-config.php:define( 'WP_DEBUG', true ); define( 'WP_DEBUG_LOG', true ); define( 'WP_DEBUG_DISPLAY', false );Then re-trigger Run Migration and share any errors from
wp-content/debug.log.B. From the Docker host, test the POST loopback from inside the WordPress container (replace the URL with what
home_url()returns):docker exec -it <wp_container> sh -c \ 'apk add curl; curl -v -X POST \ https://your-site.example/wp-admin/admin-ajax.php \ -d action=heartbeat'A healthy response is a quick
0. If it hangs, returns 403/5xx, or fails at DNS or SSL, the container cannot reach its own public URL. The fix is a Docker network alias or anextra_hostsentry so the container resolves its own domain locally.Share the results of A and B and we will pinpoint it from there.
Best regards,
Thank you for your reply.
I found that my configuration did prevent Docker from accessing /wp-admin/admin-ajax.php.After fixing it, most of the background tasks were completed and disappeared once I manually triggered them.
However, “Refresh Summary Totals: 0% complete (0/365)” is still not moving at all.
Maybe I should leave it for a while and see if it progresses?Hi @kheresy,
Glad the loopback fix cleared the other queues. Please do not just leave the Summary Totals job, though. If it has been at 0/365 since before the Docker fix, the original dispatch went out while admin-ajax was unreachable, so the workers never claimed it and it will not retry on its own.
Please re-trigger that one specifically:
- Go to Statistics → Optimization → Plugin Maintenance → Data Migrations.
- Click Run Migration next to “Refresh Summary Totals”. That button passes
force=1, which internally clears the stale process lock, drops any leftover batches, and re-queues from scratch. Right after clicking, please check two things:- A. In Tools → Cron Events (WP Crontrol), look for a new hook named
wp_statistics_summary_totals_data_migration_cron. Its presence confirms the queue was scheduled. Your earlier list did not include it, which is most likely why this one never advanced. - B. Tail
wp-content/debug.log(you already enabled it). The Summary Totals job builds its batch from your full daily visitor history, so on a small Alpine container it can occasionally hit the PHP memory limit. If you see “Allowed memory size of X bytes exhausted”, raiseWP_MEMORY_LIMITinwp-config.php(e.g. to512M) and try Run Migration again.
- A. In Tools → Cron Events (WP Crontrol), look for a new hook named
If after the force-restart the cron event appears but the counter still does not advance after 5-10 minutes, please share the latest debug.log lines and we will dig further.
Best regards,
The button next to Refresh Summary Totals is Refresh Totals, and when Refresh Summary Totals is stuck in the background tasks, that button becomes grayed out and cannot be used.
I tried manually adding the wp_statistics_summary_totals_data_migration_cron hook through Cron Events and executed it. After that, the background task for Refresh Summary Totals disappeared.It looks like there are no stuck background tasks now. Thank you for your assistance.
Hi @kheresy,
Glad it is fully cleared. Triggering the
wp_statistics_summary_totals_data_migration_cronhook manually was the right move. That hook is exactly what drains the queue, and once you fired it the worker claimed the existing batches and finished them.You also caught a real UX bug on our side, and thank you for that. While a migration was “active” (queue dispatched but not yet drained), the Run Migration button on Data Migrations was disabled, even though the underlying action already calls
stopProcess()and re-queues withforce=1. So when a queue was genuinely stuck, the very button that would unstick it was the one we were disabling.Just pushed a fix on the
developmentbranch that keeps the button clickable in that state, so future users will not need to fall back to WP Crontrol. It will ship in the next release (14.16.7).Thanks again for the patience and the thorough debugging on your end. Marking as resolved.
Best regards,
Thank you for your detailed assistance. Everything seems to be working fine now
You must be logged in to reply to this topic.