diff --git a/substrate/client/authority-discovery/src/interval.rs b/substrate/client/authority-discovery/src/interval.rs
index 23c7ce266e3bf8c13485f78dac6d4bb848ef4612..0eee0d159cd86bc781aeed0f3c68f28a75c02f46 100644
--- a/substrate/client/authority-discovery/src/interval.rs
+++ b/substrate/client/authority-discovery/src/interval.rs
@@ -28,6 +28,7 @@ use std::{
 ///
 /// Doubles interval duration on each tick until the configured maximum is reached.
 pub struct ExpIncInterval {
+	start: Duration,
 	max: Duration,
 	next: Duration,
 	delay: Delay,
@@ -37,14 +38,29 @@ impl ExpIncInterval {
 	/// Create a new [`ExpIncInterval`].
 	pub fn new(start: Duration, max: Duration) -> Self {
 		let delay = Delay::new(start);
-		Self { max, next: start * 2, delay }
+		Self { start, max, next: start * 2, delay }
 	}
 
-	/// Fast forward the exponentially increasing interval to the configured maximum.
+	/// Fast forward the exponentially increasing interval to the configured maximum, if not already
+	/// set.
 	pub fn set_to_max(&mut self) {
+		if self.next == self.max {
+			return;
+		}
+
 		self.next = self.max;
 		self.delay = Delay::new(self.next);
 	}
+
+	/// Rewind the exponentially increasing interval to the configured start, if not already set.
+	pub fn set_to_start(&mut self) {
+		if self.next == self.start * 2 {
+			return;
+		}
+
+		self.next = self.start * 2;
+		self.delay = Delay::new(self.start);
+	}
 }
 
 impl Stream for ExpIncInterval {
diff --git a/substrate/client/authority-discovery/src/worker.rs b/substrate/client/authority-discovery/src/worker.rs
index b77f0241ec2faf4d0466103b2bd07226715b334c..4ad7db5f7da94c8676a25f2090970c54fc09c05b 100644
--- a/substrate/client/authority-discovery/src/worker.rs
+++ b/substrate/client/authority-discovery/src/worker.rs
@@ -129,6 +129,9 @@ pub struct Worker<Client, Network, Block, DhtEventStream> {
 	/// List of keys onto which addresses have been published at the latest publication.
 	/// Used to check whether they have changed.
 	latest_published_keys: HashSet<AuthorityId>,
+	/// List of the kademlia keys that have been published at the latest publication.
+	/// Used to associate DHT events with our published records.
+	latest_published_kad_keys: HashSet<KademliaKey>,
 
 	/// Same value as in the configuration.
 	publish_non_global_ips: bool,
@@ -265,6 +268,7 @@ where
 			publish_interval,
 			publish_if_changed_interval,
 			latest_published_keys: HashSet::new(),
+			latest_published_kad_keys: HashSet::new(),
 			publish_non_global_ips: config.publish_non_global_ips,
 			public_addresses,
 			strict_record_validation: config.strict_record_validation,
@@ -397,8 +401,17 @@ where
 			self.client.as_ref(),
 		).await?.into_iter().collect::<HashSet<_>>();
 
-		if only_if_changed && keys == self.latest_published_keys {
-			return Ok(())
+		if only_if_changed {
+			// If the authority keys did not change and the `publish_if_changed_interval` was
+			// triggered then do nothing.
+			if keys == self.latest_published_keys {
+				return Ok(())
+			}
+
+			// We have detected a change in the authority keys, reset the timers to
+			// publish and gather data faster.
+			self.publish_interval.set_to_start();
+			self.query_interval.set_to_start();
 		}
 
 		let addresses = serialize_addresses(self.addresses_to_publish());
@@ -422,6 +435,8 @@ where
 			keys_vec,
 		)?;
 
+		self.latest_published_kad_keys = kv_pairs.iter().map(|(k, _)| k.clone()).collect();
+
 		for (key, value) in kv_pairs.into_iter() {
 			self.network.put_value(key, value);
 		}
@@ -523,6 +538,10 @@ where
 				}
 			},
 			DhtEvent::ValuePut(hash) => {
+				if !self.latest_published_kad_keys.contains(&hash) {
+					return;
+				}
+
 				// Fast forward the exponentially increasing interval to the configured maximum. In
 				// case this was the first successful address publishing there is no need for a
 				// timely retry.
@@ -535,6 +554,11 @@ where
 				debug!(target: LOG_TARGET, "Successfully put hash '{:?}' on Dht.", hash)
 			},
 			DhtEvent::ValuePutFailed(hash) => {
+				if !self.latest_published_kad_keys.contains(&hash) {
+					// Not a value we have published or received multiple times.
+					return;
+				}
+
 				if let Some(metrics) = &self.metrics {
 					metrics.dht_event_received.with_label_values(&["value_put_failed"]).inc();
 				}