diff --git a/amadeus/src/app.rs b/amadeus/src/app.rs
index fde30c99b9cbde913aefff656a87af02fb23fd06..262a7dd4b4398625359a7fb0b83e762ce4c4477f 100644
--- a/amadeus/src/app.rs
+++ b/amadeus/src/app.rs
@@ -37,6 +37,9 @@ pub struct Amadeus {
     /// The last recieved instant, to calculate the delta and maybe time some animations.
     last_instant: iced::time::Instant,
 
+    /// The last database epoch found.
+    last_epoch: Option<u64>,
+
     /// The configuration, can be edited with the settings modal.
     config: config::State,
 
@@ -97,6 +100,7 @@ impl Default for Amadeus {
             show_main_panel: false,
             is_connected: false,
             is_init: false,
+            last_epoch: None,
 
             // Has default.
             connect_config: Default::default(),
@@ -120,12 +124,27 @@ impl Amadeus {
         id: KId,
         cb: impl FnOnce(Arc<Kara>) -> Message + 'static + Send,
     ) -> Command<Message> {
-        let store = self.kara_store.clone();
-        Command::perform(async move { store.get(id).await }, |kara| {
+        Command::perform(KaraStore::into_get(self.kara_store.clone(), id), |kara| {
             kara.map(cb).into()
         })
     }
 
+    /// Commands to issue to clear data from the [Amadeus] application.
+    fn clear() -> Command<Message> {
+        Message::from_iter([
+            Message::ConfigMessage(config::Message::Infos(None)),
+            Message::MainPanelMessage(mainpanel::Message::Queue(mainpanel::queue::Message::Clear)),
+            Message::MainPanelMessage(mainpanel::Message::History(
+                mainpanel::history::Message::Clear,
+            )),
+            Message::MainPanelMessage(mainpanel::Message::Playlists(
+                mainpanel::playlists::Message::Clear,
+            )),
+            Message::SidebarMessage(sidebar::Message::ClearPlaylists),
+        ])
+        .perform()
+    }
+
     fn get_history(&self) -> impl Future<Output = Option<Vec<Arc<Kara>>>> {
         let cfg = self.connect_config.clone();
         let store = self.kara_store.clone();
@@ -298,8 +317,8 @@ impl Amadeus {
                     send(remove_from_playlist(cfg, name, KaraFilter::KId(id)))
                 }
                 playlists::Request::ChangeView => {
-                    let show = either!(self.is_connected => MainPanelDisplay::MainPanel(mainpanel::Show::Queue); MainPanelDisplay::Config);
-                    Command::perform(async {}, |_| Message::MainPanelDisplay(show))
+                    Message::MainPanelDisplay(either!(self.is_connected => MainPanelDisplay::MainPanel(mainpanel::Show::Queue); MainPanelDisplay::Config))
+                        .perform()
                 }
             },
 
@@ -370,8 +389,7 @@ impl Amadeus {
                         playlists::Message::RemoveKaraFromPlaylist(name, id.clone()).into(),
                     ])
                 });
-                let action = |_| ShowModal::ChoosePlaylist(plts, callback).into();
-                Command::perform(async {}, action)
+                Message::from(ShowModal::ChoosePlaylist(plts, callback)).perform()
             }
             (Some(plt), AddToPlaylist(id)) => {
                 let plts = self.playlist_list().to_vec();
@@ -421,7 +439,12 @@ impl Amadeus {
     }
 
     /// Perform the init ping if needed
-    fn command_init_ping(&self) -> Command<<Self as Application>::Message> {
+    fn command_init_ping(&mut self) -> Command<<Self as Application>::Message> {
+        if self.is_init {
+            log::error!("try to send init ping multiple times");
+            return Command::none();
+        }
+        self.is_init = true;
         let flag = self.config.amadeus.open_config_if_init_ping_failed;
         Command::perform(get_infos(self.connect_config.clone()), move |res| {
             Message::from_err_or_elses(
@@ -508,9 +531,7 @@ impl Application for Amadeus {
                 res.map_err(|err| anyhow!("load icon font err: {err:?}"))
                     .into()
             }),
-            Command::perform(async {}, move |()| {
-                config::Message::LoadConfig(config).into()
-            }),
+            Message::from(config::Message::LoadConfig(config)).perform(),
             iced::system::fetch_information(config::Message::SystemInformations).map(Message::from),
         ]);
         (Default::default(), init_events)
@@ -583,11 +604,10 @@ impl Application for Amadeus {
             }
 
             // Open a link.
-            Message::OpenLinkInBrowser(link) => Command::perform(async {}, move |_| {
+            Message::OpenLinkInBrowser(link) => Message::into_perform(
                 lektor_utils::open::that(link)
-                    .map_err(|err| anyhow!("failed to open {link}: {err:?}"))
-                    .into()
-            }),
+                    .map_err(|err| anyhow!("failed to open {link}: {err:?}")),
+            ),
 
             // Kill lektord & exit the application
             Message::ExitApplication => iced::window::close(),
@@ -610,21 +630,7 @@ impl Application for Amadeus {
                 Command::batch([
                     flag.then(|| self.update(Message::MainPanelDisplay(MainPanelDisplay::Config)))
                         .unwrap_or_else(Command::none),
-                    Command::perform(async {}, |_| {
-                        Message::from_iter([
-                            Message::ConfigMessage(config::Message::Infos(None)),
-                            Message::MainPanelMessage(mainpanel::Message::Queue(
-                                mainpanel::queue::Message::Clear,
-                            )),
-                            Message::MainPanelMessage(mainpanel::Message::History(
-                                mainpanel::history::Message::Clear,
-                            )),
-                            Message::MainPanelMessage(mainpanel::Message::Playlists(
-                                mainpanel::playlists::Message::Clear,
-                            )),
-                            Message::SidebarMessage(sidebar::Message::ClearPlaylists),
-                        ])
-                    }),
+                    Amadeus::clear(),
                 ])
             }
             Message::ConnectionStatus(_) => Command::none(),
@@ -655,7 +661,6 @@ impl Application for Amadeus {
             }
             Message::SmollTick(instant) => {
                 self.last_instant = self.last_instant.max(instant);
-                let cfg = self.connect_config.clone();
 
                 let queue = Command::perform(self.get_queue(), |res| {
                     res.map(|queue| {
@@ -675,44 +680,47 @@ impl Application for Amadeus {
                     .unwrap_or(Message::ConnectionStatus(false))
                 });
 
-                let status = Command::perform(get_status(cfg), |res| match res {
-                    Ok(PlayStateWithCurrent {
-                        state: s @ PlayState::Play | s @ PlayState::Pause,
-                        current: Some((id, elapsed, duration)),
-                    }) => Message::from_iter([
-                        Message::ChangedPlayback(s),
-                        Message::ChangedKaraId(id),
-                        Message::TimeUpdate(elapsed, duration),
-                    ]),
-                    Ok(PlayStateWithCurrent {
-                        state: PlayState::Stop,
-                        current: None,
-                    }) => Message::ChangedPlayback(PlayState::Stop),
-                    Ok(state) => {
-                        log::error!("got incoherent state from the server: {state:?}");
-                        Message::ChangedPlayback(PlayState::Stop)
-                    }
-                    Err(_) => Message::ConnectionStatus(false),
-                });
+                let status =
+                    Command::perform(get_status(self.connect_config.clone()), |res| match res {
+                        Ok(PlayStateWithCurrent {
+                            state: s @ PlayState::Play | s @ PlayState::Pause,
+                            current: Some((id, elapsed, duration)),
+                        }) => Message::from_iter([
+                            Message::ChangedPlayback(s),
+                            Message::ChangedKaraId(id),
+                            Message::TimeUpdate(elapsed, duration),
+                        ]),
+                        Ok(PlayStateWithCurrent {
+                            state: PlayState::Stop,
+                            current: None,
+                        }) => Message::ChangedPlayback(PlayState::Stop),
+                        Ok(state) => {
+                            log::error!("got incoherent state from the server: {state:?}");
+                            Message::ChangedPlayback(PlayState::Stop)
+                        }
+                        Err(_) => Message::ConnectionStatus(false),
+                    });
 
                 Command::batch([queue, history, status])
             }
 
             // Config changed
             Message::ConfigMessage(config) => self.handle_config_message(config),
-            Message::ConfigLoaded => {
-                log::info!("config was loaded, start rendering the application");
-                self.is_init = true;
-                self.command_init_ping()
-            }
-            Message::ReconnectToLektord(flush) => {
-                log::error!("need to handle the reconnect message with flush status: {flush}");
-                Command::none()
-            }
-            Message::DatabaseEpoch(epoch) => {
-                log::error!("need to handle epoch {epoch}");
-                Command::none()
-            }
+            Message::ConfigLoaded => self.command_init_ping(),
+            Message::ReconnectToLektord => Command::batch([
+                send(KaraStore::into_clear(self.kara_store.clone())),
+                Amadeus::clear(),
+            ]),
+            Message::DatabaseEpoch(epoch) => match self.last_epoch.take() {
+                Some(last_epoch) if last_epoch != epoch => {
+                    self.last_epoch = Some(last_epoch.max(epoch));
+                    Message::ReconnectToLektord.perform()
+                }
+                _ => {
+                    self.last_epoch = Some(epoch);
+                    Command::none()
+                }
+            },
 
             // Change what the main panel displays + We have informations to pass to it
             Message::MainPanelMessage(message) => self.mainpanel.update(message).map(Message::from),
diff --git a/amadeus/src/message.rs b/amadeus/src/message.rs
index 6147027ce917a28163202a405a88a884717123f2..53bf7889c271dd01b1b8289357fd7a18b06e8ce0 100644
--- a/amadeus/src/message.rs
+++ b/amadeus/src/message.rs
@@ -4,6 +4,7 @@ use crate::components::{
     modal::ShowModal,
     sidebar, topbar,
 };
+use iced::Command;
 use lektor_payloads::{KId, Kara, PlayState, Priority};
 use lektor_utils::log;
 use std::sync::Arc;
@@ -71,9 +72,8 @@ pub enum Message {
     /// The config was loaded, can start rendering the application.
     ConfigLoaded,
 
-    /// Need to reconnect to the lektord instance. If the flag is true then we need to flush the
-    /// caches and reload things...
-    ReconnectToLektord(bool),
+    /// Need to reconnect to the lektord instance. We need to flush the caches and reload things...
+    ReconnectToLektord,
 
     /// The current kara changed and we got the kara struct.
     ChangedKara(Arc<Kara>),
@@ -169,6 +169,16 @@ impl Message {
         res.map_err(|err| log::error!("{err}"))
             .unwrap_or_else(|()| Message::from_iter(err()))
     }
+
+    /// Wrapper to avoid calling [Command::perform] every time with an empty future...
+    pub fn perform(self) -> Command<Message> {
+        Command::perform(async {}, |_| self)
+    }
+
+    pub fn into_perform(this: impl Into<Self>) -> Command<Message> {
+        let this = this.into();
+        Command::perform(async {}, |_| this)
+    }
 }
 
 impl std::fmt::Display for MainPanelDisplay {
@@ -319,9 +329,8 @@ impl From<bottombar::Message> for Message {
 impl From<config::Request> for Message {
     fn from(value: config::Request) -> Self {
         match value {
-            config::Request::None => Message::None,
-            config::Request::Reconnect => Message::ReconnectToLektord(false),
-            config::Request::FlushCacheAndReconnect => Message::ReconnectToLektord(true),
+            config::Request::Reconnect | config::Request::None => Message::None,
+            config::Request::FlushCacheAndReconnect => Message::ReconnectToLektord,
             config::Request::Loaded => Message::ConfigLoaded,
             config::Request::ToggleMprisServer(flag) => Message::ToggleMprisServer(flag),
         }
diff --git a/amadeus/src/store.rs b/amadeus/src/store.rs
index 76b78dbe2247fd08b4d3a7eade67d9af5e7fa1a5..9cb0bc763ea3e7cb84150a4307d178a92632a3ca 100644
--- a/amadeus/src/store.rs
+++ b/amadeus/src/store.rs
@@ -39,6 +39,12 @@ impl KaraStore {
         let _ = self.sender.send_replace(config);
     }
 
+    /// Clear the cache.
+    pub async fn clear(&self) -> Result<()> {
+        self.store.write().await.clear();
+        Ok(())
+    }
+
     /// Get a kara from lektord by its [KId]. If the config was updated, we apply the update.
     /// We prefer to get the kara from the internal hashmap, if the kara is not present, we request
     /// it from lektord.
@@ -51,16 +57,20 @@ impl KaraStore {
             return Ok(kara.clone());
         }
         let kara = Arc::new(get_kara_by_kid(self.config.read().await.clone(), id).await?);
-        self.store
-            .write()
-            .await
-            .insert(kara.id.clone(), kara.clone());
+        let mut store = self.store.write().await;
+        store.insert(kara.id.clone(), kara.clone());
         Ok(kara)
     }
 
     /// Same as the [KaraStore::get], but we consume a cloned pointer to have to write less
     /// boiler-plate code.
-    pub async fn into_get(this: Arc<Self>, id: KId) -> Result<Arc<Kara>> {
-        this.as_ref().get(id).await
+    pub async fn into_get(self: Arc<Self>, id: KId) -> Result<Arc<Kara>> {
+        self.as_ref().get(id).await
+    }
+
+    /// Same as [KaraStore::clear], but we consume a cloned pointer to have to write less
+    /// boiler-plate code.
+    pub async fn into_clear(self: Arc<Self>) -> Result<()> {
+        self.clear().await
     }
 }