diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 74c3371c21d34cfd9abacb84a54d5ced67ed5462..59e70b6f375bb561966fbf68879f77485d070e6b 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -3649,6 +3649,33 @@ threadRun(void *arg)
 				maxsock = sock;
 		}
 
+		/* also wake up to print the next progress report on time */
+		if (progress && min_usec > 0
+#if !defined(PTHREAD_FORK_EMULATION)
+			&& thread->tid == 0
+#endif   /* !PTHREAD_FORK_EMULATION */
+			)
+		{
+			/* get current time if needed */
+			if (now_usec == 0)
+			{
+				instr_time	now;
+
+				INSTR_TIME_SET_CURRENT(now);
+				now_usec = INSTR_TIME_GET_MICROSEC(now);
+			}
+
+			if (now_usec >= next_report)
+				min_usec = 0;
+			else if ((next_report - now_usec) < min_usec)
+				min_usec = next_report - now_usec;
+		}
+
+		/*
+		 * Sleep until we receive data from the server, or a nap-time
+		 * specified in the script ends, or it's time to print a progress
+		 * report.
+		 */
 		if (min_usec > 0 && maxsock != -1)
 		{
 			int			nsocks; /* return from select(2) */
@@ -3754,7 +3781,15 @@ threadRun(void *arg)
 				last_lags = lags;
 				last_report = now;
 				last_skipped = thread->throttle_latency_skipped;
-				next_report += (int64) progress *1000000;
+
+				/*
+				 * Ensure that the next report is in the future, in case
+				 * pgbench/postgres got stuck somewhere.
+				 */
+				do
+				{
+					next_report += (int64) progress *1000000;
+				} while (now >= next_report);
 			}
 		}
 #else
@@ -3818,7 +3853,15 @@ threadRun(void *arg)
 				last_lags = lags;
 				last_report = now;
 				last_skipped = thread->throttle_latency_skipped;
-				next_report += (int64) progress *1000000;
+
+				/*
+				 * Ensure that the next report is in the future, in case
+				 * pgbench/postgres got stuck somewhere.
+				 */
+				do
+				{
+					next_report += (int64) progress *1000000;
+				} while (now >= next_report);
 			}
 		}
 #endif   /* PTHREAD_FORK_EMULATION */