diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c
index aeaf1f3ab4..0ecb87b657 100644
--- a/src/backend/storage/lmgr/deadlock.c
+++ b/src/backend/storage/lmgr/deadlock.c
@@ -31,6 +31,7 @@
 #include "storage/lmgr.h"
 #include "storage/proc.h"
 #include "utils/memutils.h"
+#include "utils/timestamp.h"
 
 
 /*
@@ -450,10 +451,19 @@ FindLockCycle(PGPROC *checkProc,
 			  EDGE *softEdges,	/* output argument */
 			  int *nSoftEdges)	/* output argument */
 {
+	bool found;
+	TimestampTz now;
+	int i;
 	nVisitedProcs = 0;
 	nDeadlockDetails = 0;
 	*nSoftEdges = 0;
-	return FindLockCycleRecurse(checkProc, 0, softEdges, nSoftEdges);
+	found = FindLockCycleRecurse(checkProc, 0, softEdges, nSoftEdges);
+	now = GetCurrentTimestamp();
+	for (i = 0; i < nVisitedProcs; i++)
+	{
+		visitedProcs[i]->lastDeadlockCheck = now;
+	}
+	return found;
 }
 
 static bool
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 6f30e082b2..4802d9da24 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -86,6 +86,8 @@ static LOCALLOCK *lockAwaited = NULL;
 
 static DeadLockState deadlock_state = DS_NOT_YET_CHECKED;
 
+static bool inside_deadlock_check = false;
+
 /* Is a deadlock check pending? */
 static volatile sig_atomic_t got_deadlock_timeout;
 
@@ -187,6 +189,7 @@ InitProcGlobal(void)
 	ProcGlobal->checkpointerLatch = NULL;
 	pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PGPROCNO);
 	pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PGPROCNO);
+	pg_atomic_init_flag(&ProcGlobal->activeDeadlockCheck);
 
 	/*
 	 * Create and initialize all the PGPROC structures we'll need.  There are
@@ -763,6 +766,14 @@ ProcReleaseLocks(bool isCommit)
 {
 	if (!MyProc)
 		return;
+
+	/* Release deadlock detection flag is backend was interrupted inside deadlock check */
+	if (inside_deadlock_check)
+	{
+		pg_atomic_clear_flag(&ProcGlobal->activeDeadlockCheck);
+		inside_deadlock_check = false;
+	}
+
 	/* If waiting, get off wait queue (should only be needed after error) */
 	LockErrorCleanup();
 	/* Release standard locks, including session-level if aborting */
@@ -1665,6 +1676,19 @@ static void
 CheckDeadLock(void)
 {
 	int			i;
+	TimestampTz now = GetCurrentTimestamp();
+
+	/*
+	 * Ensure that only one backend is checking for deadlock.
+	 * Otherwise under high load cascade of deadlock timeout expirations can cause stuck of Postgres.
+	 */
+	if (now - MyProc->lastDeadlockCheck < DeadlockTimeout*1000
+		|| !pg_atomic_test_set_flag(&ProcGlobal->activeDeadlockCheck))
+	{
+		enable_timeout_after(DEADLOCK_TIMEOUT, DeadlockTimeout);
+		return;
+	}
+	inside_deadlock_check = true;
 
 	/*
 	 * Acquire exclusive lock on the entire shared lock data structures. Must
@@ -1741,6 +1765,9 @@ CheckDeadLock(void)
 check_done:
 	for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
 		LWLockRelease(LockHashPartitionLockByIndex(i));
+
+	pg_atomic_clear_flag(&ProcGlobal->activeDeadlockCheck);
+	inside_deadlock_check = false;
 }
 
 /*
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 5c19a61dcf..4da6c17e1d 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -21,6 +21,7 @@
 #include "storage/lock.h"
 #include "storage/pg_sema.h"
 #include "storage/proclist_types.h"
+#include "datatype/timestamp.h"
 
 /*
  * Each backend advertises up to PGPROC_MAX_CACHED_SUBXIDS TransactionIds
@@ -200,6 +201,7 @@ struct PGPROC
 	PGPROC	   *lockGroupLeader;	/* lock group leader, if I'm a member */
 	dlist_head	lockGroupMembers;	/* list of members, if I'm a leader */
 	dlist_node	lockGroupLink;	/* my member link, if I'm a member */
+	TimestampTz lastDeadlockCheck;
 };
 
 /* NOTE: "typedef struct PGPROC PGPROC" appears in storage/lock.h. */
@@ -267,6 +269,8 @@ typedef struct PROC_HDR
 	int			startupProcPid;
 	/* Buffer id of the buffer that Startup process waits for pin on, or -1 */
 	int			startupBufferPinWaitBufId;
+	/* Deadlock detection is in progress */
+	pg_atomic_flag activeDeadlockCheck;
 } PROC_HDR;
 
 extern PGDLLIMPORT PROC_HDR *ProcGlobal;
