diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index fa5aeed31db3176846bfae261d0f4096f55b5141..15c23204611d2e82e54c82c1c0d6acdccfe7535a 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -899,13 +899,9 @@ PostmasterMain(int argc, char *argv[])
 
 	/*
 	 * Now that loadable modules have had their chance to register background
-	 * workers, calculate MaxBackends.  Add one for the autovacuum launcher.
+	 * workers, calculate MaxBackends.
 	 */
-	MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
-		GetNumShmemAttachedBgworkers();
-	/* internal error because the values were all checked previously */
-	if (MaxBackends > MAX_BACKENDS)
-		elog(ERROR, "too many backends configured");
+	InitializeMaxBackends();
 
 	/*
 	 * Establish input sockets.
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 0fbf65f73402fd04b81dbcf02e4febeafacd8354..3948eac039b32fc17b93acbe043bcf757221d131 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -421,6 +421,26 @@ pg_split_opts(char **argv, int *argcp, char *optstr)
 	}
 }
 
+/*
+ * Initialize MaxBackends value from config options.
+ *
+ * This must be called after modules have had the chance to register background
+ * workers in shared_preload_libraries, and before shared memory size is
+ * determined.
+ */
+void
+InitializeMaxBackends(void)
+{
+	Assert(MaxBackends == 0);
+
+	/* the extra unit accounts for the autovacuum launcher */
+	MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
+		GetNumShmemAttachedBgworkers();
+
+	/* internal error because the values were all checked previously */
+	if (MaxBackends > MAX_BACKENDS)
+		elog(ERROR, "too many backends configured");
+}
 
 /*
  * Early initialization of a backend (either standalone or under postmaster).
@@ -433,6 +453,8 @@ pg_split_opts(char **argv, int *argcp, char *optstr)
 void
 BaseInit(void)
 {
+	InitializeMaxBackends();
+
 	/*
 	 * Attach to shared memory and semaphores, and initialize our
 	 * input/output/debugging file descriptors.
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 2fb7be48adf7097dab80ebff207493deb2d8cf73..99858a765f1a0e18ff32c973eccb04ba196a7dc5 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -394,6 +394,7 @@ extern AuxProcType MyAuxProcType;
 
 /* in utils/init/postinit.c */
 extern void pg_split_opts(char **argv, int *argcp, char *optstr);
+extern void InitializeMaxBackends(void);
 extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 			 char *out_dbname);
 extern void BaseInit(void);