diff --git i/src/bin/initdb/initdb.c w/src/bin/initdb/initdb.c
index 97f15971e2b..68bce3773b0 100644
--- i/src/bin/initdb/initdb.c
+++ w/src/bin/initdb/initdb.c
@@ -76,6 +76,10 @@
 #include "getopt_long.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
+#include "portability/instr_time.h"
+
+
+//#define REPLACE_FAST
 
 
 /* Ideally this would be in a .h file, but it hardly seems worth the trouble */
@@ -174,6 +178,8 @@ static bool caught_signal = false;
 static bool output_failed = false;
 static int	output_errno = 0;
 static char *pgdata_native;
+static instr_time initdb_start_time;
+static instr_time last_ts;
 
 /* defaults */
 static int	n_connections = 10;
@@ -278,6 +284,8 @@ static void check_locale_name(int category, const char *locale,
 static bool check_locale_encoding(const char *locale, int encoding);
 static void setlocales(void);
 static void usage(const char *progname);
+static void progress(const char *point);
+
 void		setup_pgdata(void);
 void		setup_bin_paths(const char *argv0);
 void		setup_data_file_paths(void);
@@ -309,10 +317,16 @@ do { \
 
 #define PG_CMD_PUTS(line) \
 do { \
-	if (fputs(line, cmdfd) < 0 || fflush(cmdfd) < 0) \
-		output_failed = true, output_errno = errno; \
+  if (fputs(line, cmdfd) < 0) \
+      output_failed = true, output_errno = errno; \
 } while (0)
 
+#define PG_CMD_FLUSH \
+do { \
+   if (fflush(cmdfd) < 0) \
+        output_failed = true, output_errno = errno; \
+ } while (0)
+
 #define PG_CMD_PRINTF(fmt, ...) \
 do { \
 	if (fprintf(cmdfd, fmt, __VA_ARGS__) < 0 || fflush(cmdfd) < 0) \
@@ -362,6 +376,51 @@ escape_quotes_bki(const char *src)
 	return result;
 }
 
+#ifdef REPLACE_FAST
+
+static void
+replace_one_token(char **linep, const char *token, const char *replacement)
+{
+	char	   *line = *linep;
+	char	   *where;
+	int			toklen,
+				replen,
+				diff;
+	int			linelen;
+	int			pre;
+
+	/* nothing to do if NULL or no change needed */
+	if ((where = strstr(line, token)) == NULL)
+		return;
+
+	//fprintf(stderr, "replacing %s with %s, before: %s", token, replacement, line);
+
+	toklen = strlen(token);
+	replen = strlen(replacement);
+	diff = replen - toklen;
+
+	linelen = strlen(line);
+
+	pre = where - line;
+
+	/* ensure there's enough space */
+	if (diff > 0)
+	{
+		*linep = repalloc(line, linelen + diff + 1);
+		line = *linep;
+		where = line + pre;
+	}
+
+	/* move bit after token aside */
+	memmove(where + replen, where + toklen, linelen - pre - toklen + 1);
+
+	/* and copy in the the new contents */
+	memcpy(where, replacement, replen);
+
+	//fprintf(stderr, "after: %s\n", line);
+}
+#endif
+
 /*
  * make a copy of the array of lines, with token replaced by replacement
  * the first time it occurs on each line.
@@ -1357,7 +1416,17 @@ bootstrap_template1(void)
 	char	  **line;
 	char	  **bki_lines;
 	char		headerline[MAXPGPATH];
+#ifdef REPLACE_FAST
+	char		namedatalen_buf[64];
+	char		sizeof_pointer_buf[64];
+	int			numlines;
+	const char *username_esc;
+	const char *encoding;
+	const char *lc_collate_esc;
+	const char *lc_ctype_esc;
+#else
 	char		buf[64];
+#endif
 
 	printf(_("running bootstrap script ... "));
 	fflush(stdout);
@@ -1379,8 +1448,43 @@ bootstrap_template1(void)
 		exit(1);
 	}
 
+	progress("bootstrap read");
+
 	/* Substitute for various symbols used in the BKI file */
 
+#ifdef REPLACE_FAST
+	numlines = 0;
+	for (int i = 0; bki_lines[i]; i++)
+		numlines++;
+
+	sprintf(namedatalen_buf, "%d", NAMEDATALEN);
+	sprintf(sizeof_pointer_buf, "%d", (int) sizeof(Pointer));
+	username_esc = escape_quotes_bki(username);
+	encoding = encodingid_to_string(encodingid);
+	lc_collate_esc = escape_quotes_bki(lc_collate);
+	lc_ctype_esc = escape_quotes_bki(lc_ctype);
+
+	for (int i = 0; i < numlines; i++)
+	{
+		char **line = &bki_lines[i];
+
+		replace_one_token(line, "NAMEDATALEN", namedatalen_buf);
+		replace_one_token(line, "SIZEOF_POINTER", sizeof_pointer_buf);
+
+		replace_one_token(line, "ALIGNOF_POINTER",
+						  (sizeof(Pointer) == 4) ? "i" : "d");
+
+		replace_one_token(line, "FLOAT8PASSBYVAL",
+						  FLOAT8PASSBYVAL ? "true" : "false");
+
+		replace_one_token(line, "POSTGRES", username_esc);
+		replace_one_token(line, "ENCODING", encoding);
+		replace_one_token(line, "LC_COLLATE", lc_collate_esc);
+		replace_one_token(line, "LC_CTYPE", lc_ctype_esc);
+	}
+
+#else
+
 	sprintf(buf, "%d", NAMEDATALEN);
 	bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);
 
@@ -1404,6 +1508,8 @@ bootstrap_template1(void)
 
 	bki_lines = replace_token(bki_lines, "LC_CTYPE",
 							  escape_quotes_bki(lc_ctype));
+#endif
+	progress("bootstrap replace");
 
 	/* Also ensure backend isn't confused by this environment var: */
 	unsetenv("PGCLIENTENCODING");
@@ -1419,14 +1525,24 @@ bootstrap_template1(void)
 
 	PG_CMD_OPEN;
 
+	progress("bootstrap start");
+
 	for (line = bki_lines; *line != NULL; line++)
 	{
 		PG_CMD_PUTS(*line);
 		free(*line);
 	}
 
+	progress("bootstrap write");
+
+	PG_CMD_FLUSH;
+
+	progress("bootstrap flush");
+
 	PG_CMD_CLOSE;
 
+	progress("bootstrap shutdown");
+
 	free(bki_lines);
 
 	check_ok();
@@ -1450,6 +1566,7 @@ setup_auth(FILE *cmdfd)
 
 	for (line = pg_authid_setup; *line != NULL; line++)
 		PG_CMD_PUTS(*line);
+	PG_CMD_FLUSH;
 
 	if (superuser_password)
 		PG_CMD_PRINTF("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n",
@@ -1537,6 +1654,7 @@ setup_depend(FILE *cmdfd)
 
 	for (line = pg_depend_setup; *line != NULL; line++)
 		PG_CMD_PUTS(*line);
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -1556,6 +1674,7 @@ setup_run_file(FILE *cmdfd, const char *filename)
 	}
 
 	PG_CMD_PUTS("\n\n");
+	PG_CMD_FLUSH;
 
 	free(lines);
 }
