diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 220b8164c3..83534edc82 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -789,6 +789,13 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
           <literal>wait_event</literal> will identify the specific wait point.
          </para>
         </listitem>
+        <listitem>
+         <para>
+          <literal>RecoveryConflict</literal>: The server process is waiting for a
+          recovery conflict resolution.  <literal>wait_event</literal> will identify
+          the specific wait point.
+         </para>
+        </listitem>
        </itemizedlist>
       </entry>
      </row>
@@ -1797,6 +1804,15 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
          <entry><literal>WALWrite</literal></entry>
          <entry>Waiting for a write to a WAL file.</entry>
         </row>
+        <row>
+         <entry morerows="2"><literal>RecoveryConflict</literal></entry>
+         <entry><literal>Snapshot</literal></entry>
+         <entry>Waiting for recovery conflict resolution on a physical cleanup.</entry>
+        </row>
+        <row>
+         <entry><literal>Tablespace</literal></entry>
+         <entry>Waiting for recovery conflict resolution on dropping tablespace.</entry>
+        </row>
       </tbody>
      </tgroup>
     </table>
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index ab42df7e1b..129ce4cc81 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -308,6 +308,7 @@ static const char *pgstat_get_wait_client(WaitEventClient w);
 static const char *pgstat_get_wait_ipc(WaitEventIPC w);
 static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
 static const char *pgstat_get_wait_io(WaitEventIO w);
+static const char *pgstat_get_wait_recovery_conflict(WaitEventRecoveryConflict w);
 
 static void pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype);
 static void pgstat_send(void *msg, int len);
@@ -3480,6 +3481,9 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
 		case PG_WAIT_IO:
 			event_type = "IO";
 			break;
+		case PG_WAIT_RECOVERY_CONFLICT:
+			event_type = "RecoveryConflict";
+			break;
 		default:
 			event_type = "???";
 			break;
@@ -3557,6 +3561,14 @@ pgstat_get_wait_event(uint32 wait_event_info)
 				event_name = pgstat_get_wait_io(w);
 				break;
 			}
+		case PG_WAIT_RECOVERY_CONFLICT:
+			{
+				WaitEventRecoveryConflict w =
+					(WaitEventRecoveryConflict) wait_event_info;
+
+				event_name = pgstat_get_wait_recovery_conflict(w);
+				break;
+			}
 		default:
 			event_name = "unknown wait event";
 			break;
@@ -4066,6 +4078,32 @@ pgstat_get_wait_io(WaitEventIO w)
 	return event_name;
 }
 
+/* ----------
+ * pgstat_get_wait_recovery_conflict() -
+ *
+ * Convert WaitEventRecoveryConflict to string.
+ * ----------
+ */
+static const char *
+pgstat_get_wait_recovery_conflict(WaitEventRecoveryConflict w)
+{
+	const char *event_name = "unknown wait event";
+
+	switch (w)
+	{
+		case WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT:
+			event_name = "Snapshot";
+			break;
+		case WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE:
+			event_name = "Tablespace";
+			break;
+		default:
+			event_name = "unknown wait event";
+			break;
+	}
+
+	return event_name;
+}
 
 /* ----------
  * pgstat_get_backend_current_activity() -
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 08f695a980..63dfa8f26a 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -43,7 +43,9 @@ int			max_standby_streaming_delay = 30 * 1000;
 static HTAB *RecoveryLockLists;
 
 static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
-												   ProcSignalReason reason, bool report_waiting);
+												   ProcSignalReason reason,
+												   uint32 wait_event_info,
+												   bool report_waiting);
 static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason);
 static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts);
 static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks);
@@ -184,7 +186,7 @@ static int	standbyWait_us = STANDBY_INITIAL_WAIT_US;
  * more then we return true, if we can wait some more return false.
  */
 static bool
