diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 0cc3296..60bebee 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1560,7 +1560,8 @@ SET ENABLE_SEQSCAN TO OFF;
         Specifies whether transaction commit will wait for WAL records
         to be written to disk before the command returns a <quote>success</>
         indication to the client.  Valid values are <literal>on</>,
-        <literal>local</>, and <literal>off</>.  The default, and safe, value
+        <literal>local</>, <literal>fallback</> and <literal>off</>.
+         The default, and safe, value
         is <literal>on</>.  When <literal>off</>, there can be a delay between
         when success is reported to the client and when the transaction is
         really guaranteed to be safe against a server crash.  (The maximum
@@ -1574,6 +1575,10 @@ SET ENABLE_SEQSCAN TO OFF;
         can be a useful alternative when performance is more important than
         exact certainty about the durability of a transaction.  For more
         discussion see <xref linkend="wal-async-commit">.
+        If set to <literal>fallback</>, the master will act as if it was set to
+         <literal>on</> except in the special case where all suitable synchronous
+         standbys are currentlydisconnected, in which case it will temporarily fall
+	  back to <literal>local</>  mode until suitable standbys are connected.
        </para>
        <para>
         If <xref linkend="guc-synchronous-standby-names"> is set, this
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index e9ae1e8..7c39bad 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -352,7 +352,7 @@ CheckpointerMain(void)
 		ThisTimeLineID = GetRecoveryTargetTLI();
 
 	/* Do this once before starting the loop, then just at SIGHUP time. */
-	SyncRepUpdateSyncStandbysDefined();
+	SyncRepUpdateConfig();
 
 	/*
 	 * Loop forever
@@ -381,7 +381,7 @@ CheckpointerMain(void)
 			got_SIGHUP = false;
 			ProcessConfigFile(PGC_SIGHUP);
 			/* update global shmem state for sync rep */
-			SyncRepUpdateSyncStandbysDefined();
+			SyncRepUpdateConfig();
 		}
 		if (checkpoint_requested)
 		{
@@ -657,7 +657,7 @@ CheckpointWriteDelay(int flags, double progress)
 			got_SIGHUP = false;
 			ProcessConfigFile(PGC_SIGHUP);
 			/* update global shmem state for sync rep */
-			SyncRepUpdateSyncStandbysDefined();
+			SyncRepUpdateConfig();
 		}
 
 		AbsorbFsyncRequests();
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index 95de6c7..559c89c 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -126,6 +126,17 @@ SyncRepWaitForLSN(XLogRecPtr XactCommitLSN)
 		return;
 	}
 
+
+	/*
+	 * Fast exit also if running in standalone mode
+	 * because there are no synchronous standbys connected
+	 */
+	if ( WalSndCtl->sync_standalone_master )
+	{
+		LWLockRelease(SyncRepLock);
+		return;
+	}
+
 	/*
 	 * Set our waitLSN so WALSender will know when to wake us, and add
 	 * ourselves to the queue.
@@ -326,6 +337,58 @@ SyncRepCleanupAtProcExit(void)
 }
 
 /*
+ * Check if the master should switch to standalone mode and stop trying
+ *  to wait for standby synchronization because there are no standby servers currently
+ * connected. If there are servers connected, then switch back and start waiting for them.
+ * This function is called on connect/disconnect of standby WAL senders. Must hold SyncRepLock.
+ */
+void SyncRepCheckIfStandaloneMaster()
+{
+	bool sync_standby_connected = false;
+	int i = 0;
+
+	if (!SyncRepRequested() || !SyncStandbysDefined() || ! WalSndCtl->sync_standalone_allowed)
+	{
+		WalSndCtl->sync_standalone_master = false;
+		return;
+	}
+
+	for (i = 0; i < max_wal_senders && ! sync_standby_connected; i++)
+	{
+		volatile WalSnd *walsnd = &WalSndCtl->walsnds[i];
+		if ( walsnd->pid != 0 && walsnd->sync_standby_priority )
+		{
+			sync_standby_connected = true;
+			if ( WalSndCtl->sync_standalone_master )
+			{
+				ereport(LOG,
+					(errmsg("waiting for standby synchronization"),
+					 errhidestmt(true)));
+
+				WalSndCtl->sync_standalone_master = false;
+			}
+		}
+	}
+
+	if ( ! sync_standby_connected )
+	{
+		if ( ! WalSndCtl->sync_standalone_master )
+		{
+			ereport(LOG,
+				(errmsg("not waiting for standby synchronization"),
+				 errhidestmt(true)));
+
+			WalSndCtl->sync_standalone_master = true;
+
+			/*
+			 * We just switched to standalone mode so wake up anyone that is waiting
+			 */
+			SyncRepWakeQueue(true);
+		}
+	}
+}
+
+/*
  * ===========================================================
  * Synchronous Replication functions for wal sender processes
  * ===========================================================
@@ -345,10 +408,11 @@ SyncRepInitConfig(void)
 	 * for handling replies from standby.
 	 */
 	priority = SyncRepGetStandbyPriority();
