WordPress scheduled posts not publishing is almost always a WP-Cron problem: WordPress's built-in task runner only fires when a visitor lands on your site, so a post timed for 7 AM on a quiet Sunday will sit unpublished until the next person clicks through. For SA businesses already thinking about website cost in South Africa, a silent publishing failure can quietly undermine a product launch, a newsletter tie-in, or a time-sensitive promotion.

The frustrating part is that WordPress shows no error until someone notices the post still says "Missed Schedule" in the admin. The underlying mechanism, the fixes, and the quiet-window risk that catches low-traffic South African sites off guard are all straightforward once you understand them. This guide gives you a ranked list of causes and a prioritised fix sequence built for South African shared-hosting reality.

Quick Answer

WordPress scheduled posts not publishing is almost always caused by WP-Cron — WordPress's built-in scheduler that only runs when a visitor loads your site. If no visitor arrives near your scheduled time, the post sits. Fix the immediate problem by manually publishing the stuck post, then correct your timezone setting (Settings > General > Africa/Johannesburg), install a missed-schedule safety-net plugin, and replace WP-Cron with a proper server cron job for a permanent solution.

Is your website holding back your business?

Send us your current site setup and we will show you exactly where the technical gaps are costing you visibility and leads.

Get a free site review

WordPress Scheduled Posts Not Publishing: The Root Cause

A WordPress missed schedule error almost always traces back to WP-Cron — and the reason is architectural, not accidental. WordPress posts not publishing on schedule is the symptom; a visitor-triggered task queue is the cause.

WP-Cron is not a real cron job; it is that visitor-triggered queue, checking for overdue tasks on each page load. WordPress's own developer documentation states it plainly: "WP-Cron does not run constantly as the system cron does; it is only triggered on page load." It also confirms that "scheduling errors could occur if you schedule a task for 2:00PM and no page loads occur until 5:00PM."

This design made sense when WordPress was built: most shared hosts did not give site owners access to system-level cron jobs. WP-Cron was a pragmatic workaround. The trade-off is reliability — on low-traffic sites or during quiet hours, the queue builds up, and a missed schedule is the visible symptom.

A stuck post is not lost data. WordPress queues it and will publish it the moment the next visitor triggers a page load after the scheduled time. If your site gets traffic every few minutes, the delay is usually seconds. If it gets traffic every few hours — or no traffic at all during load-shedding outages — the gap can stretch to many hours.

How WP-Cron actually works

On each page load, WordPress checks a list of pending scheduled tasks in the database. If a task's scheduled time has passed, WordPress fires a background HTTP request to wp-cron.php to execute it. No page load = no check = no publish. High-traffic sites rarely notice this because the next visitor usually arrives within seconds of a scheduled time. Low-traffic sites — including many South African small-business sites — are exposed.

The South African Context — Low-Traffic Sites and Quiet Windows

Until mid-2025, load-shedding was a live compounding factor for South African sites: when customers lost power, they stopped browsing, and WP-Cron had no visitor to trigger it. South Africa's grid has been stable since then — Eskom marked 300+ consecutive days without load-shedding by March 2026 — but the underlying vulnerability has not gone away.

The problem is any predictable quiet window: overnight hours when your audience is asleep, December shutdowns when business traffic drops sharply, or a newly launched site that simply does not yet receive regular visitors. Scheduled posts failing to publish during those quiet windows are a symptom of infrastructure dependency, not a content problem — and the fix is the same regardless of what creates the quiet period.

The practical response is to remove traffic dependency from your publishing schedule entirely. That means replacing WP-Cron with a proper server cron job (covered in Fix 3 below). It is also worth monitoring your site's reliability over time — see uptime monitoring for SA businesses for a guide to doing this without expensive tools.

The practical rule of thumb

If your site reliably gets at least one visitor every 30 minutes during business hours, WP-Cron will be adequate for most scheduling needs. If your site goes quiet for long stretches — overnight, during seasonal shutdowns, or while you are still building an audience — WordPress cron not running reliably is a predictable outcome, and a server cron job is the correct response. The fix takes under 10 minutes and is permanent.