-WaitExceedsMaxStandbyDelay(void)
+WaitExceedsMaxStandbyDelay(uint32 wait_event_info)
 {
 	TimestampTz ltime;
 
@@ -198,11 +200,14 @@ WaitExceedsMaxStandbyDelay(void)
 	/*
 	 * Sleep a bit (this is essential to avoid busy-waiting).
 	 */
-	pg_usleep(standbyWait_us);
+	ResetLatch(MyLatch);
+	WaitLatch(MyLatch,
+			  WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT,
+			  standbyWait_us,
+			  wait_event_info);
 
 	/*
-	 * Progressively increase the sleep times, but not to more than 1s, since
-	 * pg_usleep isn't interruptible on some platforms.
+	 * Progressively increase the sleep times, but not to more than 1s.
 	 */
 	standbyWait_us *= 2;
 	if (standbyWait_us > 1000000)
@@ -223,7 +228,8 @@ WaitExceedsMaxStandbyDelay(void)
  */
 static void
 ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
-									   ProcSignalReason reason, bool report_waiting)
+									   ProcSignalReason reason, uint32 wait_event_info,
+									   bool report_waiting)
 {
 	TimestampTz waitStart = 0;
 	char	   *new_status;
@@ -264,7 +270,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
 			}
 
 			/* Is it time to kill it? */
-			if (WaitExceedsMaxStandbyDelay())
+			if (WaitExceedsMaxStandbyDelay(wait_event_info))
 			{
 				pid_t		pid;
 
@@ -317,6 +323,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode
 
 	ResolveRecoveryConflictWithVirtualXIDs(backends,
 										   PROCSIG_RECOVERY_CONFLICT_SNAPSHOT,
+										   WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT,
 										   true);
 }
 
@@ -346,6 +353,7 @@ ResolveRecoveryConflictWithTablespace(Oid tsid)
 												InvalidOid);
 	ResolveRecoveryConflictWithVirtualXIDs(temp_file_users,
 										   PROCSIG_RECOVERY_CONFLICT_TABLESPACE,
+										   WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE,
 										   true);
 }
 
@@ -417,6 +425,7 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag)
 		 */
 		ResolveRecoveryConflictWithVirtualXIDs(backends,
 											   PROCSIG_RECOVERY_CONFLICT_LOCK,
+											   PG_WAIT_LOCK | locktag.locktag_type,
 											   false);
 	}
 	else
@@ -430,10 +439,10 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag)
 		timeouts[0].type = TMPARAM_AT;
 		timeouts[0].fin_time = ltime;
 		enable_timeouts(timeouts, 1);
-	}
 
-	/* Wait to be signaled by the release of the Relation Lock */
-	ProcWaitForSignal(PG_WAIT_LOCK | locktag.locktag_type);
+		/* Wait to be signaled by the release of the Relation Lock */
+		ProcWaitForSignal(PG_WAIT_LOCK | locktag.locktag_type);
+	}
 
 	/*
 	 * Clear any timeout requests established above.  We assume here that the
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 763c1ee2bd..6c1c8bff7c 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -743,6 +743,7 @@ typedef enum BackendState
 #define PG_WAIT_IPC					0x08000000U
 #define PG_WAIT_TIMEOUT				0x09000000U
 #define PG_WAIT_IO					0x0A000000U
+#define PG_WAIT_RECOVERY_CONFLICT	0x0B000000U
 
 /* ----------
  * Wait Events - Activity
@@ -934,6 +935,19 @@ typedef enum
 	WAIT_EVENT_WAL_WRITE
 } WaitEventIO;
 
+/* ----------
+ * Wait Events - Recovery Conflict
+ *
+ * Use this category when a process is waiting for a recovery conflict
+ * resolution.
+ * ----------
+ */
+typedef enum
+{
+	WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT = PG_WAIT_RECOVERY_CONFLICT,
+	WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE,
+} WaitEventRecoveryConflict;
+
 /* ----------
  * Command type for progress reporting purposes
  * ----------
