diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index 1303217..707ea37 100644
--- a/contrib/pgbench/pgbench.c
+++ b/contrib/pgbench/pgbench.c
@@ -74,7 +74,7 @@ static int	pthread_join(pthread_t th, void **thread_return);
 #include <pthread.h>
 #else
 /* Use emulation with fork. Rename pthread identifiers to avoid conflicts */
-
+#define PTHREAD_FORK_EMULATION
 #include <sys/wait.h>
 
 #define pthread_t				pg_pthread_t
@@ -164,6 +164,8 @@ bool		use_log;			/* log transaction latencies to a file */
 bool		use_quiet;			/* quiet logging onto stderr */
 int			agg_interval;		/* log aggregates instead of individual
 								 * transactions */
+int			progress = 0;       /* thread progress report every this seconds */
+int         progress_nclients = 0; /* number of clients for progress report */
 bool		is_connect;			/* establish connection for each transaction */
 bool		is_latencies;		/* report per-command latencies */
 int			main_pid;			/* main process id used in log filename */
@@ -354,6 +356,8 @@ usage(void)
 		   "               protocol for submitting queries to server (default: simple)\n"
 		   "  -n           do not run VACUUM before tests\n"
 		   "  -N           do not update tables \"pgbench_tellers\" and \"pgbench_branches\"\n"
+		   "  -P NUM, --progress NUM\n"
+		   "               show progress report about every NUM seconds\n"
 		   "  -r           report average latency per command\n"
 		   "  -s NUM       report this scale factor in output\n"
 		   "  -S           perform SELECT-only transactions\n"
@@ -2115,6 +2119,7 @@ main(int argc, char **argv)
 		{"unlogged-tables", no_argument, &unlogged_tables, 1},
 		{"sampling-rate", required_argument, NULL, 4},
 		{"aggregate-interval", required_argument, NULL, 5},
+		{"progress", required_argument, NULL, 'P'},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -2181,7 +2186,7 @@ main(int argc, char **argv)
 	state = (CState *) pg_malloc(sizeof(CState));
 	memset(state, 0, sizeof(CState));
 
-	while ((c = getopt_long(argc, argv, "ih:nvp:dqSNc:j:Crs:t:T:U:lf:D:F:M:", long_options, &optindex)) != -1)
+	while ((c = getopt_long(argc, argv, "ih:nvp:dqSNc:j:Crs:t:T:U:lf:D:F:M:P:", long_options, &optindex)) != -1)
 	{
 		switch (c)
 		{
@@ -2336,6 +2341,16 @@ main(int argc, char **argv)
 					exit(1);
 				}
 				break;
+			case 'P':
+				progress = atoi(optarg);
+				if (progress <= 0)
+				{
+					fprintf(stderr,
+					   "thread progress delay (-P) must not be negative (%s)\n",
+							optarg);
+					exit(1);
+				}
+				break;
 			case 0:
 				/* This covers long options which take no argument. */
 				break;
@@ -2401,6 +2416,15 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
+#ifdef PTHREAD_FORK_EMULATION
+	if (progress && nthreads>1)
+	{
+		fprintf(stderr,
+				"option --progress does not work with thread fork emulation");
+		exit(1);
+	}
+#endif /* PTHREAD_FORK_EMULATION */
+
 	/* --sampling-rate may be used only with -l */
 	if (sample_rate > 0.0 && !use_log)
 	{
@@ -2461,6 +2485,7 @@ main(int argc, char **argv)
 	 * changed after fork.
 	 */
 	main_pid = (int) getpid();
+	progress_nclients = nclients;
 
 	if (nclients > 1)
 	{
@@ -2712,6 +2737,11 @@ threadRun(void *arg)
 	int			nstate = thread->nstate;
 	int			remains = nstate;		/* number of remaining clients */
 	int			i;
+	/* for reporting progress: */
+	int64       thread_start = INSTR_TIME_GET_MICROSEC(thread->start_time);
+	int64		last_report = thread_start;
+	int64		next_report = last_report + progress * 1000000;
+	int64		last_count = 0;
 
 	AggVals		aggs;
 
@@ -2875,6 +2905,30 @@ threadRun(void *arg)
 				st->con = NULL;
 			}
 		}
+
+		/* progress report by thread 0 */
+		if (progress && thread->tid == 0)
+		{
+			instr_time now_time;
+			int64 now;
+			INSTR_TIME_SET_CURRENT(now_time);
+			now = INSTR_TIME_GET_MICROSEC(now_time);
+			if (now >= next_report)
+			{
+				/* generate and show report */
+				int64 count = 0;
+				int64 run = now - last_report;
+				/* thread 0 reports other threads data  */
+				for (i = 0 ; i < progress_nclients ; i++)
+					count += state[i].cnt;
+				fprintf(stderr, "progress: %.1f s %.1f tps\n",
+						(now - thread_start) / 1000000.0,
+						1000000.0 * (count-last_count) / run);
+				last_count = count;
+				last_report = now;
+				next_report += progress * 1000000;
+			}
+		}
 	}
 
 done:
diff --git a/doc/src/sgml/pgbench.sgml b/doc/src/sgml/pgbench.sgml
index 8775606..e82757c 100644
--- a/doc/src/sgml/pgbench.sgml
+++ b/doc/src/sgml/pgbench.sgml
@@ -392,6 +392,17 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
      </varlistentry>
 
      <varlistentry>
+      <term><option>-P</option> <replaceable>sec</></term>
+      <term><option>--progress</option> <replaceable>sec</></term>
+      <listitem>
+       <para>
+	Show progress report about every <literal>sec</> seconds.
+	Note: this option does not work under thread fork emulation.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><option>-s</option> <replaceable>scale_factor</></term>
       <listitem>
        <para>
