diff --git a/keyserver/src/push/crypto.js b/keyserver/src/push/crypto.js
--- a/keyserver/src/push/crypto.js
+++ b/keyserver/src/push/crypto.js
@@ -46,14 +46,16 @@
 
   encryptedNotification.id = notification.id;
   encryptedNotification.payload.id = notification.id;
+  encryptedNotification.payload.keyserverID = notification.payload.keyserverID;
   encryptedNotification.topic = notification.topic;
   encryptedNotification.sound = notification.aps.sound;
   encryptedNotification.pushType = 'alert';
   encryptedNotification.mutableContent = true;
 
-  const { id, ...payloadSansId } = notification.payload;
+  const { id, keyserverID, ...payloadSansUnencryptedData } =
+    notification.payload;
   const unencryptedPayload = {
-    ...payloadSansId,
+    ...payloadSansUnencryptedData,
     badge: notification.aps.badge.toString(),
     merged: notification.body,
   };
@@ -197,8 +199,9 @@
   +payloadSizeExceeded: boolean,
   +encryptionOrder?: number,
 }> {
-  const { id, badgeOnly, ...unencryptedPayload } = notification.data;
-  let unencryptedData = { badgeOnly };
+  const { id, keyserverID, badgeOnly, ...unencryptedPayload } =
+    notification.data;
+  let unencryptedData = { badgeOnly, keyserverID };
   if (id) {
     unencryptedData = { ...unencryptedData, id };
   }
@@ -238,12 +241,13 @@
   // We don't validate payload size for rescind
   // since they are expected to be small and
   // never exceed any FCM limit
+  const { keyserverID, ...unencryptedPayload } = notification.data;
   const { resultPayload } = await encryptAndroidNotificationPayload(
     cookieID,
-    notification.data,
+    unencryptedPayload,
   );
   return {
-    data: resultPayload,
+    data: { keyserverID, ...resultPayload },
   };
 }
 
diff --git a/keyserver/src/push/rescind.js b/keyserver/src/push/rescind.js
--- a/keyserver/src/push/rescind.js
+++ b/keyserver/src/push/rescind.js
@@ -30,6 +30,7 @@
 import createIDs from '../creators/id-creator.js';
 import { dbQuery, SQL } from '../database/database.js';
 import type { SQLStatementType } from '../database/types.js';