Diagnosing the Problem — A Symptom Table

Before applying any fix, match your symptom to its most likely cause to avoid working through the wrong checklist. The table below is ranked by frequency for South African shared-hosting sites.

SymptomMost likely causeFirst check
Post shows "Missed Schedule" in the adminWP-Cron did not trigger during the scheduled windowSettings > General > Timezone, then Tools > Site Health > Scheduled Events
Post publishes several hours lateWP-Cron fired late — no visitor arrived near the scheduled timeMove to server cron job (Fix 3)
Post publishes at the wrong time of dayWordPress timezone set to a UTC offset rather than a named citySettings > General — set to Africa/Johannesburg
Post never publishes and stays as a draftWP-Cron explicitly disabled with no replacement system set upCheck wp-config.php for DISABLE_WP_CRON
Intermittent failures with no obvious patternCache or CDN serving pages without letting WordPress process the requestClear all caches; confirm your caching plugin does not bypass wp-cron.php
Failures cluster around overnight hours, weekends, or seasonal low-traffic periodsNo visitors during quiet window → WP-Cron never firesServer cron job (Fix 3) — runs independently of visitor traffic
Security plugin recently installed and failures beganFirewall blocking WordPress's loopback request to wp-cron.phpCheck firewall allow-list; add wp-cron.php as an allowed internal request

Fix 1 — Correct Your WordPress Timezone Settings

A timezone mismatch is the fastest fix and the most frequently overlooked: WordPress publishes at the exact UTC time equivalent of your scheduled time, so if your site is set to UTC+0 and you schedule a post for 9 AM, WordPress publishes it at 9 AM UTC — which is 11 AM South African Standard Time.

South Africa runs on SAST (South Africa Standard Time), which is UTC+2 with no daylight saving adjustment. The correct WordPress setting is the named city Africa/Johannesburg — not a raw UTC+2 offset. Named cities handle any future DST changes automatically; raw offsets do not.

To fix it:

  1. Log in to your WordPress admin.
  2. Go to Settings > General.
  3. In the Timezone field, select Africa/Johannesburg from the city dropdown.
  4. Click Save Changes.
  5. Open your stuck post, update the scheduled time to your intended time (the editor now shows SAST times), and republish.
Right: Timezone set to Africa/Johannesburg. A post scheduled for 09:00 publishes at 09:00 SAST, which is 07:00 UTC.
Wrong: Timezone set to UTC+2 (a raw offset). This appears identical but can break in edge cases and does not label correctly in the WordPress editor for all users.

Fix 2 — Add a Missed-Schedule Safety Net

A missed-schedule plugin provides an immediate safety net while you set up a permanent fix: it runs its own internal check every 15 minutes and publishes any posts that should have gone live but did not.

The Missed Scheduled Posts Publisher (free, by the WPBeginner team) runs its own internal check every 15 minutes and publishes any posts that missed their schedule. Install it directly from Plugins > Add New in the WordPress admin.

This is not a replacement for fixing WP-Cron — it is a catch-all for the cases WP-Cron misses. Think of it as the insurance policy while Fix 3 handles the root cause.

Do you need to republish stuck posts manually first?
Yes — the plugin catches future misses, but any post already stuck as "Missed Schedule" needs to be republished manually. Open the post, click Edit next to the published status, change it to Published, and update.

Fix 3 — Replace WP-Cron with a Server Cron Job

Replacing WP-Cron with a real server cron job is the correct long-term fix for any site that needs reliable scheduling. A server cron job runs on the hosting server's own clock, completely independently of visitor traffic — load-shedding, low traffic, or a caching layer that bypasses WordPress on page loads all become irrelevant.

Step 1: Disable WP-Cron in wp-config.php

Open your wp-config.php file (in the root folder of your WordPress installation) and add this line before the "That's all, stop editing!" comment:

define('DISABLE_WP_CRON', true);

Save the file. WP-Cron is now inactive. Do not stop here — your scheduled tasks will stop running entirely until you complete Step 2.

Step 2: Create a server cron job via cPanel

