diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 147fd53..6608666 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -526,6 +526,8 @@ typedef struct XLogCtlData
 	XLogRecPtr	RedoRecPtr;		/* a recent copy of Insert->RedoRecPtr */
 	uint32		ckptXidEpoch;	/* nextXID & epoch of latest checkpoint */
 	TransactionId ckptXid;
+	XLogRecPtr	forcedSegSwitchLSN;	/* LSN position of last forced segment
+									 * switch */
 	XLogRecPtr	asyncXactLSN;	/* LSN of newest async commit/abort */
 	XLogRecPtr	replicationSlotMinLSN;	/* oldest LSN needed by any slot */
 
@@ -6315,6 +6317,7 @@ StartupXLOG(void)
 					 checkPoint.newestCommitTs);
 	XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
 	XLogCtl->ckptXid = checkPoint.nextXid;
+	XLogCtl->forcedSegSwitchLSN = InvalidXLogRecPtr;
 
 	/*
 	 * Initialize replication slots, before there's a chance to remove
@@ -8988,6 +8991,10 @@ RequestXLogSwitch(void)
 	XLogBeginInsert();
 	RecPtr = XLogInsert(RM_XLOG_ID, XLOG_SWITCH);
 
+	SpinLockAcquire(&XLogCtl->info_lck);
+	XLogCtl->forcedSegSwitchLSN = RecPtr;
+	SpinLockRelease(&XLogCtl->info_lck);
+
 	return RecPtr;
 }
 
@@ -10628,6 +10635,21 @@ GetXLogWriteRecPtr(void)
 }
 
 /*
+ * Get last WAL position where an XLOG segment has been forcibly switched.
+ */
+XLogRecPtr
+GetXLogLastSwitchPtr(void)
+{
+	XLogRecPtr	last_switch_lsn;
+
+	SpinLockAcquire(&XLogCtl->info_lck);
+	last_switch_lsn = XLogCtl->forcedSegSwitchLSN;
+	SpinLockRelease(&XLogCtl->info_lck);
+
+	return last_switch_lsn;
+}
+
+/*
  * Returns the redo pointer of the last checkpoint or restartpoint. This is
  * the oldest point in WAL that we still need, if we have to restart recovery.
  */
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 65465d6..3abf725 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -315,14 +315,39 @@ BackgroundWriterMain(void)
 												  LOG_SNAPSHOT_INTERVAL_MS);
 
 			/*
-			 * only log if enough time has passed and some xlog record has
-			 * been inserted.
+			 * Only log if enough time has passed and some xlog record has
+			 * been inserted on a new segment. On an idle system where
+			 * segments can be archived in a fast pace with for example a
+			 * low archive_command setting, avoid as well logging a new
+			 * standby snapshot if the current insert position is still
+			 * at the beginning of the segment that has just been switched.
+			 *
+			 * It is possible that GetXLogLastSwitchPtr points to the last
+			 * position of previous segment or to the first position of the
+			 * new segment after the switch, hence take both cases into
+			 * account when deciding if a standby snapshot should be taken.
+			 * (see comments on top of RequestXLogSwitch for more details).
 			 */
-			if (now >= timeout &&
-				last_snapshot_lsn != GetXLogInsertRecPtr())
+			if (now >= timeout)
 			{
-				last_snapshot_lsn = LogStandbySnapshot();
-				last_snapshot_ts = now;
+				XLogRecPtr	insert_lsn = GetXLogInsertRecPtr();
+				XLogRecPtr	last_forced_switch_lsn = GetXLogLastSwitchPtr();
+				XLogSegNo	insert_segno;
+				bool		is_switch_current;
+
+				XLByteToSeg(insert_lsn, insert_segno);
+
+				is_switch_current =
+					XLByteInSeg(last_forced_switch_lsn, insert_segno - 1) ||
+					XLByteInSeg(last_forced_switch_lsn, insert_segno);
+
+				if (last_snapshot_lsn != insert_lsn &&
+					(!is_switch_current ||
+					 (insert_lsn % XLOG_SEG_SIZE) != SizeOfXLogLongPHD))
+				{
+					last_snapshot_lsn = LogStandbySnapshot();
+					last_snapshot_ts = now;
+				}
 			}
 		}
 
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 790ca66..f6eb9c3 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -235,6 +235,7 @@ extern void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream);
 extern XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI);
 extern XLogRecPtr GetXLogInsertRecPtr(void);
 extern XLogRecPtr GetXLogWriteRecPtr(void);
+extern XLogRecPtr GetXLogLastSwitchPtr(void);
 extern bool RecoveryIsPaused(void);
 extern void SetRecoveryPause(bool recoveryPause);
 extern TimestampTz GetLatestXTime(void);
