WP-Cron is not a system cron — it is a check that runs on incoming requests. If no one visits the site, scheduled jobs do not fire.
Disable it with define('DISABLE_WP_CRON', true) in wp-config.php and run wp cron event run --due-now from a system cron every five minutes.
This eliminates the front-end performance penalty and guarantees jobs run on time.