diff --git a/contrib/pg_xlogdump/pg_xlogdump.c b/contrib/pg_xlogdump/pg_xlogdump.c
index 024ab01efa08c076d0bc9e3811a4678c2f141d3d..e947696429d754907da8b828cad9852575dac84a 100644
--- a/contrib/pg_xlogdump/pg_xlogdump.c
+++ b/contrib/pg_xlogdump/pg_xlogdump.c
@@ -32,6 +32,7 @@ typedef struct XLogDumpPrivate
 	char	   *inpath;
 	XLogRecPtr	startptr;
 	XLogRecPtr	endptr;
+	bool		endptr_reached;
 } XLogDumpPrivate;
 
 typedef struct XLogDumpConfig
@@ -40,6 +41,7 @@ typedef struct XLogDumpConfig
 	bool		bkp_details;
 	int			stop_after_records;
 	int			already_displayed_records;
+	bool		follow;
 
 	/* filter options */
 	int			filter_by_rmgr;
@@ -308,7 +310,10 @@ XLogDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen,
 		else if (targetPagePtr + reqLen <= private->endptr)
 			count = private->endptr - targetPagePtr;
 		else
+		{
+			private->endptr_reached = true;
 			return -1;
+		}
 	}
 
 	XLogDumpXLogRead(private->inpath, private->timeline, targetPagePtr,
@@ -386,6 +391,7 @@ usage(void)
 	printf("\nOptions:\n");
 	printf("  -b, --bkp-details      output detailed information about backup blocks\n");
 	printf("  -e, --end=RECPTR       stop reading at log position RECPTR\n");
+	printf("  -f, --follow           keep retrying after reaching end of WAL\n");
 	printf("  -n, --limit=N          number of records to display\n");
 	printf("  -p, --path=PATH        directory in which to find log segment files\n");
 	printf("                         (default: ./pg_xlog)\n");
@@ -414,6 +420,7 @@ main(int argc, char **argv)
 	static struct option long_options[] = {
 		{"bkp-details", no_argument, NULL, 'b'},
 		{"end", required_argument, NULL, 'e'},
+		{"follow", no_argument, NULL, 'f'},
 		{"help", no_argument, NULL, '?'},
 		{"limit", required_argument, NULL, 'n'},
 		{"path", required_argument, NULL, 'p'},
@@ -436,10 +443,12 @@ main(int argc, char **argv)
 	private.timeline = 1;
 	private.startptr = InvalidXLogRecPtr;
 	private.endptr = InvalidXLogRecPtr;
+	private.endptr_reached = false;
 
 	config.bkp_details = false;
 	config.stop_after_records = -1;
 	config.already_displayed_records = 0;
+	config.follow = false;
 	config.filter_by_rmgr = -1;
 	config.filter_by_xid = InvalidTransactionId;
 	config.filter_by_xid_enabled = false;
@@ -450,7 +459,7 @@ main(int argc, char **argv)
 		goto bad_argument;
 	}
 
-	while ((option = getopt_long(argc, argv, "be:?n:p:r:s:t:Vx:",
+	while ((option = getopt_long(argc, argv, "be:?fn:p:r:s:t:Vx:",
 								 long_options, &optindex)) != -1)
 	{
 		switch (option)
@@ -467,6 +476,9 @@ main(int argc, char **argv)
 				}
 				private.endptr = (uint64) xlogid << 32 | xrecoff;
 				break;
+			case 'f':
+				config.follow = true;
+				break;
 			case '?':
 				usage();
 				exit(EXIT_SUCCESS);
@@ -683,9 +695,22 @@ main(int argc, char **argv)
 			   (uint32) (first_record >> 32), (uint32) first_record,
 			   (uint32) (first_record - private.startptr));
 
-	while ((record = XLogReadRecord(xlogreader_state, first_record, &errormsg)))
+	for (;;)
 	{
-		/* continue after the last record */
+		/* try to read the next record */
+		record = XLogReadRecord(xlogreader_state, first_record, &errormsg);
+		if (!record)
+		{
+			if (!config.follow || private.endptr_reached)
+				break;
+			else
+			{
+				sleep(1);
+				continue;
+			}
+		}
+
+		/* after reading the first record, continue at next one */
 		first_record = InvalidXLogRecPtr;
 		XLogDumpDisplayRecord(&config, xlogreader_state->ReadRecPtr, record);
 
diff --git a/doc/src/sgml/pg_xlogdump.sgml b/doc/src/sgml/pg_xlogdump.sgml
index 173962211981acadadf7c26d39422af441eb271b..1d1a2cea8702f0ce6f3cbe8db98c656aa5ad5aed 100644
--- a/doc/src/sgml/pg_xlogdump.sgml
+++ b/doc/src/sgml/pg_xlogdump.sgml
@@ -91,6 +91,17 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>-f</option></term>
+      <term><option>--follow</option></term>
+      <listitem>
+       <para>
+        After reaching the end of valid WAL, keep polling once per second for
+        new WAL to appear.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-n <replaceable>limit</replaceable></option></term>
       <term><option>--limit=<replaceable>limit</replaceable></option></term>