diff --git a/src/messaging/create.js b/src/messaging/create.js
index fe0fbb7de0..87ec24729f 100644
--- a/src/messaging/create.js
+++ b/src/messaging/create.js
@@ -44,6 +44,7 @@ module.exports = function (Messaging) {
 		const mid = await db.incrObjectField('global', 'nextMid');
 		const timestamp = data.timestamp || Date.now();
 		let message = {
+			mid: mid,
 			content: String(data.content),
 			timestamp: timestamp,
 			fromuid: uid,
@@ -65,6 +66,7 @@ module.exports = function (Messaging) {
 		const tasks = [
 			Messaging.addMessageToRoom(roomId, mid, timestamp),
 			Messaging.markRead(uid, roomId),
+			db.sortedSetAdd('messages:mid', timestamp, mid),
 		];
 		if (roomData.public) {
 			tasks.push(
diff --git a/src/messaging/data.js b/src/messaging/data.js
index 38c2e7761a..3542de799f 100644
--- a/src/messaging/data.js
+++ b/src/messaging/data.js
@@ -7,7 +7,7 @@ const user = require('../user');
 const utils = require('../utils');
 const plugins = require('../plugins');
 
-const intFields = ['timestamp', 'edited', 'fromuid', 'roomId', 'deleted', 'system'];
+const intFields = ['mid', 'timestamp', 'edited', 'fromuid', 'roomId', 'deleted', 'system'];
 
 module.exports = function (Messaging) {
 	Messaging.newMessageCutoff = 1000 * 60 * 3;
@@ -71,8 +71,6 @@ module.exports = function (Messaging) {
 
 			message.newSet = false;
 			message.roomId = String(message.roomId || roomId);
-			message.deleted = !!message.deleted;
-			message.system = !!message.system;
 		});
 
 		messages = await Promise.all(messages.map(async (message) => {
@@ -143,9 +141,6 @@ async function modifyMessage(message, fields, mid) {
 		if (message.hasOwnProperty('edited')) {
 			message.editedISO = utils.toISOString(message.edited);
 		}
-		if (!fields.length || fields.includes('mid')) {
-			message.mid = parseInt(mid, 10);
-		}
 	}
 
 	const payload = await plugins.hooks.fire('filter:messaging.getFields', {
diff --git a/src/messaging/delete.js b/src/messaging/delete.js
index aca7570c34..1c16ceddc1 100644
--- a/src/messaging/delete.js
+++ b/src/messaging/delete.js
@@ -9,20 +9,23 @@ module.exports = function (Messaging) {
 
 	async function doDeleteRestore(mid, state, uid) {
 		const field = state ? 'deleted' : 'restored';
-		const { content, deleted, roomId } = await Messaging.getMessageFields(mid, ['deleted', 'roomId', 'content']);
-		if (deleted === state) {
+		const msgData = await Messaging.getMessageFields(mid, [
+			'mid', 'fromuid', 'deleted', 'roomId', 'content', 'system',
+		]);
+		if (msgData.deleted === state) {
 			throw new Error(`[[error:chat-${field}-already]]`);
 		}
 
 		await Messaging.setMessageField(mid, 'deleted', state);
-		const ioRoom = sockets.in(`chat_room_${roomId}`);
+		msgData.deleted = state;
+		const ioRoom = sockets.in(`chat_room_${msgData.roomId}`);
 		if (state === 1 && ioRoom) {
 			ioRoom.emit('event:chats.delete', mid);
-			plugins.hooks.fire('action:messaging.delete', { message: { mid, content, deleted: 1, roomId } });
+			plugins.hooks.fire('action:messaging.delete', { message: msgData });
 		} else if (state === 0 && ioRoom) {
-			const messages = await Messaging.getMessagesData([mid], uid, roomId, true);
+			const messages = await Messaging.getMessagesData([mid], uid, msgData.roomId, true);
 			ioRoom.emit('event:chats.restore', messages[0]);
-			plugins.hooks.fire('action:messaging.restore', { message: { ...messages[0], content } });
+			plugins.hooks.fire('action:messaging.restore', { message: msgData });
 		}
 	}
 };
diff --git a/src/messaging/edit.js b/src/messaging/edit.js
index bd930f9ae9..438d43685a 100644
--- a/src/messaging/edit.js
+++ b/src/messaging/edit.js
@@ -31,7 +31,9 @@ module.exports = function (Messaging) {
 		sockets.in(`chat_room_${roomId}`).emit('event:chats.edit', {
 			messages: messages,
 		});
-		plugins.hooks.fire('action:messaging.edit', { message: messages[0] });
+		plugins.hooks.fire('action:messaging.edit', {
+			message: { ...messages[0], content: payload.content },
+		});
 	};
 
 	const canEditDelete = async (messageId, uid, type) => {
diff --git a/src/upgrades/3.3.0/chat_message_mids.js b/src/upgrades/3.3.0/chat_message_mids.js
new file mode 100644
index 0000000000..ebb79324fa
--- /dev/null
+++ b/src/upgrades/3.3.0/chat_message_mids.js
@@ -0,0 +1,45 @@
+'use strict';
+
+
+const db = require('../../database');
+const batch = require('../../batch');
+
+
+module.exports = {
+	name: 'Set mid on message objects and create messages:mid',
+	timestamp: Date.UTC(2023, 6, 27),
+	method: async function () {
+		const { progress } = this;
+
+		progress.total = await db.sortedSetCard(`chat:rooms`);
+		await batch.processSortedSet(`chat:rooms`, async (roomIds) => {
+			progress.incr(roomIds.length);
+			await Promise.all(roomIds.map(async (roomId) => {
+				await batch.processSortedSet(`chat:room:${roomId}:mids`, async (mids) => {
+					let messageData = await db.getObjects(mids.map(mid => `message:${mid}`));
+					messageData.forEach((m, idx) => {
+						if (m) {
+							m.mid = parseInt(mids[idx], 10);
+						}
+					});
+					messageData = messageData.filter(Boolean);
+
+					const bulkSet = messageData.map(
+						msg => [`message:${msg.mid}`, { mid: msg.mid }]
+					);
+
+					await db.setObjectBulk(bulkSet);
+					await db.sortedSetAdd(
+						'messages:mid',
+						messageData.map(msg => msg.timestamp),
+						messageData.map(msg => msg.mid)
+					);
+				}, {
+					batch: 500,
+				});
+			}));
+		}, {
+			batch: 500,
+		});
+	},
+};