-	if (MyWalSnd->sync_standby_priority != priority)
+	if (priority)
 	{
 		LWLockAcquire(SyncRepLock, LW_EXCLUSIVE);
 		MyWalSnd->sync_standby_priority = priority;
+		SyncRepCheckIfStandaloneMaster();
 		LWLockRelease(SyncRepLock);
 		ereport(DEBUG1,
 			(errmsg("standby \"%s\" now has synchronous standby priority %u",
@@ -567,6 +631,17 @@ SyncRepWakeQueue(bool all)
 }
 
 /*
+ * The background writer calls this as needed to update the shared WalSndCtl
+ * with new sync-related config.
+ */
+void
+SyncRepUpdateConfig(void)
+{
+	SyncRepUpdateSyncStandbysDefined();
+	SyncRepUpdateSyncStandaloneAllowed();
+}
+
+/*
  * The background writer calls this as needed to update the shared
  * sync_standbys_defined flag, so that backends don't remain permanently wedged
  * if synchronous_standby_names is unset.  It's safe to check the current value
@@ -598,6 +673,28 @@ SyncRepUpdateSyncStandbysDefined(void)
 		 * the queue (and never wake up).  This prevents that.
 		 */
 		WalSndCtl->sync_standbys_defined = sync_standbys_defined;
+		LWLockRelease(SyncRepLock);
+	}
+
+
+}
+
+/*
+ * The background writer calls this as needed to update the shared
+ * sync_standalone_allowed flag. If the flag is enabled, then also check if
+ * any synchronous standby servers are connected in order to switch mode from sync
+ * replication to standalone mode.
+ */
+void
+SyncRepUpdateSyncStandaloneAllowed(void)
+{
+	bool		SyncRepStandaloneMasterAllowed = SyncRepRequested() && synchronous_commit == SYNCHRONOUS_COMMIT_FALLBACK;
+	if ( SyncRepStandaloneMasterAllowed != WalSndCtl->sync_standalone_allowed )
+	{
+		LWLockAcquire(SyncRepLock, LW_EXCLUSIVE);
+
+		WalSndCtl->sync_standalone_allowed = SyncRepStandaloneMasterAllowed;
+		SyncRepCheckIfStandaloneMaster();
 
 		LWLockRelease(SyncRepLock);
 	}
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index ea86520..1da44e0 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -955,6 +955,13 @@ WalSndKill(int code, Datum arg)
 	MyWalSnd->pid = 0;
 	DisownLatch(&MyWalSnd->latch);
 
+	/*
+	 * Check if this was the last standby
+	 */
+	LWLockAcquire(SyncRepLock, LW_EXCLUSIVE);
+	SyncRepCheckIfStandaloneMaster();
+	LWLockRelease(SyncRepLock);
+
 	/* WalSnd struct isn't mine anymore */
 	MyWalSnd = NULL;
 }
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index da7b6d4..f2d8f96 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -370,11 +370,12 @@ static const struct config_enum_entry constraint_exclusion_options[] = {
 };
 
 /*
- * Although only "on", "off", and "local" are documented, we
+ * Although only "on", "off", "fallback" and "local" are documented, we
  * accept all the likely variants of "on" and "off".
  */
 static const struct config_enum_entry synchronous_commit_options[] = {
 	{"local", SYNCHRONOUS_COMMIT_LOCAL_FLUSH, false},
+	{"fallback", SYNCHRONOUS_COMMIT_FALLBACK, false},
 	{"on", SYNCHRONOUS_COMMIT_ON, false},
 	{"off", SYNCHRONOUS_COMMIT_OFF, false},
 	{"true", SYNCHRONOUS_COMMIT_ON, true},
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 315db46..83bc120 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -158,7 +158,7 @@
 #wal_level = minimal			# minimal, archive, or hot_standby
 					# (change requires restart)
 #fsync = on				# turns forced synchronization on or off
-#synchronous_commit = on		# synchronization level; on, off, or local
+#synchronous_commit = on		# synchronization level; on, off, fallback or local
 #wal_sync_method = fsync		# the default is the first option
 					# supported by the operating system:
 					#   open_datasync
@@ -215,6 +215,7 @@
 				# from standby(s); '*' = all
 #vacuum_defer_cleanup_age = 0	# number of xacts by which cleanup is delayed
 
+
 # - Standby Servers -
 
 # These settings are ignored on a master server
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index aaa6204..6e8f7dc 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -55,6 +55,7 @@ typedef enum
 {
 	SYNCHRONOUS_COMMIT_OFF,		/* asynchronous commit */
 	SYNCHRONOUS_COMMIT_LOCAL_FLUSH,		/* wait for local flush only */
+	SYNCHRONOUS_COMMIT_FALLBACK,	/* wait for local and remote flush, if connected standbys */
 	SYNCHRONOUS_COMMIT_REMOTE_FLUSH		/* wait for local and remote flush */
 }	SyncCommitLevel;
 
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index 65b725f..66a2c71 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -34,7 +34,9 @@ extern void SyncRepInitConfig(void);
 extern void SyncRepReleaseWaiters(void);
 
 /* called by wal writer */
-extern void SyncRepUpdateSyncStandbysDefined(void);
+extern void SyncRepUpdateSyncConfig(void);
+
+extern void SyncRepCheckIfStandaloneMaster(void);
 
 /* called by various procs */
 extern int	SyncRepWakeQueue(bool all);
diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h
index be7a341..954c79f 100644
--- a/src/include/replication/walsender_private.h
+++ b/src/include/replication/walsender_private.h
@@ -85,6 +85,17 @@ typedef struct
 	 */
 	bool		sync_standbys_defined;
 
+	/*
+	 * Is the synchronous master allowed to switch to standalone mode when no
+	 * synchronous standby servers are connected ? Protected by SyncRepLock.
+	 */
+	bool            sync_standalone_allowed;
+
+	/*
+	 * Is the synchronous master currently running in standalone mode ? Protected by SyncRepLock.
+	 */
+	bool            sync_standalone_master;
+
 	WalSnd		walsnds[1];		/* VARIABLE LENGTH ARRAY */
 } WalSndCtlData;
 