@@ -1579,6 +1698,7 @@ setup_description(FILE *cmdfd)
 				"  AND NOT EXISTS (SELECT 1 FROM pg_description "
 				"   WHERE objoid = o_oid AND classoid = 'pg_operator'::regclass"
 				"         AND description LIKE 'deprecated%');\n\n");
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -1598,6 +1718,7 @@ setup_collation(FILE *cmdfd)
 
 	/* Now import all collations we can find in the operating system */
 	PG_CMD_PUTS("SELECT pg_import_system_collations('pg_catalog');\n\n");
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -1763,6 +1884,7 @@ setup_privileges(FILE *cmdfd)
 							   escape_quotes(username));
 	for (line = priv_lines; *line != NULL; line++)
 		PG_CMD_PUTS(*line);
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -1820,6 +1942,7 @@ static void
 load_plpgsql(FILE *cmdfd)
 {
 	PG_CMD_PUTS("CREATE EXTENSION plpgsql;\n\n");
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -1830,6 +1953,7 @@ vacuum_db(FILE *cmdfd)
 {
 	/* Run analyze before VACUUM so the statistics are frozen. */
 	PG_CMD_PUTS("ANALYZE;\n\nVACUUM FREEZE;\n\n");
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -1888,6 +2012,7 @@ make_template0(FILE *cmdfd)
 
 	for (line = template0_setup; *line; line++)
 		PG_CMD_PUTS(*line);
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -1907,6 +2032,7 @@ make_postgres(FILE *cmdfd)
 
 	for (line = postgres_setup; *line; line++)
 		PG_CMD_PUTS(*line);
+	PG_CMD_FLUSH;
 }
 
 /*
@@ -2771,6 +2897,8 @@ initialize_data_directory(void)
 	printf(_("creating subdirectories ... "));
 	fflush(stdout);
 
+	progress("subdirs");
+
 	for (i = 0; i < lengthof(subdirs); i++)
 	{
 		char	   *path;
@@ -2802,9 +2930,13 @@ initialize_data_directory(void)
 	/* Now create all the text config files */
 	setup_config();
 
+	progress("config");
+
 	/* Bootstrap template1 */
 	bootstrap_template1();
 
+	progress("bootstrap");
+
 	/*
 	 * Make the per-database PG_VERSION for template1 only after init'ing it
 	 */
@@ -2814,7 +2946,7 @@ initialize_data_directory(void)
 	 * Create the stuff we don't need to use bootstrap mode for, using a
 	 * backend running in simple standalone mode.
 	 */
-	fputs(_("performing post-bootstrap initialization ... "), stdout);
+	fputs(_("performing post-bootstrap initialization ... \n"), stdout);
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
@@ -2826,11 +2958,16 @@ initialize_data_directory(void)
 
 	setup_auth(cmdfd);
 
+	progress("auth");
+
 	setup_run_file(cmdfd, system_constraints_file);
+	progress("constraints");
 
 	setup_run_file(cmdfd, system_functions_file);
+	progress("functions");
 
 	setup_depend(cmdfd);
+	progress("depend");
 
 	/*
 	 * Note that no objects created after setup_depend() will be "pinned".
@@ -2838,30 +2975,56 @@ initialize_data_directory(void)
 	 */
 
 	setup_run_file(cmdfd, system_views_file);
+	progress("views");
 
 	setup_description(cmdfd);
+	progress("desc");
 
 	setup_collation(cmdfd);
+	progress("coll");
 
 	setup_run_file(cmdfd, dictionary_file);
+	progress("dict");
 
 	setup_privileges(cmdfd);
+	progress("priv");
 
 	setup_schema(cmdfd);
+	progress("schema");
 
 	load_plpgsql(cmdfd);
+	progress("plpgsql");
 
 	vacuum_db(cmdfd);
+	progress("vacuum");
 
 	make_template0(cmdfd);
+	progress("db dict");
 
 	make_postgres(cmdfd);
+	progress("db postgres");
 
 	PG_CMD_CLOSE;
 
 	check_ok();
+
+	progress("shutdown");
 }
 
