diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c
index dbc5f884e8..c99646fa6f 100644
--- a/src/backend/access/transam/transam.c
+++ b/src/backend/access/transam/transam.c
@@ -73,6 +73,14 @@ TransactionLogFetch(TransactionId transactionId)
 		return TRANSACTION_STATUS_ABORTED;
 	}
 
+	/*
+	 * Safeguard that we have called TransactionIsIdInProgress() before
+	 * checking commit log manager, to ensure that we do not cache the
+	 * result until the xid is no longer in the procarray at eoxact.
+	 */
+	if (!TransactionIdKnownNotInProgress(transactionId))
+		return TRANSACTION_STATUS_IN_PROGRESS;
+
 	/*
 	 * Get the transaction status.
 	 */
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 13d192ec2b..a47ba74c68 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -262,6 +262,11 @@ static ProcArrayStruct *procArray;
 
 static PGPROC *allProcs;
 
+/*
+ * Cache to reduce overhead of repeated calls to TransactionIdIsInProgress()
+ */
+static TransactionId cachedXidIsNotInProgress = InvalidTransactionId;
+
 /*
  * Bookkeeping for tracking emulated transactions in recovery
  */
@@ -1400,7 +1405,7 @@ TransactionIdIsInProgress(TransactionId xid)
 	 * already known to be completed, we can fall out without any access to
 	 * shared memory.
 	 */
-	if (TransactionIdIsKnownCompleted(xid))
+	if (TransactionIdKnownNotInProgress(xid))
 	{
 		xc_by_known_xact_inc();
 		return false;
@@ -1558,6 +1563,7 @@ TransactionIdIsInProgress(TransactionId xid)
 	if (nxids == 0)
 	{
 		xc_no_overflow_inc();
+		cachedXidIsNotInProgress = xid;
 		return false;
 	}
 
@@ -1572,7 +1578,10 @@ TransactionIdIsInProgress(TransactionId xid)
 	xc_slow_answer_inc();
 
 	if (TransactionIdDidAbort(xid))
+	{
+		cachedXidIsNotInProgress = xid;
 		return false;
+	}
 
 	/*
 	 * It isn't aborted, so check whether the transaction tree it belongs to
@@ -1590,6 +1599,16 @@ TransactionIdIsInProgress(TransactionId xid)
 		}
 	}
 
+	cachedXidIsNotInProgress = xid;
+	return false;
+}
+
+bool
+TransactionIdKnownNotInProgress(TransactionId xid)
+{
+	if (TransactionIdEquals(cachedXidIsNotInProgress, xid))
+		return true;
+
 	return false;
 }
 
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index 9a2816de51..50a5ac13e5 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -289,6 +289,9 @@ extern TransactionId TransactionIdLatest(TransactionId mainxid,
 										 int nxids, const TransactionId *xids);
 extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
 
+/* in procarray.c */
+extern bool TransactionIdKnownNotInProgress(TransactionId xid);
+
 /* in transam/varsup.c */
 extern FullTransactionId GetNewTransactionId(bool isSubXact);
 extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid);
