diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 20ccb2d6b54..d8961977d40 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -12873,6 +12873,29 @@ LOG:  CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-logical-replication-subscriptions-enabled" xreflabel="logical_replication_subscriptions_enabled">
+      <term><varname>logical_replication_subscriptions_enabled</varname> (<type>boolean</type>)
+      <indexterm>
+       <primary>logical_replication_subscriptions_enabled</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Enables or disables all logical replication subscription apply workers in this server.
+        When set to <literal>off</literal>, subscriber workers will wait until the value
+        is changed to <literal>on</literal>. The change takes effect immediately.
+       </para>
+       <para>
+        This parameter can be changed at run time with <command>ALTER SYSTEM</command>
+       </para>
+       <para>
+        This setting is intended for operational maintenance, such as pausing
+        replication apply during upgrades or large schema changes. This is also useful to not
+        start subscribers immediately after point-in-time restore.
+       </para>
+      </listitem>
+     </varlistentry>
+
     </variablelist>
   </sect1>
   <sect1 id="runtime-config-short">
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 37377f7eb63..281997e932f 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -53,6 +53,7 @@ int			max_sync_workers_per_subscription = 2;
 int			max_parallel_apply_workers_per_subscription = 2;
 
 LogicalRepWorker *MyLogicalRepWorker = NULL;
+bool logical_replication_subscriptions_enabled = true;
 
 typedef struct LogicalRepCtxStruct
 {
@@ -1193,6 +1194,8 @@ ApplyLauncherMain(Datum main_arg)
 									   ALLOCSET_DEFAULT_SIZES);
 		oldctx = MemoryContextSwitchTo(subctx);
 
+		if (logical_replication_subscriptions_enabled)
+		{
 			/*
 			* Start any missing workers for enabled subscriptions.
 			*
@@ -1314,6 +1317,7 @@ ApplyLauncherMain(Datum main_arg)
 									wal_retrieve_retry_interval - elapsed);
 				}
 			}
+		}
 
 		/*
 		 * Drop the CONFLICT_DETECTION_SLOT slot if there is no subscription
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 0fdc5de57ba..48b122c1c2d 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -3948,6 +3948,13 @@ LogicalRepApplyLoop(XLogRecPtr last_received)
 
 		CHECK_FOR_INTERRUPTS();
 		
+		if (!logical_replication_subscriptions_enabled)
+		{
+			ereport(LOG,
+				(errmsg("logical replication apply worker exiting because replication is disabled")));
+			proc_exit(0);
+		}
+
 		MemoryContextSwitchTo(ApplyMessageContext);
 
 		len = walrcv_receive(LogRepWorkerWalRcvConn, &buf, &fd);
@@ -4697,6 +4704,17 @@ maybe_reread_subscription(void)
 	Subscription *newsub;
 	bool		started_tx = false;
 
+	/*
+	 * Exit if logical_replication_subscriber_enabled is set to false.
+	*/
+	if (!logical_replication_subscriptions_enabled)
+	{
+		ereport(LOG,
+				(errmsg("logical replication worker for subscription \"%s\" will stop because logical replication subscriptions were disabled.",
+						MySubscription->name)));
+		proc_exit(0);
+	}
+
 	/* When cache state is valid there is nothing to do here. */
 	if (MySubscriptionValid)
 		return;
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index d14b1678e7f..0724997934b 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -2143,6 +2143,16 @@ struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"logical_replication_subscriptions_enabled", PGC_SIGHUP, REPLICATION_SUBSCRIBERS,
+			gettext_noop("Enables or disables launching logical replication subscriptions."),
+			NULL
+		},
+		&logical_replication_subscriptions_enabled,
+		true, NULL,
+		NULL, NULL, NULL, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index a9d8293474a..cd88c9730ed 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -396,7 +396,7 @@
 					# (change requires restart)
 #max_sync_workers_per_subscription = 2	# taken from max_logical_replication_workers
 #max_parallel_apply_workers_per_subscription = 2	# taken from max_logical_replication_workers
-
+#logical_replication_subscriptions_enabled = on   # enable or disable logical replication subscriptions
 
 #------------------------------------------------------------------------------
 # QUERY TUNING
diff --git a/src/include/replication/logicallauncher.h b/src/include/replication/logicallauncher.h
index b29453e8e4f..ce5ff5c606f 100644
--- a/src/include/replication/logicallauncher.h
+++ b/src/include/replication/logicallauncher.h
@@ -15,6 +15,7 @@
 extern PGDLLIMPORT int max_logical_replication_workers;
 extern PGDLLIMPORT int max_sync_workers_per_subscription;
 extern PGDLLIMPORT int max_parallel_apply_workers_per_subscription;
+extern PGDLLIMPORT bool logical_replication_subscriptions_enabled;
 
 extern void ApplyLauncherRegister(void);
 extern void ApplyLauncherMain(Datum main_arg);
