diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs
index f40940a8b25faa7c441b1ac9b237cb34e671cf17..dbe681f51bb2a8a1f61f9e923e16914dd2eb2fd8 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_ambassador_core.rs
@@ -58,6 +58,17 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo<
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `AmbassadorCore::Params` (r:0 w:1)
+	/// Proof: `AmbassadorCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`)
+	fn set_partial_params() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 11_000_000 picoseconds.
+		Weight::from_parts(11_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
 	/// Storage: `AmbassadorCore::Member` (r:1 w:1)
 	/// Proof: `AmbassadorCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
 	/// Storage: `AmbassadorCollective::Members` (r:1 w:1)
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs
index 471ee82ead729ea5abff616f0c9fe3a86704fd91..7e6264c0c10d708f1a089cb861094e121f0c5604 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_core_fellowship_fellowship_core.rs
@@ -57,6 +57,17 @@ impl<T: frame_system::Config> pallet_core_fellowship::WeightInfo for WeightInfo<
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `FellowshipCore::Params` (r:0 w:1)
+	/// Proof: `FellowshipCore::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`)
+	fn set_partial_params() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 11_000_000 picoseconds.
+		Weight::from_parts(12_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
 	/// Storage: `FellowshipCore::Member` (r:1 w:1)
 	/// Proof: `FellowshipCore::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
 	/// Storage: `FellowshipCollective::Members` (r:1 w:1)
diff --git a/prdoc/pr_3843.prdoc b/prdoc/pr_3843.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..e01900dcc25b998124a2929f14171d049c2fa698
--- /dev/null
+++ b/prdoc/pr_3843.prdoc
@@ -0,0 +1,17 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Introduce a new dispatchable function `set_partial_params` in `pallet-core-fellowship`
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      This PR adds a new dispatchable function `set_partial_params` 
+      to update config with multiple arguments without duplicating the 
+      fields that does not need to update.
+
+crates:
+  - name: pallet-core-fellowship
+    bump: major
+  - name: collectives-westend-runtime
+    bump: patch
diff --git a/substrate/frame/core-fellowship/src/benchmarking.rs b/substrate/frame/core-fellowship/src/benchmarking.rs
index b3ee3ab7d165fd87710b207ab4668bba450e2189..2dabab3983d094d566ad500ae4e4e5cbdba65b70 100644
--- a/substrate/frame/core-fellowship/src/benchmarking.rs
+++ b/substrate/frame/core-fellowship/src/benchmarking.rs
@@ -85,6 +85,45 @@ mod benchmarks {
 		Ok(())
 	}
 
+	#[benchmark]
+	fn set_partial_params() -> Result<(), BenchmarkError> {
+		let max_rank = T::MaxRank::get().try_into().unwrap();
+
+		// Set up the initial default state for the Params storage
+		let params = ParamsType {
+			active_salary: BoundedVec::try_from(vec![100u32.into(); max_rank]).unwrap(),
+			passive_salary: BoundedVec::try_from(vec![10u32.into(); max_rank]).unwrap(),
+			demotion_period: BoundedVec::try_from(vec![100u32.into(); max_rank]).unwrap(),
+			min_promotion_period: BoundedVec::try_from(vec![100u32.into(); max_rank]).unwrap(),
+			offboard_timeout: 1u32.into(),
+		};
+		CoreFellowship::<T, I>::set_params(RawOrigin::Root.into(), Box::new(params))?;
+
+		let default_params = Params::<T, I>::get();
+		let expected_params = ParamsType {
+			active_salary: default_params.active_salary,
+			passive_salary: BoundedVec::try_from(vec![10u32.into(); max_rank]).unwrap(),
+			demotion_period: default_params.demotion_period,
+			min_promotion_period: BoundedVec::try_from(vec![100u32.into(); max_rank]).unwrap(),
+			offboard_timeout: 1u32.into(),
+		};
+
+		let params_payload = ParamsType {
+			active_salary: BoundedVec::try_from(vec![None; max_rank]).unwrap(),
+			passive_salary: BoundedVec::try_from(vec![Some(10u32.into()); max_rank]).unwrap(),
+			demotion_period: BoundedVec::try_from(vec![None; max_rank]).unwrap(),
+			min_promotion_period: BoundedVec::try_from(vec![Some(100u32.into()); max_rank])
+				.unwrap(),
+			offboard_timeout: None,
+		};
+
+		#[extrinsic_call]
+		_(RawOrigin::Root, Box::new(params_payload.clone()));
+
+		assert_eq!(Params::<T, I>::get(), expected_params);
+		Ok(())
+	}
+
 	#[benchmark]
 	fn bump_offboard() -> Result<(), BenchmarkError> {
 		set_benchmark_params::<T, I>()?;
diff --git a/substrate/frame/core-fellowship/src/lib.rs b/substrate/frame/core-fellowship/src/lib.rs
index 94339b85d0524a297241248312e92b31e761149c..6f0bb77714d99fd174f0c3ec3df31269df64823f 100644
--- a/substrate/frame/core-fellowship/src/lib.rs
+++ b/substrate/frame/core-fellowship/src/lib.rs
@@ -222,6 +222,11 @@ pub mod pallet {
 
 	pub type ParamsOf<T, I> =
 		ParamsType<<T as Config<I>>::Balance, BlockNumberFor<T>, <T as Config<I>>::MaxRank>;
+	pub type PartialParamsOf<T, I> = ParamsType<
+		Option<<T as Config<I>>::Balance>,
+		Option<BlockNumberFor<T>>,
+		<T as Config<I>>::MaxRank,
+	>;
 	pub type MemberStatusOf<T> = MemberStatus<BlockNumberFor<T>>;
 	pub type RankOf<T, I> = <<T as Config<I>>::Members as RankedMembers>::Rank;
 
@@ -558,9 +563,59 @@ pub mod pallet {
 
 			Ok(Pays::No.into())
 		}
+
+		/// Set the parameters partially.
+		///
+		/// - `origin`: An origin complying with `ParamsOrigin` or root.
+		/// - `partial_params`: The new parameters for the pallet.
+		///
+		/// This update config with multiple arguments without duplicating
+		/// the fields that does not need to update (set to None).
+		#[pallet::weight(T::WeightInfo::set_partial_params())]
+		#[pallet::call_index(9)]
+		pub fn set_partial_params(
+			origin: OriginFor<T>,
+			partial_params: Box<PartialParamsOf<T, I>>,
+		) -> DispatchResult {
+			T::ParamsOrigin::ensure_origin_or_root(origin)?;
+			let params = Params::<T, I>::mutate(|p| {
+				Self::set_partial_params_slice(&mut p.active_salary, partial_params.active_salary);
+				Self::set_partial_params_slice(
+					&mut p.passive_salary,
+					partial_params.passive_salary,
+				);
+				Self::set_partial_params_slice(
+					&mut p.demotion_period,
+					partial_params.demotion_period,
+				);
+				Self::set_partial_params_slice(
+					&mut p.min_promotion_period,
+					partial_params.min_promotion_period,
+				);
+				if let Some(new_offboard_timeout) = partial_params.offboard_timeout {
+					p.offboard_timeout = new_offboard_timeout;
+				}
+				p.clone()
+			});
+			Self::deposit_event(Event::<T, I>::ParamsChanged { params });
+			Ok(())
+		}
 	}
 
 	impl<T: Config<I>, I: 'static> Pallet<T, I> {
+		/// Partially update the base slice with a new slice
+		///
+		/// Only elements in the base slice which has a new value in the new slice will be updated.
+		pub(crate) fn set_partial_params_slice<S>(
+			base_slice: &mut BoundedVec<S, <T as Config<I>>::MaxRank>,
+			new_slice: BoundedVec<Option<S>, <T as Config<I>>::MaxRank>,
+		) {
+			for (base_element, new_element) in base_slice.iter_mut().zip(new_slice) {
+				if let Some(element) = new_element {
+					*base_element = element;
+				}
+			}
+		}
 		/// Convert a rank into a `0..RANK_COUNT` index suitable for the arrays in Params.
 		///
 		/// Rank 1 becomes index 0, rank `RANK_COUNT` becomes index `RANK_COUNT - 1`. Any rank not
diff --git a/substrate/frame/core-fellowship/src/tests/unit.rs b/substrate/frame/core-fellowship/src/tests/unit.rs
index 9245e5159a901d47842339836ae3f0767a2b1b1f..5d6d59c5c8918987087ea4dc3537a96fd56e00e4 100644
--- a/substrate/frame/core-fellowship/src/tests/unit.rs
+++ b/substrate/frame/core-fellowship/src/tests/unit.rs
@@ -187,6 +187,40 @@ fn set_params_works() {
 	});
 }
 
+#[test]
+fn set_partial_params_works() {
+	new_test_ext().execute_with(|| {
+		let params = ParamsType {
+			active_salary: bounded_vec![None; 9],
+			passive_salary: bounded_vec![None; 9],
+			demotion_period: bounded_vec![None, Some(10), None, None, None, None, None, None, None],
+			min_promotion_period: bounded_vec![None; 9],
+			offboard_timeout: Some(2),
+		};
+		assert_noop!(
+			CoreFellowship::set_partial_params(signed(2), Box::new(params.clone())),
+			DispatchError::BadOrigin
+		);
+		assert_ok!(CoreFellowship::set_partial_params(signed(1), Box::new(params)));
+
+		// Update params from the base params value declared in `new_test_ext`
+		let raw_updated_params = ParamsType {
+			active_salary: bounded_vec![10, 20, 30, 40, 50, 60, 70, 80, 90],
+			passive_salary: bounded_vec![1, 2, 3, 4, 5, 6, 7, 8, 9],
+			demotion_period: bounded_vec![2, 10, 6, 8, 10, 12, 14, 16, 18],
+			min_promotion_period: bounded_vec![3, 6, 9, 12, 15, 18, 21, 24, 27],
+			offboard_timeout: 2,
+		};
+		// Updated params stored in Params storage value
+		let updated_params = Params::<Test>::get();
+		assert_eq!(raw_updated_params, updated_params);
+
+		System::assert_last_event(
+			Event::<Test, _>::ParamsChanged { params: updated_params }.into(),
+		);
+	});
+}
+
 #[test]
 fn induct_works() {
 	new_test_ext().execute_with(|| {
diff --git a/substrate/frame/core-fellowship/src/weights.rs b/substrate/frame/core-fellowship/src/weights.rs
index 8fad6f585c1129e9a6c4160ed396cea28158e990..c1042d0ddfafa6c05fb1632c751d81c309fda1b3 100644
--- a/substrate/frame/core-fellowship/src/weights.rs
+++ b/substrate/frame/core-fellowship/src/weights.rs
@@ -50,6 +50,7 @@ use core::marker::PhantomData;
 /// Weight functions needed for `pallet_core_fellowship`.
 pub trait WeightInfo {
 	fn set_params() -> Weight;
+	fn set_partial_params() -> Weight;
 	fn bump_offboard() -> Weight;
 	fn bump_demote() -> Weight;
 	fn set_active() -> Weight;
@@ -74,6 +75,16 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		Weight::from_parts(8_018_000, 0)
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
+	/// Storage: CoreFellowship Params (r:0 w:1)
+	/// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen)
+	fn set_partial_params() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 9_454_000 picoseconds.
+		Weight::from_parts(9_804_000, 0)
+			.saturating_add(T::DbWeight::get().writes(1_u64))
+	}
 	/// Storage: `CoreFellowship::Member` (r:1 w:1)
 	/// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
 	/// Storage: `RankedCollective::Members` (r:1 w:1)
@@ -245,6 +256,16 @@ impl WeightInfo for () {
 		Weight::from_parts(8_018_000, 0)
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
+	/// Storage: CoreFellowship Params (r:0 w:1)
+	/// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen)
+	fn set_partial_params() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 9_454_000 picoseconds.
+		Weight::from_parts(9_804_000, 0)
+			.saturating_add(RocksDbWeight::get().writes(1_u64))
+	}
 	/// Storage: `CoreFellowship::Member` (r:1 w:1)
 	/// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
 	/// Storage: `RankedCollective::Members` (r:1 w:1)