diff --git a/include/shell.h b/include/shell.h
index 8ad2e522bdc3d56f511161e845038188802356e4..2b7be9c1a8f670b903b44d6ad46ef8875ba1da4e 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -3,9 +3,9 @@
 
 #define UI_SHELL_MODE 0
 #define UI_GUI_MODE 1
-#define UI_STAT_MODE 2
 
 extern int wrc_ui_mode;
+extern int wrc_stat_running;
 
 const char *fromhex(const char *hex, int *v);
 const char *fromdec(const char *dec, int *v);
diff --git a/include/wrc.h b/include/wrc.h
index 0054967462ec654a46c02193450a7da38cc43f32..6f3e86a40b6aac9b684b566858351d841a6020d8 100644
--- a/include/wrc.h
+++ b/include/wrc.h
@@ -30,7 +30,7 @@
 
 void wrc_mon_gui(void);
 void shell_init(void);
-int wrc_log_stats(uint8_t onetime);
+int wrc_log_stats(void);
 void wrc_debug_printf(int subsys, const char *fmt, ...);
 
 /* This header is included by softpll: manage wrc/wrs difference */
diff --git a/monitor/monitor_ppsi.c b/monitor/monitor_ppsi.c
index c49a180f90de874b0ef47e81e801ddda564bbc68..7b667bb366e0720216682a38e14c102c06671e40 100644
--- a/monitor/monitor_ppsi.c
+++ b/monitor/monitor_ppsi.c
@@ -74,7 +74,8 @@ static int wrc_mon_status(void)
 
 void wrc_mon_gui(void)
 {
-	static uint32_t last;
+	static uint32_t last_jiffies;
+	static uint32_t last_servo_count;
 	struct hal_port_state state;
 	int tx, rx;
 	int aux_stat;
@@ -87,12 +88,14 @@ void wrc_mon_gui(void)
 			&((struct wr_data *)ppi->ext_data)->servo_state;
 	int64_t crtt;
 	int64_t total_asymmetry;
-	if (!last)
-		last = timer_get_tics();
-	if (time_before(timer_get_tics(), last + wrc_ui_refperiod))
-		return;
 
-	last = timer_get_tics();
+	if (!last_jiffies)
+		last_jiffies = timer_get_tics() - 1 -  wrc_ui_refperiod;
+	if (time_before(timer_get_tics(), last_jiffies + wrc_ui_refperiod)
+		&& last_servo_count == s->update_count)
+		return;
+	last_jiffies = timer_get_tics();
+	last_servo_count = s->update_count;
 
 	term_clear();
 
@@ -266,22 +269,22 @@ static void wrc_mon_std_servo(void)
 }
 
 
-int wrc_log_stats(uint8_t onetime)
+/* internal "last", exported to shell command */
+uint32_t wrc_stats_last;
+
+int wrc_log_stats(void)
 {
-	static uint32_t last;
 	struct hal_port_state state;
 	int tx, rx;
 	int aux_stat;
 	uint64_t sec;
 	uint32_t nsec;
-
-	if (!last)
-		last = timer_get_tics();
-	if (!onetime && time_before(timer_get_tics(), wrc_ui_refperiod + last))
-		return 0;
 	struct wr_servo_state *s =
 			&((struct wr_data *)ppi->ext_data)->servo_state;
-	last = timer_get_tics();
+
+	if (wrc_stats_last == s->update_count)
+		return 0;
+	wrc_stats_last = s->update_count;
 
 	shw_pps_gen_get_time(&sec, &nsec);
 	wrpc_get_port_state(&state, NULL);
diff --git a/shell/cmd_stat.c b/shell/cmd_stat.c
index 4c895cdd1afab0d93ecfd03d7f03d23892e441d1..7e158e6fdcbe54fac6b91b6f17dcb8fb02d9b497 100644
--- a/shell/cmd_stat.c
+++ b/shell/cmd_stat.c
@@ -2,15 +2,35 @@
 #include "endpoint.h"
 #include <string.h>
 #include <wrc.h>
+#include <errno.h>
+
+int wrc_stat_running;
+extern uint32_t wrc_stats_last;
 
 static int cmd_stat(const char *args[])
 {
-	if (!strcasecmp(args[0], "bts"))
-		mprintf("%d ps\n", ep_get_bitslide());
-	else
-		wrc_ui_mode = UI_STAT_MODE;
+	/* no arguments: invert */
+	if (!args[0]) {
+		wrc_stat_running = !wrc_stat_running;
+		wrc_stats_last--; /* force a line to be printed */
+		if (!wrc_stat_running)
+			pp_printf("statistics now off\n");
+		return 0;
+	}
 
+	/* arguments: bts, on, off */
+	if (!strcasecmp(args[0], "bts")) {
+		mprintf("%d ps\n", ep_get_bitslide());
+	} else if (!strcasecmp(args[0], "on")) {
+		wrc_stat_running = 1;
+		wrc_stats_last--; /* force a line to be printed */
+	} else if (!strcasecmp(args[0], "off")) {
+		wrc_stat_running = 0;
+		pp_printf("statistics now off\n");
+	} else
+		return -EINVAL;
 	return 0;
+
 }
 
 DEFINE_WRC_COMMAND(stat) = {
diff --git a/wrc_main.c b/wrc_main.c
index d2060514e646ac2b8bad39937e9f23d9da359da2..fd28e3e07427627feb2b022de94798500ba3b5c9 100644
--- a/wrc_main.c
+++ b/wrc_main.c
@@ -148,15 +148,12 @@ static void ui_update(void)
 			shell_init();
 			wrc_ui_mode = UI_SHELL_MODE;
 		}
-	} else if (wrc_ui_mode == UI_STAT_MODE) {
-		wrc_log_stats(0);
-		if (uart_read_byte() == 27 || wrc_ui_refperiod == 0) {
-			shell_init();
-			wrc_ui_mode = UI_SHELL_MODE;
-		}
-	} else
+	} else {
 		shell_interactive();
-
+	}
+	/* Stats is asynchronous now. It's not a different mode, but a flag */
+	if (wrc_stat_running)
+		wrc_log_stats();
 }
 
 /* initialize functions to be called after reset in check_reset function */