diff --git a/src/box/recovery.cc b/src/box/recovery.cc
index ce3630afaab346ba203532e0fd355db7035fd293..e94ca3e22e0218345753b5a2693f8bf9df477e0c 100644
--- a/src/box/recovery.cc
+++ b/src/box/recovery.cc
@@ -451,6 +451,23 @@ recovery_finalize(struct recovery_state *r, enum wal_mode wal_mode,
 
 /* {{{ Local recovery: support of hot standby and replication relay */
 
+struct recovery_stat_data {
+	struct fiber *f;
+	bool signaled;
+};
+
+static void
+recovery_stat_cb(ev_loop *loop, ev_stat *stat, int revents)
+{
+	(void) loop;
+	(void) revents;
+	struct recovery_stat_data *data =
+		(struct recovery_stat_data *) stat->data;
+	data->signaled = true;
+	if (data->f->flags & FIBER_IS_CANCELLABLE)
+		fiber_wakeup(data->f);
+}
+
 static void
 recovery_follow_f(va_list ap)
 {
@@ -458,20 +475,40 @@ recovery_follow_f(va_list ap)
 	ev_tstamp wal_dir_rescan_delay = va_arg(ap, ev_tstamp);
 	fiber_set_user(fiber(), &admin_credentials);
 
+	char path[PATH_MAX] = { '\0' };
+	struct recovery_stat_data data = { fiber(), false };
+	struct ev_stat stat;
+	ev_stat_init(&stat, recovery_stat_cb, path, 0.0);
+	stat.data = &data;
+
+	auto evstat_guard = make_scoped_guard([&] {
+		ev_stat_stop(loop(), &stat);
+	});
+
 	while (! fiber_is_cancelled()) {
+		data.signaled = false;
 		recover_remaining_wals(r);
+
+		if (ev_is_active(&stat) && ((r->current_wal == NULL) ||
+		     (strcmp(r->current_wal->filename, stat.path) != 0)))
+			ev_stat_stop(loop(), &stat);
+
+		if (r->current_wal != NULL && !ev_is_active(&stat)) {
+			snprintf(path, sizeof(path), "%s",
+				 r->current_wal->filename);
+			ev_stat_init(&stat, recovery_stat_cb, path, 0.0);
+			ev_stat_start(loop(), &stat);
+		}
+
+		if (data.signaled)
+			continue;
+
 		/**
 		 * Allow an immediate wakeup/break loop
 		 * from recovery_stop_local().
 		 */
 		fiber_set_cancellable(true);
-		if (r->current_wal != NULL) {
-			ev_stat stat;
-			coio_stat_init(&stat, r->current_wal->filename);
-			coio_stat_stat_timeout(&stat, wal_dir_rescan_delay);
-		} else {
-			fiber_yield_timeout(wal_dir_rescan_delay);
-		}
+		fiber_yield_timeout(wal_dir_rescan_delay);
 		fiber_set_cancellable(false);
 	}
 }