From 0f4a1aa14cb6d8378f3de6f863a49e80829d797e Mon Sep 17 00:00:00 2001
From: Rishu Bagga <rishu@WA-TP-1104.localdomain>
Date: Thu, 17 Jul 2025 17:10:26 -0700
Subject: [PATCH] add option to allow out of order notifications for
 performance

---
 src/backend/commands/async.c        | 17 +++++++++++++++--
 src/backend/utils/misc/guc_tables.c | 13 ++++++++++++-
 src/include/commands/async.h        |  1 +
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 4bd37d5beb5..293449321af 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -150,6 +150,7 @@
 #include "utils/ps_status.h"
 #include "utils/snapmgr.h"
 #include "utils/timestamp.h"
+#include "utils/guc_tables.h"
 
 
 /*
@@ -423,6 +424,7 @@ static bool tryAdvanceTail = false;
 
 /* GUC parameters */
 bool		Trace_notify = false;
+bool		publish_notifications_out_of_order = false;
 
 /* For 8 KB pages this gives 8 GB of disk space */
 int			max_notify_queue_pages = 1048576;
@@ -919,9 +921,20 @@ PreCommit_Notify(void)
 		 * (Historical note: before PG 9.0, a similar lock on "database 0" was
 		 * used by the flatfiles mechanism.)
 		 */
-		LockSharedObject(DatabaseRelationId, InvalidOid, 0,
-						 AccessExclusiveLock);
 
+		/*
+		 * Allow notifications to be written out of commit order
+		 * for performance gains. Note that some notifications
+		 * may be published even if the transaction fails
+		 * later on.
+		 */
+		if (!publish_notifications_out_of_order)
+		{
+			LockSharedObject(DatabaseRelationId, InvalidOid, 0,
+							AccessExclusiveLock);
+	
+		}
+	
 		/* Now push the notifications into the queue */
 		nextNotify = list_head(pendingNotifies->events);
 		while (nextNotify != NULL)
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index d14b1678e7f..400face33dd 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -638,7 +638,6 @@ char	   *role_string;
 /* should be static, but guc.c needs to get at this */
 bool		in_hot_standby_guc;
 
-
 /*
  * Displayable names for context types (enum GucContext)
  *
@@ -1549,6 +1548,18 @@ struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"publish_notifications_out_of_order", PGC_USERSET, DEVELOPER_OPTIONS,
+			gettext_noop("Allows NOTIFY messages to be published out of order for increased performance."),
+			gettext_noop("When enabled, NOTIFY messages may be delivered to listeners out of order, which can improve performance " 
+						"but may break applications that rely on strict ordering."),
+			GUC_NOT_IN_SAMPLE
+		},
+		&publish_notifications_out_of_order,
+		false,
+		NULL, NULL, NULL
+	},
+
 #ifdef LOCK_DEBUG
 	{
 		{"trace_locks", PGC_SUSET, DEVELOPER_OPTIONS,
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index f75c3df9556..6e7981d9981 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -16,6 +16,7 @@
 #include <signal.h>
 
 extern PGDLLIMPORT bool Trace_notify;
+extern PGDLLIMPORT bool publish_notifications_out_of_order;
 extern PGDLLIMPORT int max_notify_queue_pages;
 extern PGDLLIMPORT volatile sig_atomic_t notifyInterruptPending;
 
-- 
2.47.1

