diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0314fde0..0426b63d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -199,6 +199,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
     ([`#1915`](https://github.com/polybar/polybar/issues/1915))
 - `internal/network`: The module now properly supports 'altnames' for
   interfaces.
+- Some modules stop updating when system time moves backwards. ([`#857`](https://github.com/polybar/polybar/issues/857), [`#1932`](https://github.com/polybar/polybar/issues/1932))
 
 ## [3.5.7] - 2021-09-21
 ### Fixed
diff --git a/include/adapters/mpd.hpp b/include/adapters/mpd.hpp
index 2a152b01..d6f1b26e 100644
--- a/include/adapters/mpd.hpp
+++ b/include/adapters/mpd.hpp
@@ -162,7 +162,6 @@ namespace mpd {
     mpd_status_t m_status{};
     unique_ptr<mpdsong> m_song{};
     mpdstate m_state{mpdstate::UNKNOWN};
-    chrono::system_clock::time_point m_updated_at{};
 
     bool m_random{false};
     bool m_repeat{false};
diff --git a/include/adapters/net.hpp b/include/adapters/net.hpp
index f9aa2920..4785db78 100644
--- a/include/adapters/net.hpp
+++ b/include/adapters/net.hpp
@@ -62,7 +62,7 @@ namespace net {
   struct link_activity {
     bytes_t transmitted{0};
     bytes_t received{0};
-    std::chrono::system_clock::time_point time;
+    std::chrono::steady_clock::time_point time;
   };
 
   struct link_status {
diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp
index 83c7450f..4a10a501 100644
--- a/include/modules/battery.hpp
+++ b/include/modules/battery.hpp
@@ -112,7 +112,7 @@ namespace modules {
     string m_timeformat;
     size_t m_unchanged{SKIP_N_UNCHANGED};
     chrono::duration<double> m_interval{};
-    chrono::system_clock::time_point m_lastpoll;
+    chrono::steady_clock::time_point m_lastpoll;
     thread m_subthread;
   };
 }  // namespace modules
diff --git a/include/modules/meta/timer_module.hpp b/include/modules/meta/timer_module.hpp
index a9ede914..4d475271 100644
--- a/include/modules/meta/timer_module.hpp
+++ b/include/modules/meta/timer_module.hpp
@@ -50,7 +50,7 @@ namespace modules {
             CAST_MOD(Impl)->broadcast();
           }
           // wait until next full interval to avoid drifting clocks
-          using clock = chrono::system_clock;
+          using clock = chrono::steady_clock;
           using sys_duration_t = clock::time_point::duration;
 
           auto sys_interval = chrono::duration_cast<sys_duration_t>(m_interval);
diff --git a/include/modules/mpd.hpp b/include/modules/mpd.hpp
index 855132e9..5c44ae1d 100644
--- a/include/modules/mpd.hpp
+++ b/include/modules/mpd.hpp
@@ -96,7 +96,7 @@ namespace modules {
     string m_pass;
     unsigned int m_port{6600U};
 
-    chrono::system_clock::time_point m_lastsync{};
+    chrono::steady_clock::time_point m_lastsync{};
     float m_synctime{1.0f};
 
     int m_quick_attempts{0};
diff --git a/src/adapters/mpd.cpp b/src/adapters/mpd.cpp
index 425af042..ac600f93 100644
--- a/src/adapters/mpd.cpp
+++ b/src/adapters/mpd.cpp
@@ -382,7 +382,6 @@ namespace mpd {
 
   void mpdstatus::fetch_data(mpdconnection* conn) {
     m_status.reset(mpd_run_status(*conn));
-    m_updated_at = chrono::system_clock::now();
     m_songid = mpd_status_get_song_id(m_status.get());
     m_queuelen = mpd_status_get_queue_length(m_status.get());
     m_random = mpd_status_get_random(m_status.get());
diff --git a/src/adapters/net.cpp b/src/adapters/net.cpp
index e7853486..cc351f21 100644
--- a/src/adapters/net.cpp
+++ b/src/adapters/net.cpp
@@ -141,7 +141,7 @@ namespace net {
     m_status.previous = m_status.current;
     m_status.current.transmitted = 0;
     m_status.current.received = 0;
-    m_status.current.time = std::chrono::system_clock::now();
+    m_status.current.time = std::chrono::steady_clock::now();
     m_status.ip = NO_IP;
     m_status.ip6 = NO_IP;
 
diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp
index 4c6dd7ff..e0f47c98 100644
--- a/src/modules/battery.cpp
+++ b/src/modules/battery.cpp
@@ -29,7 +29,7 @@ namespace modules {
     m_fullat = math_util::min(m_conf.get(name(), "full-at", m_fullat), 100);
     m_lowat = math_util::max(m_conf.get(name(), "low-at", m_lowat), 0);
     m_interval = m_conf.get<decltype(m_interval)>(name(), "poll-interval", 5s);
-    m_lastpoll = chrono::system_clock::now();
+    m_lastpoll = chrono::steady_clock::now();
 
     auto path_adapter = string_util::replace(PATH_ADAPTER, "%adapter%", m_conf.get(name(), "adapter", "ADP1"s)) + "/";
     auto path_battery = string_util::replace(PATH_BATTERY, "%battery%", m_conf.get(name(), "battery", "BAT0"s)) + "/";
@@ -195,7 +195,7 @@ namespace modules {
    */
   void battery_module::idle() {
     if (m_interval.count() > 0) {
-      auto now = chrono::system_clock::now();
+      auto now = chrono::steady_clock::now();
       if (chrono::duration_cast<decltype(m_interval)>(now - m_lastpoll) > m_interval) {
         m_lastpoll = now;
         m_log.info("%s: Polling values (inotify fallback)", name());
@@ -214,7 +214,7 @@ namespace modules {
     auto percentage = current_percentage();
 
     // Reset timer to avoid unnecessary polling
-    m_lastpoll = chrono::system_clock::now();
+    m_lastpoll = chrono::steady_clock::now();
 
     if (event != nullptr) {
       m_log.trace("%s: Inotify event reported for %s", name(), event->filename);
diff --git a/src/modules/mpd.cpp b/src/modules/mpd.cpp
index c2658be7..56c9c361 100644
--- a/src/modules/mpd.cpp
+++ b/src/modules/mpd.cpp
@@ -129,7 +129,7 @@ namespace modules {
 
     // }}}
 
-    m_lastsync = chrono::system_clock::now();
+    m_lastsync = chrono::steady_clock::now();
 
     try {
       m_mpd = std::make_unique<mpdconnection>(m_log, m_host, m_port, m_pass);
@@ -204,7 +204,7 @@ namespace modules {
     }
 
     if ((m_label_time || m_bar_progress) && m_status->match_state(mpdstate::PLAYING)) {
-      auto now = chrono::system_clock::now();
+      auto now = chrono::steady_clock::now();
       auto diff = now - m_lastsync;
 
       if (chrono::duration_cast<chrono::milliseconds>(diff).count() > m_synctime * 1000) {