+static void
+progress(const char *point)
+{
+	instr_time now;
+
+	INSTR_TIME_SET_CURRENT(now);
+
+	fprintf(stderr, "%.3f ms + %.3f ms: %s\n",
+			(INSTR_TIME_GET_DOUBLE(now) - INSTR_TIME_GET_DOUBLE(initdb_start_time)) * 1000,
+			(INSTR_TIME_GET_DOUBLE(now) - INSTR_TIME_GET_DOUBLE(last_ts))  * 1000,
+			point);
+
+	last_ts = now;
+}
 
 int
 main(int argc, char *argv[])
@@ -2912,6 +3075,9 @@ main(int argc, char *argv[])
 	PQExpBuffer start_db_cmd;
 	char		pg_ctl_path[MAXPGPATH];
 
+	INSTR_TIME_SET_CURRENT(initdb_start_time);
+	last_ts = initdb_start_time;
+
 	/*
 	 * Ensure that buffering behavior of stdout matches what it is in
 	 * interactive usage (at least on most platforms).  This prevents
@@ -3100,6 +3266,8 @@ main(int argc, char *argv[])
 		exit(1);
 	}
 
+	progress("start");
+
 	check_authmethod_unspecified(&authmethodlocal);
 	check_authmethod_unspecified(&authmethodhost);
 
@@ -3133,8 +3301,12 @@ main(int argc, char *argv[])
 
 	get_restricted_token();
 
+	progress("checks");
+
 	setup_pgdata();
 
+	progress("setup_pgdata");
+
 	setup_bin_paths(argv[0]);
 
 	effective_user = get_id();
@@ -3160,6 +3332,8 @@ main(int argc, char *argv[])
 
 	setup_text_search();
 
+	progress("setup_more");
+
 	printf("\n");
 
 	if (data_checksums)
@@ -3174,12 +3348,16 @@ main(int argc, char *argv[])
 
 	initialize_data_directory();
 
+	progress("initialize data dir complete");
+
 	if (do_sync)
 	{
 		fputs(_("syncing data to disk ... "), stdout);
 		fflush(stdout);
 		fsync_pgdata(pg_data, PG_VERSION_NUM);
 		check_ok();
+
+		progress("fsync");
 	}
 	else
 		printf(_("\nSync to disk skipped.\nThe data directory might become corrupt if the operating system crashes.\n"));
