diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php
index 12e1273..d1a7d22 100644
--- a/src/wp-admin/includes/class-wp-site-health.php
+++ b/src/wp-admin/includes/class-wp-site-health.php
@@ -1411,7 +1411,8 @@ class WP_Site_Health {
 				)
 			);
 		} else {
-			if ( $this->has_missed_cron() ) {
+			$has_missed_cron = $this->has_missed_cron();
+			if ( 'failed' === $has_missed_cron ) {
 				$result['status'] = 'recommended';
 
 				$result['label'] = __( 'A scheduled event has failed' );
@@ -1424,6 +1425,19 @@ class WP_Site_Health {
 						$this->last_missed_cron
 					)
 				);
+			} elseif ( 'late' === $has_missed_cron ) {
+				$result['status'] = 'recommended';
+
+				$result['label'] = __( 'A scheduled event is late' );
+
+				$result['description'] = sprintf(
+					'<p>%s</p>',
+					sprintf(
+						/* translators: %s: The name of the failed cron event. */
+						__( 'The scheduled event, %s, is late to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.' ),
+						$this->last_missed_cron
+					)
+				);
 			}
 		}
 
@@ -1907,25 +1921,46 @@ class WP_Site_Health {
 	/**
 	 * Check if any scheduled tasks have been missed.
 	 *
-	 * Returns a boolean value of `true` if a scheduled task has been missed and ends processing. If the list of
-	 * crons is an instance of WP_Error, return the instance instead of a boolean value.
+	 * Returns a boolean `false` if there are no missed cron jobs, otherwise
+	 * returns the status of missed events as either `late` or `failed`.
+	 *
+	 * If getting cron jobs has failed, a WP_Error object is returned.
 	 *
 	 * @since 5.2.0
 	 *
-	 * @return bool|WP_Error true if a cron was missed, false if it wasn't. WP_Error if the cron is set to that.
+	 * @return bool|string|WP_Error False if no cron was missed,
+	 *                              'failed' if a cron failed to run,
+	 *                              'late' if a cron is late to run.
+	 *                              WP_Error if the cron is set to that.
 	 */
 	public function has_missed_cron() {
 		if ( is_wp_error( $this->crons ) ) {
 			return $this->crons;
 		}
 
+		$late_timeout   = 0;
+		$failed_timeout = -5 * MINUTE_IN_SECONDS;
+		$late_cron      = false;
+
+		if ( defined( 'DISABLE_WP_CRON' ) && true === DISABLE_WP_CRON ) {
+			$late_timeout   = -15 * MINUTE_IN_SECONDS;
+			$failed_timeout = -1 * HOUR_IN_SECONDS;
+		}
+
 		foreach ( $this->crons as $id => $cron ) {
-			if ( ( $cron->time - time() ) < 0 ) {
+			if ( ( $cron->time - time() ) < $failed_timeout ) {
+				$this->last_missed_cron = $cron->hook;
+				return 'failed';
+			} elseif ( ( $cron->time - time() < $late_timeout ) ) {
 				$this->last_missed_cron = $cron->hook;
-				return true;
+				$late_cron              = true;
 			}
 		}
 
+		if ( true === $late_cron ) {
+			return 'late';
+		}
+
 		return false;
 	}
 
