diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 9856968997..16c5a6ee65 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1281,7 +1281,7 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
          <entry>Waiting for confirmation from remote server during synchronous replication.</entry>
         </row>
         <row>
-         <entry morerows="2"><literal>Timeout</></entry>
+         <entry morerows="3"><literal>Timeout</></entry>
          <entry><literal>BaseBackupThrottle</></entry>
          <entry>Waiting during base backup when throttling activity.</entry>
         </row>
@@ -1294,6 +1294,10 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
          <entry>Waiting to apply WAL at recovery because it is delayed.</entry>
         </row>
         <row>
+         <entry><literal>RecoveryConflict</></entry>
+         <entry>Waiting for conflict resolution of query running on standby.</entry>
+        </row>
+        <row>
          <entry morerows="65"><literal>IO</></entry>
          <entry><literal>BufFileRead</></entry>
          <entry>Waiting for a read from a buffered file.</entry>
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 56a8bf2d17..6309014703 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3600,6 +3600,9 @@ pgstat_get_wait_timeout(WaitEventTimeout w)
 		case WAIT_EVENT_RECOVERY_APPLY_DELAY:
 			event_name = "RecoveryApplyDelay";
 			break;
+		case WAIT_EVENT_RECOVERY_CONFLICT:
+			event_name = "RecoveryConflict";
+			break;
 		/* no default case, so that compiler will warn */
 	}
 
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 8e57f933ca..8f0017e8e2 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -148,8 +148,8 @@ GetStandbyLimitTime(void)
 	}
 }
 
-#define STANDBY_INITIAL_WAIT_US  1000
-static int	standbyWait_us = STANDBY_INITIAL_WAIT_US;
+#define STANDBY_INITIAL_WAIT_MS  1
+static int	standbyWait_ms = STANDBY_INITIAL_WAIT_MS;
 
 /*
  * Standby wait logic for ResolveRecoveryConflictWithVirtualXIDs.
@@ -160,8 +160,7 @@ static bool
 WaitExceedsMaxStandbyDelay(void)
 {
 	TimestampTz ltime;
-
-	CHECK_FOR_INTERRUPTS();
+	int			rc;
 
 	/* Are we past the limit time? */
 	ltime = GetStandbyLimitTime();
@@ -171,15 +170,29 @@ WaitExceedsMaxStandbyDelay(void)
 	/*
 	 * Sleep a bit (this is essential to avoid busy-waiting).
 	 */
-	pg_usleep(standbyWait_us);
+	rc = WaitLatch(MyLatch,
+				   WL_TIMEOUT | WL_POSTMASTER_DEATH,
+				   standbyWait_ms,
+				   WAIT_EVENT_RECOVERY_CONFLICT);
+
+	/* emergency bailout if postmaster has died */
+	if (rc & WL_POSTMASTER_DEATH)
+		exit(1);
 
 	/*
-	 * Progressively increase the sleep times, but not to more than 1s, since
-	 * pg_usleep isn't interruptable on some platforms.
+	 * Progressively increase the sleep times, but not to more than 1s.
+	 * This process is expected to wake up reasonably fast after the
+	 * transactions this is waiting for are committed.
 	 */
-	standbyWait_us *= 2;
-	if (standbyWait_us > 1000000)
-		standbyWait_us = 1000000;
+	if (rc & WL_TIMEOUT)
+	{
+		standbyWait_ms *= 2;
+		if (standbyWait_ms > 1000)
+			standbyWait_ms = 1000;
+	}
+
+	/* An interrupt may have occurred while waiting */
+	CHECK_FOR_INTERRUPTS();
 
 	return false;
 }
@@ -206,8 +219,8 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
 
 	while (VirtualTransactionIdIsValid(*waitlist))
 	{
-		/* reset standbyWait_us for each xact we wait for */
-		standbyWait_us = STANDBY_INITIAL_WAIT_US;
+		/* reset standbyWait_ms for each xact we wait for */
+		standbyWait_ms = STANDBY_INITIAL_WAIT_MS;
 
 		/* wait until the virtual xid is gone */
 		while (!VirtualXactLock(*waitlist, false))
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index e29397f25b..2bb213fdd4 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -824,7 +824,8 @@ typedef enum
 {
 	WAIT_EVENT_BASE_BACKUP_THROTTLE = PG_WAIT_TIMEOUT,
 	WAIT_EVENT_PG_SLEEP,
-	WAIT_EVENT_RECOVERY_APPLY_DELAY
+	WAIT_EVENT_RECOVERY_APPLY_DELAY,
+	WAIT_EVENT_RECOVERY_CONFLICT
 } WaitEventTimeout;
 
 /* ----------