Most South African shared hosts (including those using cPanel) give you access to cron job settings. In cPanel:

  1. Navigate to the Cron Jobs section.
  2. Set the frequency to every 30 minutes (twice per hour).
  3. Enter the following command, replacing yourdomain.co.za with your actual domain:
wget -q -O - https://yourdomain.co.za/wp-cron.php?doing_wp_cron >/dev/null 2>&1
  1. Click Add New Cron Job.

Every 30 minutes is the practical sweet spot: frequent enough that a post timed for 9 AM publishes by 9:30 AM at the latest, infrequent enough not to overload a shared hosting account. Do not set the interval shorter than 15 minutes on shared hosting.

No cPanel access?
If your host does not give you cron job access, a free external service such as EasyCron can call your wp-cron.php URL on a fixed schedule. Create an account, add https://yourdomain.co.za/wp-cron.php?doing_wp_cron as the URL to call, set the interval to 30 minutes, and save.

Fix 4 — Clear Your Cache and Audit Security Plugins

Two less obvious culprits cause intermittent missed-schedule failures: caching plugins and security firewalls. Both interfere with the mechanism WP-Cron uses to execute tasks — a background HTTP request from WordPress to its own wp-cron.php file (called a loopback request).

Cache plugins: An aggressive caching layer can serve a cached HTML page to an incoming request without letting WordPress process it. If WordPress never processes the request, WP-Cron never checks its task list. Fix: configure your caching plugin to exclude /wp-cron.php from cached responses. In WP Rocket, for example, this is under Advanced Rules > Never Cache URL(s).

Security plugins and firewalls: Some security plugin configurations — particularly aggressive firewall presets — can block WordPress's loopback request to wp-cron.php, treating the self-ping as a suspicious internal call. Check your security plugin's firewall log for blocked requests to wp-cron.php, and add it to the allow-list.

WordPress's built-in diagnostic tool helps here: navigate to Tools > Site Health > Info and scroll to Scheduled Events — this section shows whether any scheduled tasks are stuck or overdue, and whether the loopback request is reachable.

If you recently installed a new plugin or updated a theme and missed schedules began immediately after, a plugin conflict is likely. Use WordPress's Troubleshooting Mode (available via the Health Check plugin) to isolate the culprit without taking your site offline.

Low PHP memory is a less common but real cause. If the server runs out of memory mid-task, the cron job fails silently. You can raise the memory limit by adding the following to wp-config.php:

define('WP_MEMORY_LIMIT', '500M');

Not sure which hosting plan supports server cron jobs?

Tell us your current setup — host, WordPress version, caching plugin — and we will map the fastest fix path for your specific configuration.

Get a configuration review

Why South African Businesses Choose Growth Pulse Media

Growth Pulse Media is built around one operating principle: the person who builds and manages your digital presence is the same person who built and scaled a large South African e-commerce business from the ground up. Dirk van Greuning founded GPM after running campaigns, paying invoices, and managing the operational realities that textbooks skip — including the kinds of technical failures, like missed scheduled posts, that only surface at the worst possible moments.

That operator background shapes how GPM approaches web design for South African businesses: not as a sequence of deliverables, but as a business-critical system that needs to work reliably when traffic is low, when a security update breaks something, and when load-shedding shifts the conditions. All work is executed in-house, with a limited client load so that senior attention is the default, not the exception.

If your WordPress site has persistent technical issues — scheduling, contact forms, speed, or uptime — a structured audit typically surfaces the root cause in a single session. GPM works with a small number of clients at a time specifically so that the attention stays at the level that solves problems, not just the level that fields them.

Who This Is NOT For

