From 855c47b2d5feada37fb08bd12c7207ed109e9bda Mon Sep 17 00:00:00 2001
From: Serban Iorga <serban@parity.io>
Date: Fri, 21 Mar 2025 14:02:12 +0200
Subject: [PATCH] Improve XCMP weight metering (#7963)

This PR Improves the weight metering for the `enqueue_xcmp_message()`
method, by accounting for cached reads/writes and for the size of the
enqueued messages

---------

Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---
 .../pallets/xcmp-queue/src/benchmarking.rs    |  47 +++-
 cumulus/pallets/xcmp-queue/src/lib.rs         |  41 ++-
 cumulus/pallets/xcmp-queue/src/mock.rs        |  14 +-
 cumulus/pallets/xcmp-queue/src/tests.rs       |  12 +-
 cumulus/pallets/xcmp-queue/src/weights.rs     | 248 +++++++++++-------
 cumulus/pallets/xcmp-queue/src/weights_ext.rs |  44 ++++
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 .../src/weights/cumulus_pallet_xcmp_queue.rs  |  57 ++--
 substrate/frame/message-queue/src/lib.rs      |  82 +++---
 16 files changed, 699 insertions(+), 302 deletions(-)
 create mode 100644 cumulus/pallets/xcmp-queue/src/weights_ext.rs

diff --git a/cumulus/pallets/xcmp-queue/src/benchmarking.rs b/cumulus/pallets/xcmp-queue/src/benchmarking.rs
index 73cd10607a1..47f60384f5e 100644
--- a/cumulus/pallets/xcmp-queue/src/benchmarking.rs
+++ b/cumulus/pallets/xcmp-queue/src/benchmarking.rs
@@ -20,7 +20,7 @@ use crate::*;
 use alloc::vec;
 use codec::DecodeAll;
 use frame_benchmarking::v2::*;
-use frame_support::traits::Hooks;
+use frame_support::{assert_ok, traits::Hooks};
 use frame_system::RawOrigin;
 use xcm::MAX_INSTRUCTIONS_TO_DECODE;
 
@@ -40,15 +40,48 @@ mod benchmarks {
 		Pallet::<T>::update_resume_threshold(RawOrigin::Root, 1);
 	}
 
+	/// Add a XCMP message of `n` bytes to the message queue.
+	///
+	/// The message will be added on a new page and also, the `BookState` will be added
+	/// to the ready ring.
 	#[benchmark]
-	fn enqueue_xcmp_message() {
-		assert!(QueueConfig::<T>::get().drop_threshold * MaxXcmpMessageLenOf::<T>::get() > 1000);
-		let msg = BoundedVec::<u8, MaxXcmpMessageLenOf<T>>::default();
+	fn enqueue_n_bytes_xcmp_message(n: Linear<1, { MaxXcmpMessageLenOf::<T>::get() }>) {
+		#[cfg(test)]
+		{
+			mock::EnqueuedMessages::set(vec![]);
+		}
+
+		let msg = BoundedVec::<u8, MaxXcmpMessageLenOf<T>>::try_from(vec![0; n as usize]).unwrap();
+		let fp_before = T::XcmpQueue::footprint(0.into());
+		#[block]
+		{
+			assert_ok!(Pallet::<T>::enqueue_xcmp_message(0.into(), msg));
+		}
+		let fp_after = T::XcmpQueue::footprint(0.into());
+		assert_eq!(fp_after.ready_pages, fp_before.ready_pages + 1);
+	}
+
+	/// Add 2 XCMP message of 0 bytes to the message queue.
+	///
+	/// Only for the first message a new page will be created and the `BookState` will be added
+	/// to the ready ring.
+	#[benchmark]
+	fn enqueue_2_empty_xcmp_messages() {
+		#[cfg(test)]
+		{
+			mock::EnqueuedMessages::set(vec![]);
+		}
 
+		let msg_1 = BoundedVec::<u8, MaxXcmpMessageLenOf<T>>::default();
+		let msg_2 = BoundedVec::<u8, MaxXcmpMessageLenOf<T>>::default();
+		let fp_before = T::XcmpQueue::footprint(0.into());
 		#[block]
 		{
-			Pallet::<T>::enqueue_xcmp_message(0.into(), msg, &mut WeightMeter::new()).unwrap();
+			assert_ok!(Pallet::<T>::enqueue_xcmp_message(0.into(), msg_1));
+			assert_ok!(Pallet::<T>::enqueue_xcmp_message(0.into(), msg_2));
 		}
+		let fp_after = T::XcmpQueue::footprint(0.into());
+		assert_eq!(fp_after.ready_pages, fp_before.ready_pages + 1);
 	}
 
 	#[benchmark]
@@ -94,7 +127,7 @@ mod benchmarks {
 	/// Split a singular XCM.
 	#[benchmark]
 	fn take_first_concatenated_xcm() {
-		let max_downward_message_size = MaxXcmpMessageLenOf::<T>::get() as usize;
+		let max_message_size = MaxXcmpMessageLenOf::<T>::get() as usize;
 
 		assert!(MAX_INSTRUCTIONS_TO_DECODE as u32 > MAX_XCM_DECODE_DEPTH, "Preconditon failed");
 		let max_instrs = MAX_INSTRUCTIONS_TO_DECODE as u32 - MAX_XCM_DECODE_DEPTH;
@@ -105,7 +138,7 @@ mod benchmarks {
 		}
 
 		let data = VersionedXcm::<T>::from(xcm).encode();
-		assert!(data.len() < max_downward_message_size, "Page size is too small");
+		assert!(data.len() < max_message_size, "Page size is too small");
 		// Verify that decoding works with the exact recursion limit:
 		VersionedXcm::<T::RuntimeCall>::decode_all_with_depth_limit(
 			MAX_XCM_DECODE_DEPTH,
diff --git a/cumulus/pallets/xcmp-queue/src/lib.rs b/cumulus/pallets/xcmp-queue/src/lib.rs
index 10a1a99577a..cc6216ef8ea 100644
--- a/cumulus/pallets/xcmp-queue/src/lib.rs
+++ b/cumulus/pallets/xcmp-queue/src/lib.rs
@@ -48,7 +48,10 @@ mod benchmarking;
 #[cfg(feature = "bridging")]
 pub mod bridging;
 pub mod weights;
+pub mod weights_ext;
+
 pub use weights::WeightInfo;
+pub use weights_ext::WeightInfoExt;
 
 extern crate alloc;
 
@@ -164,7 +167,7 @@ pub mod pallet {
 		type PriceForSiblingDelivery: PriceForMessageDelivery<Id = ParaId>;
 
 		/// The weight information of this pallet.
-		type WeightInfo: WeightInfo;
+		type WeightInfo: WeightInfoExt;
 	}
 
 	#[pallet::call]
@@ -637,13 +640,7 @@ impl<T: Config> Pallet<T> {
 	fn enqueue_xcmp_message(
 		sender: ParaId,
 		xcm: BoundedVec<u8, MaxXcmpMessageLenOf<T>>,
-		meter: &mut WeightMeter,
 	) -> Result<(), ()> {
-		if meter.try_consume(T::WeightInfo::enqueue_xcmp_message()).is_err() {
-			defensive!("Out of weight: cannot enqueue XCMP messages; dropping msg");
-			return Err(())
-		}
-
 		let QueueConfigData { drop_threshold, .. } = <QueueConfig<T>>::get();
 		let fp = T::XcmpQueue::footprint(sender);
 		// Assume that it will not fit into the current page:
@@ -791,7 +788,10 @@ impl<T: Config> XcmpMessageHandler for Pallet<T> {
 							},
 						}
 					},
-				XcmpMessageFormat::ConcatenatedVersionedXcm =>
+				XcmpMessageFormat::ConcatenatedVersionedXcm => {
+					// We need to know if the current message is the first on the current XCMP page
+					// for weight metering accuracy.
+					let mut is_first_xcm_on_page = true;
 					while !data.is_empty() {
 						let Ok(xcm) = Self::take_first_concatenated_xcm(&mut data, &mut meter)
 						else {
@@ -799,14 +799,35 @@ impl<T: Config> XcmpMessageHandler for Pallet<T> {
 							break
 						};
 
-						if let Err(()) = Self::enqueue_xcmp_message(sender, xcm, &mut meter) {
+						// For simplicity, we consider that each new XCMP page results in a new
+						// message queue page. This is not always true, but it's a good enough
+						// estimation.
+						if meter
+							.try_consume(T::WeightInfo::enqueue_xcmp_message(
+								xcm.len(),
+								is_first_xcm_on_page,
+							))
+							.is_err()
+						{
+							defensive!(
+								"Out of weight: cannot enqueue XCMP messages; dropping msg; \
+								Used weight: ",
+								meter.consumed_ratio()
+							);
+							break;
+						}
+
+						if let Err(()) = Self::enqueue_xcmp_message(sender, xcm) {
 							defensive!(
 								"Could not enqueue XCMP messages. Used weight: ",
 								meter.consumed_ratio()
 							);
 							break
 						}
-					},
+
+						is_first_xcm_on_page = false;
+					}
+				},
 				XcmpMessageFormat::ConcatenatedEncodedBlob => {
 					defensive!("Blob messages are unhandled - dropping");
 					continue
diff --git a/cumulus/pallets/xcmp-queue/src/mock.rs b/cumulus/pallets/xcmp-queue/src/mock.rs
index 3964ecf28ca..bea1c6da278 100644
--- a/cumulus/pallets/xcmp-queue/src/mock.rs
+++ b/cumulus/pallets/xcmp-queue/src/mock.rs
@@ -15,7 +15,7 @@
 
 use super::*;
 use crate as xcmp_queue;
-use core::marker::PhantomData;
+use core::{cmp::max, marker::PhantomData};
 use cumulus_pallet_parachain_system::AnyRelayNumber;
 use cumulus_primitives_core::{ChannelInfo, IsSystem, ParaId};
 use frame_support::{
@@ -144,7 +144,7 @@ parameter_types! {
 pub struct EnqueueToLocalStorage<T>(PhantomData<T>);
 
 impl<T: OnQueueChanged<ParaId>> EnqueueMessage<ParaId> for EnqueueToLocalStorage<T> {
-	type MaxMessageLen = sp_core::ConstU32<65_536>;
+	type MaxMessageLen = sp_core::ConstU32<256>;
 
 	fn enqueue_message(message: BoundedSlice<u8, Self::MaxMessageLen>, origin: ParaId) {
 		let mut msgs = EnqueuedMessages::get();
@@ -179,7 +179,11 @@ impl<T: OnQueueChanged<ParaId>> EnqueueMessage<ParaId> for EnqueueToLocalStorage
 				footprint.storage.size += m.len() as u64;
 			}
 		}
-		footprint.pages = footprint.storage.size as u32 / 16; // Number does not matter
+		footprint.pages =
+			(footprint.storage.size as u32).div_ceil(<Self::MaxMessageLen as Get<u32>>::get());
+		if footprint.storage.count > 0 {
+			footprint.pages = max(footprint.pages, 1);
+		}
 		footprint.ready_pages = footprint.pages;
 		footprint
 	}
@@ -228,7 +232,7 @@ pub struct MockedChannelInfo;
 impl GetChannelInfo for MockedChannelInfo {
 	fn get_channel_status(id: ParaId) -> ChannelStatus {
 		if id == HRMP_PARA_ID.into() {
-			return ChannelStatus::Ready(usize::MAX, usize::MAX)
+			return ChannelStatus::Ready(usize::MAX, usize::MAX);
 		}
 
 		ParachainSystem::get_channel_status(id)
@@ -242,7 +246,7 @@ impl GetChannelInfo for MockedChannelInfo {
 				max_message_size: u32::MAX,
 				msg_count: 0,
 				total_size: 0,
-			})
+			});
 		}
 
 		ParachainSystem::get_channel_info(id)
diff --git a/cumulus/pallets/xcmp-queue/src/tests.rs b/cumulus/pallets/xcmp-queue/src/tests.rs
index 308772d3ce5..d783befab67 100644
--- a/cumulus/pallets/xcmp-queue/src/tests.rs
+++ b/cumulus/pallets/xcmp-queue/src/tests.rs
@@ -104,10 +104,16 @@ fn xcm_enqueueing_multiple_times_works() {
 #[cfg_attr(debug_assertions, should_panic = "Could not enqueue XCMP messages.")]
 fn xcm_enqueueing_starts_dropping_on_overflow() {
 	new_test_ext().execute_with(|| {
-		let xcm = VersionedXcm::<Test>::from(Xcm::<Test>(vec![ClearOrigin]));
+		let xcm = VersionedXcm::<Test>::from(Xcm::<Test>(vec![
+			ClearOrigin;
+			MAX_INSTRUCTIONS_TO_DECODE as usize
+		]));
 		let data = (ConcatenatedVersionedXcm, xcm).encode();
-		// Its possible to enqueue 256 messages at most:
-		let limit = 256;
+		// It's possible to enqueue at most `limit` messages:
+		let max_message_len: u32 =
+			<<Test as Config>::XcmpQueue as EnqueueMessage<ParaId>>::MaxMessageLen::get();
+		let drop_threshold = <QueueConfig<Test>>::get().drop_threshold;
+		let limit = max_message_len as usize / data.len() * drop_threshold as usize;
 
 		XcmpQueue::handle_xcmp_messages(
 			repeat((1000.into(), 1, data.as_slice())).take(limit * 2),
diff --git a/cumulus/pallets/xcmp-queue/src/weights.rs b/cumulus/pallets/xcmp-queue/src/weights.rs
index 27daa791e19..78e76dfa278 100644
--- a/cumulus/pallets/xcmp-queue/src/weights.rs
+++ b/cumulus/pallets/xcmp-queue/src/weights.rs
@@ -15,11 +15,11 @@
 
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-09-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2025-03-18, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `Olivers-MacBook-Pro.local`, CPU: `<UNKNOWN>`
-//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-kusama-dev")`, DB CACHE: `1024`
+//! HOSTNAME: `serban-ROG-Zephyrus`, CPU: `AMD Ryzen 9 7945HX with Radeon Graphics`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: `1024`
 
 // Executed Command:
 // ./target/release/polkadot-parachain
@@ -28,7 +28,7 @@
 // --pallet
 // cumulus-pallet-xcmp-queue
 // --chain
-// asset-hub-kusama-dev
+// asset-hub-westend-dev
 // --output
 // cumulus/pallets/xcmp-queue/src/weights.rs
 // --template
@@ -40,6 +40,7 @@
 #![allow(unused_parens)]
 #![allow(unused_imports)]
 #![allow(missing_docs)]
+#![allow(dead_code)]
 
 use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
 use core::marker::PhantomData;
@@ -47,7 +48,8 @@ use core::marker::PhantomData;
 /// Weight functions needed for `cumulus_pallet_xcmp_queue`.
 pub trait WeightInfo {
 	fn set_config_with_u32() -> Weight;
-	fn enqueue_xcmp_message() -> Weight;
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight;
+	fn enqueue_2_empty_xcmp_messages() -> Weight;
 	fn suspend_channel() -> Weight;
 	fn resume_channel() -> Weight;
 	fn take_first_concatenated_xcm() -> Weight;
@@ -59,54 +61,76 @@ pub trait WeightInfo {
 pub struct SubstrateWeight<T>(PhantomData<T>);
 impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:1)
-	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
 	fn set_config_with_u32() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `76`
-		//  Estimated: `1561`
-		// Minimum execution time: 5_000_000 picoseconds.
-		Weight::from_parts(6_000_000, 1561)
+		//  Measured:  `109`
+		//  Estimated: `1497`
+		// Minimum execution time: 3_562_000 picoseconds.
+		Weight::from_parts(4_749_000, 1497)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
-	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
 	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
 	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
 	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
-	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
-	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[0, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `118`
-		//  Estimated: `3517`
-		// Minimum execution time: 15_000_000 picoseconds.
-		Weight::from_parts(16_000_000, 3517)
+		//  Measured:  `151`
+		//  Estimated: `5487`
+		// Minimum execution time: 11_873_000 picoseconds.
+		Weight::from_parts(9_562_967, 5487)
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(700, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4_u64))
+			.saturating_add(T::DbWeight::get().writes(3_u64))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `151`
+		//  Estimated: `5487`
+		// Minimum execution time: 18_997_000 picoseconds.
+		Weight::from_parts(18_997_000, 5487)
 			.saturating_add(T::DbWeight::get().reads(4_u64))
 			.saturating_add(T::DbWeight::get().writes(3_u64))
 	}
 	/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1)
-	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`)
 	fn suspend_channel() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `76`
-		//  Estimated: `1561`
-		// Minimum execution time: 3_000_000 picoseconds.
-		Weight::from_parts(4_000_000, 1561)
+		//  Measured:  `109`
+		//  Estimated: `2767`
+		// Minimum execution time: 2_374_000 picoseconds.
+		Weight::from_parts(3_562_000, 2767)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1)
-	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`)
 	fn resume_channel() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `111`
-		//  Estimated: `1596`
-		// Minimum execution time: 4_000_000 picoseconds.
-		Weight::from_parts(4_000_000, 1596)
+		//  Measured:  `144`
+		//  Estimated: `2767`
+		// Minimum execution time: 3_562_000 picoseconds.
+		Weight::from_parts(4_749_000, 2767)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -114,96 +138,130 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 44_000_000 picoseconds.
-		Weight::from_parts(45_000_000, 0)
+		// Minimum execution time: 5_936_000 picoseconds.
+		Weight::from_parts(5_937_000, 0)
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
 	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
-	/// Storage: `XcmpQueue::InboundXcmpMessages` (r:1 w:1)
-	/// Proof: `XcmpQueue::InboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
+	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
 	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
 	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
 	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
 	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
-	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
 	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
-	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
-	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
 	fn on_idle_good_msg() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `65747`
-		//  Estimated: `69212`
-		// Minimum execution time: 63_000_000 picoseconds.
-		Weight::from_parts(66_000_000, 69212)
+		//  Measured:  `105716`
+		//  Estimated: `109181`
+		// Minimum execution time: 132_977_000 picoseconds.
+		Weight::from_parts(137_727_000, 109181)
 			.saturating_add(T::DbWeight::get().reads(6_u64))
 			.saturating_add(T::DbWeight::get().writes(5_u64))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
 	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
-		fn on_idle_large_msg() -> Weight {
+	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
+	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn on_idle_large_msg() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `65710`
-		//  Estimated: `69175`
-		// Minimum execution time: 42_000_000 picoseconds.
-		Weight::from_parts(52_000_000, 69175)
-			.saturating_add(T::DbWeight::get().reads(2_u64))
-			.saturating_add(T::DbWeight::get().writes(2_u64))
+		//  Measured:  `65785`
+		//  Estimated: `69250`
+		// Minimum execution time: 81_924_000 picoseconds.
+		Weight::from_parts(87_860_000, 69250)
+			.saturating_add(T::DbWeight::get().reads(6_u64))
+			.saturating_add(T::DbWeight::get().writes(5_u64))
 	}
 }
 
 // For backwards compatibility and tests.
 impl WeightInfo for () {
 	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:1)
-	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
 	fn set_config_with_u32() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `76`
-		//  Estimated: `1561`
-		// Minimum execution time: 5_000_000 picoseconds.
-		Weight::from_parts(6_000_000, 1561)
+		//  Measured:  `109`
+		//  Estimated: `1497`
+		// Minimum execution time: 3_562_000 picoseconds.
+		Weight::from_parts(4_749_000, 1497)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
-	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
 	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
 	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
 	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
-	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
-	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[0, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `118`
-		//  Estimated: `3517`
-		// Minimum execution time: 15_000_000 picoseconds.
-		Weight::from_parts(16_000_000, 3517)
+		//  Measured:  `151`
+		//  Estimated: `5487`
+		// Minimum execution time: 11_873_000 picoseconds.
+		Weight::from_parts(9_562_967, 5487)
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(700, 0).saturating_mul(n.into()))
+			.saturating_add(RocksDbWeight::get().reads(4_u64))
+			.saturating_add(RocksDbWeight::get().writes(3_u64))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `151`
+		//  Estimated: `5487`
+		// Minimum execution time: 20_184_000 picoseconds.
+		Weight::from_parts(20_184_000, 5487)
 			.saturating_add(RocksDbWeight::get().reads(4_u64))
 			.saturating_add(RocksDbWeight::get().writes(3_u64))
 	}
 	/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1)
-	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`)
 	fn suspend_channel() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `76`
-		//  Estimated: `1561`
-		// Minimum execution time: 3_000_000 picoseconds.
-		Weight::from_parts(4_000_000, 1561)
+		//  Measured:  `109`
+		//  Estimated: `2767`
+		// Minimum execution time: 2_374_000 picoseconds.
+		Weight::from_parts(3_562_000, 2767)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1)
-	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`)
 	fn resume_channel() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `111`
-		//  Estimated: `1596`
-		// Minimum execution time: 4_000_000 picoseconds.
-		Weight::from_parts(4_000_000, 1596)
+		//  Measured:  `144`
+		//  Estimated: `2767`
+		// Minimum execution time: 3_562_000 picoseconds.
+		Weight::from_parts(4_749_000, 2767)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -211,41 +269,53 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 44_000_000 picoseconds.
-		Weight::from_parts(45_000_000, 0)
+		// Minimum execution time: 5_936_000 picoseconds.
+		Weight::from_parts(5_937_000, 0)
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
 	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
-	/// Storage: `XcmpQueue::InboundXcmpMessages` (r:1 w:1)
-	/// Proof: `XcmpQueue::InboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
+	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
 	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
 	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
 	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
 	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
-	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
 	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
-	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
-	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
 	fn on_idle_good_msg() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `65747`
-		//  Estimated: `69212`
-		// Minimum execution time: 63_000_000 picoseconds.
-		Weight::from_parts(66_000_000, 69212)
+		//  Measured:  `105716`
+		//  Estimated: `109181`
+		// Minimum execution time: 132_977_000 picoseconds.
+		Weight::from_parts(137_727_000, 109181)
 			.saturating_add(RocksDbWeight::get().reads(6_u64))
 			.saturating_add(RocksDbWeight::get().writes(5_u64))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
 	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
-		fn on_idle_large_msg() -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `65710`
-		//  Estimated: `69175`
-		// Minimum execution time: 42_000_000 picoseconds.
-		Weight::from_parts(52_000_000, 69175)
-			.saturating_add(RocksDbWeight::get().reads(2_u64))
-			.saturating_add(RocksDbWeight::get().writes(2_u64))
+	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
+	/// Proof: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6bedc49980ba3aa32b0a189290fd036649` (r:1 w:1)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn on_idle_large_msg() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `65785`
+		//  Estimated: `69250`
+		// Minimum execution time: 81_924_000 picoseconds.
+		Weight::from_parts(87_860_000, 69250)
+			.saturating_add(RocksDbWeight::get().reads(6_u64))
+			.saturating_add(RocksDbWeight::get().writes(5_u64))
 	}
 }
diff --git a/cumulus/pallets/xcmp-queue/src/weights_ext.rs b/cumulus/pallets/xcmp-queue/src/weights_ext.rs
new file mode 100644
index 00000000000..ac526da7ef9
--- /dev/null
+++ b/cumulus/pallets/xcmp-queue/src/weights_ext.rs
@@ -0,0 +1,44 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Weight-related utilities.
+
+use crate::weights::WeightInfo;
+
+use frame_support::weights::Weight;
+use sp_runtime::SaturatedConversion;
+
+/// Extended weight info.
+pub trait WeightInfoExt: WeightInfo {
+	fn enqueue_xcmp_message(size_in_bytes: usize, new_page: bool) -> Weight {
+		let size_in_bytes = size_in_bytes.saturated_into();
+		// The first message for a certain origin consumes some extra reads and writes.
+		// Also, the first message on a page consumes 1 extra write.
+		// For simplicity let's just consider that the first message on a page is also
+		// the first message for that origin.
+		match new_page {
+			true => Self::enqueue_n_bytes_xcmp_message(size_in_bytes),
+			false => {
+				let size_overhead = Self::enqueue_n_bytes_xcmp_message(size_in_bytes) -
+					Self::enqueue_n_bytes_xcmp_message(0);
+				Self::enqueue_2_empty_xcmp_messages()
+					.saturating_sub(Self::enqueue_n_bytes_xcmp_message(0))
+					.saturating_add(size_overhead)
+			},
+		}
+	}
+}
+
+impl<T: WeightInfo> WeightInfoExt for T {}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
index 99b638e7365..fca7263a227 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `ef4134d66388`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `1497`
-		// Minimum execution time: 5_301_000 picoseconds.
-		Weight::from_parts(5_510_000, 0)
+		// Minimum execution time: 5_172_000 picoseconds.
+		Weight::from_parts(5_380_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_953_000 picoseconds.
-		Weight::from_parts(14_482_000, 0)
+		// Minimum execution time: 13_963_000 picoseconds.
+		Weight::from_parts(9_886_718, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(964, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `151`
+		//  Estimated: `5487`
+		// Minimum execution time: 22_410_000 picoseconds.
+		Weight::from_parts(23_319_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_322_000 picoseconds.
-		Weight::from_parts(3_530_000, 0)
+		// Minimum execution time: 3_188_000 picoseconds.
+		Weight::from_parts(3_413_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `144`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_606_000 picoseconds.
-		Weight::from_parts(4_777_000, 0)
+		// Minimum execution time: 4_496_000 picoseconds.
+		Weight::from_parts(4_646_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_359_000 picoseconds.
-		Weight::from_parts(5_584_000, 0)
+		// Minimum execution time: 5_111_000 picoseconds.
+		Weight::from_parts(5_316_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105716`
 		//  Estimated: `109181`
-		// Minimum execution time: 224_046_000 picoseconds.
-		Weight::from_parts(233_413_000, 0)
+		// Minimum execution time: 208_684_000 picoseconds.
+		Weight::from_parts(216_633_000, 0)
 			.saturating_add(Weight::from_parts(0, 109181))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65785`
 		//  Estimated: `69250`
-		// Minimum execution time: 131_648_000 picoseconds.
-		Weight::from_parts(134_036_000, 0)
+		// Minimum execution time: 124_803_000 picoseconds.
+		Weight::from_parts(128_914_000, 0)
 			.saturating_add(Weight::from_parts(0, 69250))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs
index 8cb6872b1fc..3eb4e1682e0 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `73b9817d6032`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `1497`
-		// Minimum execution time: 5_180_000 picoseconds.
-		Weight::from_parts(5_501_000, 0)
+		// Minimum execution time: 5_067_000 picoseconds.
+		Weight::from_parts(5_439_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_794_000 picoseconds.
-		Weight::from_parts(14_562_000, 0)
+		// Minimum execution time: 13_290_000 picoseconds.
+		Weight::from_parts(9_464_819, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 5
+			.saturating_add(Weight::from_parts(952, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `151`
+		//  Estimated: `5487`
+		// Minimum execution time: 22_251_000 picoseconds.
+		Weight::from_parts(22_846_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_332_000 picoseconds.
-		Weight::from_parts(3_556_000, 0)
+		// Minimum execution time: 3_267_000 picoseconds.
+		Weight::from_parts(3_454_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `144`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_640_000 picoseconds.
-		Weight::from_parts(4_889_000, 0)
+		// Minimum execution time: 4_470_000 picoseconds.
+		Weight::from_parts(4_685_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_323_000 picoseconds.
-		Weight::from_parts(5_609_000, 0)
+		// Minimum execution time: 5_295_000 picoseconds.
+		Weight::from_parts(5_543_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105716`
 		//  Estimated: `109181`
-		// Minimum execution time: 211_589_000 picoseconds.
-		Weight::from_parts(214_622_000, 0)
+		// Minimum execution time: 206_483_000 picoseconds.
+		Weight::from_parts(214_203_000, 0)
 			.saturating_add(Weight::from_parts(0, 109181))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65785`
 		//  Estimated: `69250`
-		// Minimum execution time: 129_311_000 picoseconds.
-		Weight::from_parts(130_885_000, 0)
+		// Minimum execution time: 124_337_000 picoseconds.
+		Weight::from_parts(128_576_000, 0)
 			.saturating_add(Weight::from_parts(0, 69250))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
index cbe7fcf1e7b..0e646a4549d 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `814af52b0d43`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `4`
 		//  Estimated: `1497`
-		// Minimum execution time: 4_399_000 picoseconds.
-		Weight::from_parts(4_639_000, 0)
+		// Minimum execution time: 4_194_000 picoseconds.
+		Weight::from_parts(4_680_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105549), added: 108024, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `80`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_375_000 picoseconds.
-		Weight::from_parts(13_735_000, 0)
+		// Minimum execution time: 12_927_000 picoseconds.
+		Weight::from_parts(9_172_345, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(961, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(136), added: 2611, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105549), added: 108024, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `80`
+		//  Estimated: `5487`
+		// Minimum execution time: 21_412_000 picoseconds.
+		Weight::from_parts(21_809_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `4`
 		//  Estimated: `2767`
-		// Minimum execution time: 2_556_000 picoseconds.
-		Weight::from_parts(2_710_000, 0)
+		// Minimum execution time: 2_408_000 picoseconds.
+		Weight::from_parts(2_633_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `39`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_836_000 picoseconds.
-		Weight::from_parts(4_034_000, 0)
+		// Minimum execution time: 3_803_000 picoseconds.
+		Weight::from_parts(3_934_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_248_000 picoseconds.
-		Weight::from_parts(5_439_000, 0)
+		// Minimum execution time: 5_057_000 picoseconds.
+		Weight::from_parts(5_302_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105645`
 		//  Estimated: `109110`
-		// Minimum execution time: 203_421_000 picoseconds.
-		Weight::from_parts(215_043_000, 0)
+		// Minimum execution time: 206_959_000 picoseconds.
+		Weight::from_parts(214_700_000, 0)
 			.saturating_add(Weight::from_parts(0, 109110))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65714`
 		//  Estimated: `69179`
-		// Minimum execution time: 124_024_000 picoseconds.
-		Weight::from_parts(125_716_000, 0)
+		// Minimum execution time: 123_991_000 picoseconds.
+		Weight::from_parts(126_653_000, 0)
 			.saturating_add(Weight::from_parts(0, 69179))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs
index ddee62057fc..3c1b77c3c2d 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `d3b41be4aae8`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `1497`
-		// Minimum execution time: 5_476_000 picoseconds.
-		Weight::from_parts(5_902_000, 0)
+		// Minimum execution time: 5_170_000 picoseconds.
+		Weight::from_parts(5_450_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105549), added: 108024, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `115`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_469_000 picoseconds.
-		Weight::from_parts(13_846_000, 0)
+		// Minimum execution time: 13_128_000 picoseconds.
+		Weight::from_parts(9_482_283, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(950, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(136), added: 2611, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105549), added: 108024, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `115`
+		//  Estimated: `5487`
+		// Minimum execution time: 21_482_000 picoseconds.
+		Weight::from_parts(21_978_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_234_000 picoseconds.
-		Weight::from_parts(3_493_000, 0)
+		// Minimum execution time: 3_350_000 picoseconds.
+		Weight::from_parts(3_448_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `144`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_568_000 picoseconds.
-		Weight::from_parts(4_969_000, 0)
+		// Minimum execution time: 4_540_000 picoseconds.
+		Weight::from_parts(4_770_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_722_000 picoseconds.
-		Weight::from_parts(5_844_000, 0)
+		// Minimum execution time: 5_058_000 picoseconds.
+		Weight::from_parts(5_359_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105680`
 		//  Estimated: `109145`
-		// Minimum execution time: 223_451_000 picoseconds.
-		Weight::from_parts(233_157_000, 0)
+		// Minimum execution time: 205_680_000 picoseconds.
+		Weight::from_parts(212_942_000, 0)
 			.saturating_add(Weight::from_parts(0, 109145))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65749`
 		//  Estimated: `69214`
-		// Minimum execution time: 132_250_000 picoseconds.
-		Weight::from_parts(135_401_000, 0)
+		// Minimum execution time: 123_699_000 picoseconds.
+		Weight::from_parts(125_875_000, 0)
 			.saturating_add(Weight::from_parts(0, 69214))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/cumulus_pallet_xcmp_queue.rs
index fbfd43181fb..a18af411a02 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `e0f303704c84`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `142`
 		//  Estimated: `1497`
-		// Minimum execution time: 5_254_000 picoseconds.
-		Weight::from_parts(5_564_000, 0)
+		// Minimum execution time: 5_270_000 picoseconds.
+		Weight::from_parts(5_618_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `148`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_241_000 picoseconds.
-		Weight::from_parts(13_586_000, 0)
+		// Minimum execution time: 13_108_000 picoseconds.
+		Weight::from_parts(8_994_190, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(1_004, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `148`
+		//  Estimated: `5487`
+		// Minimum execution time: 21_290_000 picoseconds.
+		Weight::from_parts(21_828_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `142`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_388_000 picoseconds.
-		Weight::from_parts(3_609_000, 0)
+		// Minimum execution time: 3_367_000 picoseconds.
+		Weight::from_parts(3_527_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `177`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_830_000 picoseconds.
-		Weight::from_parts(4_999_000, 0)
+		// Minimum execution time: 4_540_000 picoseconds.
+		Weight::from_parts(4_853_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_366_000 picoseconds.
-		Weight::from_parts(5_537_000, 0)
+		// Minimum execution time: 5_213_000 picoseconds.
+		Weight::from_parts(5_423_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105713`
 		//  Estimated: `109178`
-		// Minimum execution time: 222_810_000 picoseconds.
-		Weight::from_parts(225_413_000, 0)
+		// Minimum execution time: 223_334_000 picoseconds.
+		Weight::from_parts(231_201_000, 0)
 			.saturating_add(Weight::from_parts(0, 109178))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65782`
 		//  Estimated: `69247`
-		// Minimum execution time: 131_105_000 picoseconds.
-		Weight::from_parts(133_000_000, 0)
+		// Minimum execution time: 131_267_000 picoseconds.
+		Weight::from_parts(133_054_000, 0)
 			.saturating_add(Weight::from_parts(0, 69247))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
index 43b872de075..67f3c73ca77 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `731f893ee36e`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `1497`
-		// Minimum execution time: 4_922_000 picoseconds.
-		Weight::from_parts(5_485_000, 0)
+		// Minimum execution time: 4_937_000 picoseconds.
+		Weight::from_parts(5_212_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `82`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_346_000 picoseconds.
-		Weight::from_parts(14_155_000, 0)
+		// Minimum execution time: 12_825_000 picoseconds.
+		Weight::from_parts(8_895_081, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(1_000, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `82`
+		//  Estimated: `5487`
+		// Minimum execution time: 20_817_000 picoseconds.
+		Weight::from_parts(21_346_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_176_000 picoseconds.
-		Weight::from_parts(3_643_000, 0)
+		// Minimum execution time: 3_155_000 picoseconds.
+		Weight::from_parts(3_396_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `111`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_570_000 picoseconds.
-		Weight::from_parts(4_756_000, 0)
+		// Minimum execution time: 4_421_000 picoseconds.
+		Weight::from_parts(4_583_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_267_000 picoseconds.
-		Weight::from_parts(5_374_000, 0)
+		// Minimum execution time: 5_488_000 picoseconds.
+		Weight::from_parts(5_668_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105647`
 		//  Estimated: `109112`
-		// Minimum execution time: 224_395_000 picoseconds.
-		Weight::from_parts(247_578_000, 0)
+		// Minimum execution time: 224_744_000 picoseconds.
+		Weight::from_parts(232_481_000, 0)
 			.saturating_add(Weight::from_parts(0, 109112))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65716`
 		//  Estimated: `69181`
-		// Minimum execution time: 133_644_000 picoseconds.
-		Weight::from_parts(139_467_000, 0)
+		// Minimum execution time: 131_622_000 picoseconds.
+		Weight::from_parts(133_617_000, 0)
 			.saturating_add(Weight::from_parts(0, 69181))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/cumulus_pallet_xcmp_queue.rs
index 8466ec01693..fe0ecc6d686 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `050e4dc4313a`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `1497`
-		// Minimum execution time: 5_113_000 picoseconds.
-		Weight::from_parts(5_279_000, 0)
+		// Minimum execution time: 5_064_000 picoseconds.
+		Weight::from_parts(5_258_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `82`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_082_000 picoseconds.
-		Weight::from_parts(13_476_000, 0)
+		// Minimum execution time: 12_809_000 picoseconds.
+		Weight::from_parts(8_700_568, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(1_009, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `82`
+		//  Estimated: `5487`
+		// Minimum execution time: 21_303_000 picoseconds.
+		Weight::from_parts(21_691_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_232_000 picoseconds.
-		Weight::from_parts(3_424_000, 0)
+		// Minimum execution time: 3_089_000 picoseconds.
+		Weight::from_parts(3_279_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `111`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_434_000 picoseconds.
-		Weight::from_parts(4_656_000, 0)
+		// Minimum execution time: 4_401_000 picoseconds.
+		Weight::from_parts(4_603_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_126_000 picoseconds.
-		Weight::from_parts(5_320_000, 0)
+		// Minimum execution time: 5_394_000 picoseconds.
+		Weight::from_parts(5_624_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105647`
 		//  Estimated: `109112`
-		// Minimum execution time: 221_568_000 picoseconds.
-		Weight::from_parts(227_309_000, 0)
+		// Minimum execution time: 224_608_000 picoseconds.
+		Weight::from_parts(231_977_000, 0)
 			.saturating_add(Weight::from_parts(0, 109112))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65716`
 		//  Estimated: `69181`
-		// Minimum execution time: 129_160_000 picoseconds.
-		Weight::from_parts(132_491_000, 0)
+		// Minimum execution time: 131_497_000 picoseconds.
+		Weight::from_parts(132_938_000, 0)
 			.saturating_add(Weight::from_parts(0, 69181))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
index de6ff8c5890..554d7e89aa1 100644
--- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `afc679a858d4`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `1497`
-		// Minimum execution time: 5_078_000 picoseconds.
-		Weight::from_parts(5_438_000, 0)
+		// Minimum execution time: 5_111_000 picoseconds.
+		Weight::from_parts(5_638_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `82`
 		//  Estimated: `5487`
-		// Minimum execution time: 12_914_000 picoseconds.
-		Weight::from_parts(13_444_000, 0)
+		// Minimum execution time: 12_977_000 picoseconds.
+		Weight::from_parts(9_165_318, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(943, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `82`
+		//  Estimated: `5487`
+		// Minimum execution time: 21_041_000 picoseconds.
+		Weight::from_parts(21_560_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_191_000 picoseconds.
-		Weight::from_parts(3_401_000, 0)
+		// Minimum execution time: 3_097_000 picoseconds.
+		Weight::from_parts(3_280_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `111`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_580_000 picoseconds.
-		Weight::from_parts(4_722_000, 0)
+		// Minimum execution time: 4_460_000 picoseconds.
+		Weight::from_parts(4_666_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_076_000 picoseconds.
-		Weight::from_parts(5_406_000, 0)
+		// Minimum execution time: 5_097_000 picoseconds.
+		Weight::from_parts(5_495_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105647`
 		//  Estimated: `109112`
-		// Minimum execution time: 204_129_000 picoseconds.
-		Weight::from_parts(208_166_000, 0)
+		// Minimum execution time: 204_640_000 picoseconds.
+		Weight::from_parts(212_439_000, 0)
 			.saturating_add(Weight::from_parts(0, 109112))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65716`
 		//  Estimated: `69181`
-		// Minimum execution time: 123_913_000 picoseconds.
-		Weight::from_parts(125_285_000, 0)
+		// Minimum execution time: 124_818_000 picoseconds.
+		Weight::from_parts(126_464_000, 0)
 			.saturating_add(Weight::from_parts(0, 69181))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/cumulus_pallet_xcmp_queue.rs
index 9db3b3216b4..75c943eee46 100644
--- a/cumulus/parachains/runtimes/people/people-westend/src/weights/cumulus_pallet_xcmp_queue.rs
+++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/cumulus_pallet_xcmp_queue.rs
@@ -16,9 +16,9 @@
 //! Autogenerated weights for `cumulus_pallet_xcmp_queue`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-03-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `b9a9df1fcddf`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `b81a49f17bac`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
 
 // Executed Command:
@@ -56,8 +56,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `1497`
-		// Minimum execution time: 4_977_000 picoseconds.
-		Weight::from_parts(5_285_000, 0)
+		// Minimum execution time: 5_201_000 picoseconds.
+		Weight::from_parts(5_452_000, 0)
 			.saturating_add(Weight::from_parts(0, 1497))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -72,12 +72,35 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
 	/// Storage: `MessageQueue::Pages` (r:0 w:1)
 	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
-	fn enqueue_xcmp_message() -> Weight {
+	/// The range of component `n` is `[1, 105467]`.
+	fn enqueue_n_bytes_xcmp_message(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `82`
 		//  Estimated: `5487`
-		// Minimum execution time: 13_367_000 picoseconds.
-		Weight::from_parts(13_613_000, 0)
+		// Minimum execution time: 13_044_000 picoseconds.
+		Weight::from_parts(8_877_877, 0)
+			.saturating_add(Weight::from_parts(0, 5487))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(977, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmpQueue::QueueConfig` (r:1 w:0)
+	/// Proof: `XcmpQueue::QueueConfig` (`max_values`: Some(1), `max_size`: Some(12), added: 507, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
+	/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
+	/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(105521), added: 107996, mode: `MaxEncodedLen`)
+	fn enqueue_2_empty_xcmp_messages() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `82`
+		//  Estimated: `5487`
+		// Minimum execution time: 21_762_000 picoseconds.
+		Weight::from_parts(22_352_000, 0)
 			.saturating_add(Weight::from_parts(0, 5487))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -88,8 +111,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `2767`
-		// Minimum execution time: 3_247_000 picoseconds.
-		Weight::from_parts(3_438_000, 0)
+		// Minimum execution time: 3_291_000 picoseconds.
+		Weight::from_parts(3_443_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -100,8 +123,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `111`
 		//  Estimated: `2767`
-		// Minimum execution time: 4_597_000 picoseconds.
-		Weight::from_parts(4_822_000, 0)
+		// Minimum execution time: 4_364_000 picoseconds.
+		Weight::from_parts(4_602_000, 0)
 			.saturating_add(Weight::from_parts(0, 2767))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -110,8 +133,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_124_000 picoseconds.
-		Weight::from_parts(5_305_000, 0)
+		// Minimum execution time: 5_390_000 picoseconds.
+		Weight::from_parts(5_502_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1)
@@ -132,8 +155,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `105647`
 		//  Estimated: `109112`
-		// Minimum execution time: 220_260_000 picoseconds.
-		Weight::from_parts(223_231_000, 0)
+		// Minimum execution time: 207_968_000 picoseconds.
+		Weight::from_parts(217_920_000, 0)
 			.saturating_add(Weight::from_parts(0, 109112))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -156,8 +179,8 @@ impl<T: frame_system::Config> cumulus_pallet_xcmp_queue::WeightInfo for WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `65716`
 		//  Estimated: `69181`
-		// Minimum execution time: 130_156_000 picoseconds.
-		Weight::from_parts(133_488_000, 0)
+		// Minimum execution time: 126_367_000 picoseconds.
+		Weight::from_parts(129_651_000, 0)
 			.saturating_add(Weight::from_parts(0, 69181))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
diff --git a/substrate/frame/message-queue/src/lib.rs b/substrate/frame/message-queue/src/lib.rs
index 0e2a2f6b01b..133ba2c5256 100644
--- a/substrate/frame/message-queue/src/lib.rs
+++ b/substrate/frame/message-queue/src/lib.rs
@@ -975,39 +975,57 @@ impl<T: Config> Pallet<T> {
 		Ok(())
 	}
 
-	fn do_enqueue_message(
+	fn do_enqueue_messages<'a>(
 		origin: &MessageOriginOf<T>,
-		message: BoundedSlice<u8, MaxMessageLenOf<T>>,
+		messages: impl Iterator<Item = BoundedSlice<'a, u8, MaxMessageLenOf<T>>>,
 	) {
 		let mut book_state = BookStateFor::<T>::get(origin);
-		book_state.message_count.saturating_inc();
-		book_state
-			.size
-			// This should be payload size, but here the payload *is* the message.
-			.saturating_accrue(message.len() as u64);
 
+		let mut maybe_page = None;
+		// Check if we already have a page in progress.
 		if book_state.end > book_state.begin {
 			debug_assert!(book_state.ready_neighbours.is_some(), "Must be in ready ring if ready");
-			// Already have a page in progress - attempt to append.
-			let last = book_state.end - 1;
-			let mut page = match Pages::<T>::get(origin, last) {
-				Some(p) => p,
-				None => {
-					defensive!("Corruption: referenced page doesn't exist.");
-					return
-				},
-			};
-			if page.try_append_message::<T>(message).is_ok() {
-				Pages::<T>::insert(origin, last, &page);
-				BookStateFor::<T>::insert(origin, book_state);
-				return
+			maybe_page = Pages::<T>::get(origin, book_state.end - 1).or_else(|| {
+				defensive!("Corruption: referenced page doesn't exist.");
+				None
+			});
+		}
+
+		for message in messages {
+			// Try to append the message to the current page if possible.
+			if let Some(mut page) = maybe_page {
+				maybe_page = match page.try_append_message::<T>(message) {
+					Ok(_) => Some(page),
+					Err(_) => {
+						// Not enough space on the current page.
+						// Let's save it, since we'll move to a new one.
+						Pages::<T>::insert(origin, book_state.end - 1, page);
+						None
+					},
+				}
 			}
-		} else {
-			debug_assert!(
-				book_state.ready_neighbours.is_none(),
-				"Must not be in ready ring if not ready"
-			);
-			// insert into ready queue.
+			// If not, add it to a new page.
+			if maybe_page.is_none() {
+				book_state.end.saturating_inc();
+				book_state.count.saturating_inc();
+				maybe_page = Some(Page::from_message::<T>(message));
+			}
+
+			// Account for the message that we just added.
+			book_state.message_count.saturating_inc();
+			book_state
+				.size
+				// This should be payload size, but here the payload *is* the message.
+				.saturating_accrue(message.len() as u64);
+		}
+
+		// Save the last page that we created.
+		if let Some(page) = maybe_page {
+			Pages::<T>::insert(origin, book_state.end - 1, page);
+		}
+
+		// Insert book state for current origin into the ready queue.
+		if book_state.ready_neighbours.is_none() {
 			match Self::ready_ring_knit(origin) {
 				Ok(neighbours) => book_state.ready_neighbours = Some(neighbours),
 				Err(()) => {
@@ -1015,11 +1033,7 @@ impl<T: Config> Pallet<T> {
 				},
 			}
 		}
-		// No room on the page or no page - link in a new page.
-		book_state.end.saturating_inc();
-		book_state.count.saturating_inc();
-		let page = Page::from_message::<T>(message);
-		Pages::<T>::insert(origin, book_state.end - 1, page);
+
 		// NOTE: `T::QueueChangeHandler` is called by the caller.
 		BookStateFor::<T>::insert(origin, book_state);
 	}
@@ -1758,7 +1772,7 @@ impl<T: Config> EnqueueMessage<MessageOriginOf<T>> for Pallet<T> {
 		message: BoundedSlice<u8, Self::MaxMessageLen>,
 		origin: <T::MessageProcessor as ProcessMessage>::Origin,
 	) {
-		Self::do_enqueue_message(&origin, message);
+		Self::do_enqueue_messages(&origin, [message].into_iter());
 		let book_state = BookStateFor::<T>::get(&origin);
 		T::QueueChangeHandler::on_queue_changed(origin, book_state.into());
 	}
@@ -1767,9 +1781,7 @@ impl<T: Config> EnqueueMessage<MessageOriginOf<T>> for Pallet<T> {
 		messages: impl Iterator<Item = BoundedSlice<'a, u8, Self::MaxMessageLen>>,
 		origin: <T::MessageProcessor as ProcessMessage>::Origin,
 	) {
-		for message in messages {
-			Self::do_enqueue_message(&origin, message);
-		}
+		Self::do_enqueue_messages(&origin, messages);
 		let book_state = BookStateFor::<T>::get(&origin);
 		T::QueueChangeHandler::on_queue_changed(origin, book_state.into());
 	}
-- 
GitLab