diff --git a/bridges/relays/parachains/src/parachains_loop.rs b/bridges/relays/parachains/src/parachains_loop.rs
index 6648f2efc72797dd3755a34b6f023092d3abb708..3ef9a7f7a731cc470c3041291d66cfd774ead5ca 100644
--- a/bridges/relays/parachains/src/parachains_loop.rs
+++ b/bridges/relays/parachains/src/parachains_loop.rs
@@ -24,7 +24,7 @@ use bp_polkadot_core::{
 };
 use futures::{
 	future::{FutureExt, Shared},
-	poll, select,
+	poll, select_biased,
 };
 use relay_substrate_client::{BlockNumberOf, Chain, HeaderIdOf};
 use relay_utils::{
@@ -216,10 +216,12 @@ where
 	// regular errors.
 
 	loop {
-		// either wait for new block, or exit signal
-		select! {
-			_ = async_std::task::sleep(min_block_interval).fuse() => {},
+		// Either wait for new block, or exit signal.
+		// Please note that we are prioritizing the exit signal since if both events happen at once
+		// it doesn't make sense to perform one more loop iteration.
+		select_biased! {
 			_ = exit_signal => return Ok(()),
+			_ = async_std::task::sleep(min_block_interval).fuse() => {},
 		}
 
 		// if source client is not yet synced, we'll need to sleep. Otherwise we risk submitting too