Sites on fully managed WordPress hosting (WP Engine, Kinsta, etc.): Managed hosts replace WP-Cron with their own reliable scheduling infrastructure. This guide targets self-managed or cPanel-hosted WordPress sites. If you are on managed hosting and experiencing missed schedules, contact your host's support — the fix will be different.
Businesses with high-frequency editorial schedules: If you publish dozens of posts daily and precision timing matters within minutes, a server cron job running every 30 minutes still introduces a potential delay. A sub-minute cron job or a dedicated WP Cron replacement plugin with its own server process (such as Action Scheduler) is the correct tool.
Sites that have WP-Cron disabled by the host: Some managed hosts disable WP-Cron intentionally and document their replacement system. Check your host's knowledge base before assuming this guide's server cron steps apply — running two competing cron systems can create duplicate task execution.
Operators looking for a once-off quick fix without the underlying change: Manually republishing a stuck post solves today's problem. If you do not also fix the root cause — timezone, WP-Cron reliability, or cache blocking — the same post will miss its schedule next week. The permanent fix takes under 15 minutes and is worth doing once.

Want a full WordPress technical audit?

We will review your wp-config.php, cron setup, caching layer, and security configuration and tell you exactly what to fix and in what order. No obligation — we will get back to you within 24 hours.

Request a WordPress audit

Frequently Asked Questions

Why are my WordPress scheduled posts not publishing on time?

WordPress scheduled posts not publishing on time is almost always caused by WP-Cron, WordPress's built-in task scheduler, which only runs when a visitor loads a page on your site. If no visitor arrives near your scheduled publish time — including during load-shedding outages that reduce site traffic — the post stays in the queue until the next page load after the scheduled time.

A timezone mismatch between your WordPress settings and your intended publish time is the other common cause.

What does the "Missed Schedule" error mean in WordPress?

The "Missed Schedule" status means WordPress attempted to publish a post at the scheduled time but WP-Cron did not execute the task. The post is still queued and will publish as soon as the next visitor triggers a page load — or immediately if you manually change the post status to Published. The error does not mean the post content was lost or corrupted.

How do I permanently fix WordPress missed schedule errors?

The permanent fix is to replace WP-Cron with a real server cron job. Add define('DISABLE_WP_CRON', true); to your wp-config.php file, then set up a server cron job via cPanel to call https://yourdomain.co.za/wp-cron.php?doing_wp_cron every 30 minutes. This makes WordPress scheduling independent of visitor traffic. Install a missed-schedule safety-net plugin in the meantime as a catch-all.

Which WordPress timezone setting is correct for South Africa?

Set your WordPress timezone to Africa/Johannesburg in Settings > General. South Africa runs on UTC+2 with no daylight saving adjustment. Using a named city (Africa/Johannesburg) rather than a raw UTC offset (UTC+2) is recommended because named cities handle any future policy changes automatically and label times correctly in the WordPress editor.

Does low traffic cause WordPress scheduled posts to fail?

Yes. WP-Cron only fires when a visitor loads a page, so any quiet period — overnight, over a long weekend, or during a seasonal slowdown — creates a window where scheduled posts can sit unpublished.

The same logic applied historically during South Africa's load-shedding era (which ended mid-2025), when power outages suppressed traffic at predictable times. The practical fix in all cases is a server cron job, which runs on the hosting server's own clock and is unaffected by visitor traffic patterns.

Does disabling WP-Cron break anything else on my WordPress site?

Disabling WP-Cron without a replacement will stop all scheduled tasks — not just post publishing, but also plugin update checks, automated email sequences, backups triggered by WordPress, and any scheduled routines your plugins use. This is why you must set up a server cron job before or immediately after adding define('DISABLE_WP_CRON', true); to wp-config.php. If your host does not support server cron jobs, use an external cron service like EasyCron to call the wp-cron.php URL instead.

Need a WordPress site that works reliably — including scheduled publishing?

Growth Pulse Media handles web design, technical configuration, and ongoing site management for South African businesses that need more than a template. We work across WordPress, WooCommerce, and Shopify, with all builds and fixes executed in-house. No obligation — we will get back to you within 24 hours.

Talk to us about your site
Dirk van Greuning — Founder, Growth Pulse Media
Dirk van Greuning Founder, Growth Pulse Media

Founder of Growth Pulse Media and a specialist in South African search dominance. Dirk translates his experience in scaling South African businesses into high-velocity digital strategies for B2B and retail leaders. He writes about SEO, lead generation, and paid media from an operator's perspective — prioritising pipeline value over impressions.

Connect on LinkedIn