+import { thisKeyserverID } from '../user/identity.js';
 import { validateOutput } from '../utils/validation-utils.js';
 
 type ParsedDelivery = {
@@ -61,7 +62,7 @@
   fetchQuery.append(SQL`
       ) AS unread_count
     FROM notifications n
-    LEFT JOIN memberships m ON m.user = n.user 
+    LEFT JOIN memberships m ON m.user = n.user
       AND m.last_message > m.last_read_message 
       AND m.role > 0 
       AND JSON_EXTRACT(subscription, ${notificationExtractString})
@@ -70,7 +71,10 @@
   `);
   fetchQuery.append(notifCondition);
   fetchQuery.append(SQL` GROUP BY n.id, m.user`);
-  const [fetchResult] = await dbQuery(fetchQuery);
+  const [[fetchResult], keyserverID] = await Promise.all([
+    dbQuery(fetchQuery),
+    thisKeyserverID(),
+  ]);
 
   const allDeviceTokens = new Set<string>();
   const parsedDeliveries: { [string]: $ReadOnlyArray<ParsedDelivery> } = {};
@@ -152,6 +156,7 @@
         }));
         const deliveryPromise = (async () => {
           const targetedNotifications = await prepareIOSNotification(
+            keyserverID,
             delivery.notificationID,
             row.unread_count,
             threadID,
@@ -174,6 +179,7 @@
         }));
         const deliveryPromise = (async () => {
           const targetedNotifications = await prepareAndroidNotification(
+            keyserverID,
             delivery.notificationID,
             row.unread_count,
             threadID,
@@ -303,6 +309,7 @@
 }
 
 async function prepareIOSNotification(
+  keyserverID: string,
   iosID: string,
   unreadCount: number,
   threadID: string,
@@ -334,6 +341,7 @@
           notificationId: iosID,
           setUnreadStatus: true,
           threadID,
+          keyserverID,
         }
       : {
           managedAps: {
@@ -350,6 +358,7 @@
 }
 
 async function prepareAndroidNotification(
+  keyserverID: string,
   notifID: string,
   unreadCount: number,
   threadID: string,
@@ -366,6 +375,7 @@
       rescindID: notifID,
       setUnreadStatus: 'true',
       threadID,
+      keyserverID,
     },
   };
   return await conditionallyEncryptNotification(
diff --git a/keyserver/src/push/send.js b/keyserver/src/push/send.js
--- a/keyserver/src/push/send.js
+++ b/keyserver/src/push/send.js
@@ -78,6 +78,7 @@
 import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
 import { fetchUserInfos } from '../fetchers/user-fetchers.js';
 import type { Viewer } from '../session/viewer.js';
+import { thisKeyserverID } from '../user/identity.js';
 import { getENSNames } from '../utils/ens-cache.js';
 import { validateOutput } from '../utils/validation-utils.js';
 
@@ -112,6 +113,8 @@
     return;
   }
 
+  const keyserverID = await thisKeyserverID();
+
   const [
     unreadCounts,
     { usersToCollapsableNotifInfo, serverThreadInfos, userInfos },
@@ -148,6 +151,7 @@
     for (const notifInfo of usersToCollapsableNotifInfo[userID]) {
       preparePromises.push(
         preparePushNotif({
+          keyserverID,
           notifInfo,
           userID,
           pushUserInfo: pushInfo[userID],
@@ -192,6 +196,7 @@
 };
 
 async function preparePushNotif(input: {
+  keyserverID: string,
   notifInfo: CollapsableNotifInfo,
   userID: string,
   pushUserInfo: PushUserInfo,
@@ -204,6 +209,7 @@
   rowsToSave: Map<string, NotificationRow>, // mutable
 }): Promise<?$ReadOnlyArray<PreparePushResult>> {
   const {
+    keyserverID,
     notifInfo,
     userID,
     pushUserInfo,
@@ -319,6 +325,7 @@
         (async () => {
           const targetedNotifications = await prepareAPNsNotification(
             {
+              keyserverID,
               notifTexts,
               newRawMessageInfos: shimmedNewRawMessageInfos,
               threadID: threadInfo.id,
@@ -359,6 +366,7 @@
         (async () => {
           const targetedNotifications = await prepareAndroidNotification(
             {
+              keyserverID,
               notifTexts,
               newRawMessageInfos: shimmedNewRawMessageInfos,
               threadID: threadInfo.id,
@@ -437,6 +445,7 @@
         (async () => {
           const targetedNotifications = await prepareAPNsNotification(
             {
+              keyserverID,
               notifTexts,
               newRawMessageInfos: shimmedNewRawMessageInfos,
               threadID: threadInfo.id,
@@ -886,6 +895,7 @@
 }
 
 type APNsNotifInputData = {
+  +keyserverID: string,
   +notifTexts: ResolvedNotifTexts,
   +newRawMessageInfos: RawMessageInfo[],
   +threadID: string,
@@ -895,6 +905,7 @@
   +platformDetails: PlatformDetails,
 };
 const apnsNotifInputDataValidator = tShape<APNsNotifInputData>({
+  keyserverID: t.String,
   notifTexts: resolvedNotifTextsValidator,
   newRawMessageInfos: t.list(rawMessageInfoValidator),
   threadID: tID,
@@ -913,6 +924,7 @@
     inputData,
   );
   const {
+    keyserverID,
     notifTexts,
     newRawMessageInfos,
     threadID,
@@ -960,10 +972,14 @@
     notification.body = merged;
     notification.sound = 'default';
   }
+
   notification.payload = {
     ...notification.payload,
     ...rest,
   };
+  if (platformDetails.platform !== 'macos') {
+    notification.payload.keyserverID = keyserverID;
+  }
 
   notification.badge = unreadCount;
   notification.threadId = threadID;
@@ -1093,6 +1109,7 @@
     inputData,
   );
   const {
+    keyserverID,
     notifTexts,
     newRawMessageInfos,
     threadID,
@@ -1118,6 +1135,7 @@
   const { merged, ...rest } = notifTexts;
   const notification = {
     data: {
+      keyserverID,
       badge: unreadCount.toString(),
       ...rest,
       threadID,
@@ -1628,11 +1646,13 @@
   if (viewer.data.cookieID) {
     deviceTokenQuery.append(SQL`AND id != ${viewer.cookieID} `);
   }
-  const [unreadCounts, [deviceTokenResult], [dbID]] = await Promise.all([
-    getUnreadCounts([userID]),
-    dbQuery(deviceTokenQuery),
-    createIDs('notifications', 1),
-  ]);
+  const [unreadCounts, [deviceTokenResult], [dbID], keyserverID] =
+    await Promise.all([
+      getUnreadCounts([userID]),
+      dbQuery(deviceTokenQuery),
+      createIDs('notifications', 1),
+      thisKeyserverID(),
+    ]);
   const unreadCount = unreadCounts[userID];
   const devices = deviceTokenResult.map(row => {
     const versions = JSON.parse(row.versions);
@@ -1660,6 +1680,7 @@
       });
       notification.badge = unreadCount;
       notification.pushType = 'alert';
+      notification.payload.keyserverID = keyserverID;
       const preparePromise: Promise<PreparePushResult[]> = (async () => {
         let targetedNotifications: $ReadOnlyArray<TargetedAPNsNotification>;
         if (codeVersion > 222) {
@@ -1706,7 +1727,9 @@
         codeVersion < 69
           ? { badge: unreadCount.toString() }
           : { badge: unreadCount.toString(), badgeOnly: '1' };
-      const notification = { data: notificationData };
+      const notification = {
+        data: { ...notificationData, keyserverID },
+      };
       const preparePromise: Promise<PreparePushResult[]> = (async () => {
         let targetedNotifications: $ReadOnlyArray<TargetedAndroidNotification>;
         if (codeVersion > 222) {
diff --git a/keyserver/src/push/types.js b/keyserver/src/push/types.js
--- a/keyserver/src/push/types.js
+++ b/keyserver/src/push/types.js
@@ -39,21 +39,25 @@
   +data: {
     +id?: string,
     +badgeOnly?: string,
+    +keyserverID: string,
     ...AndroidNotificationPayload | { +encryptedPayload: string },
   },
 };
 
 export type AndroidNotificationRescind = {
-  +data:
-    | {
-        +badge: string,
-        +rescind: 'true',
-        +rescindID: string,
-        +setUnreadStatus: 'true',
-        +threadID: string,
-        +encryptionFailed?: string,
-      }
-    | { +encryptedPayload: string },
+  +data: {
+    +keyserverID: string,
+    ...
+      | {
+          +badge: string,
+          +rescind: 'true',
+          +rescindID: string,
+          +setUnreadStatus: 'true',
+          +threadID: string,
+          +encryptionFailed?: string,
+        }
+      | { +encryptedPayload: string },
+  },
 };
 
 export type TargetedAndroidNotification = {