diff --git a/bigbluebutton-html5/imports/api/connection-status/server/methods/addConnectionStatus.js b/bigbluebutton-html5/imports/api/connection-status/server/methods/addConnectionStatus.js
index 9e58b49f7f3d0256a8c748bc7d6bf7bc5e9a71e9..1774f594b63082d16a29c245e1c6b5dd67c6ab12 100644
--- a/bigbluebutton-html5/imports/api/connection-status/server/methods/addConnectionStatus.js
+++ b/bigbluebutton-html5/imports/api/connection-status/server/methods/addConnectionStatus.js
@@ -1,14 +1,53 @@
 import { check } from 'meteor/check';
+import Logger from '/imports/startup/server/logger';
 import updateConnectionStatus from '/imports/api/connection-status/server/modifiers/updateConnectionStatus';
 import { extractCredentials } from '/imports/api/common/server/helpers';
 
-export default function addConnectionStatus(level) {
-  check(level, String);
+const STATS = Meteor.settings.public.stats;
+
+const logConnectionStatus = (meetingId, userId, status, type, value) => {
+  switch (status) {
+    case 'normal':
+      Logger.info(`Connection status updated: meetingId=${meetingId} userId=${userId} type=${type}`);
+      break;
+    case 'warning':
+      // Skip
+      break;
+    case 'danger':
+    case 'critical':
+      switch (type) {
+        case 'audio':
+          const {
+            jitter,
+            loss,
+          } = value;
+          Logger.info(`Connection status updated: meetingId=${meetingId} userId=${userId} jitter=${jitter} loss=${loss}`);
+          break;
+        case 'socket':
+          const { rtt } = value;
+          Logger.info(`Connection status updated: meetingId=${meetingId} userId=${userId} rtt=${rtt}`);
+          break;
+        default:
+      }
+      break;
+    default:
+  }
+};
+
+export default function addConnectionStatus(status, type, value) {
+  check(status, String);
+  check(type, String);
+  check(value, Object);
 
   const { meetingId, requesterUserId } = extractCredentials(this.userId);
 
   check(meetingId, String);
   check(requesterUserId, String);
 
-  updateConnectionStatus(meetingId, requesterUserId, level);
+  if (STATS.log) logConnectionStatus(meetingId, requesterUserId, status, type, value);
+
+  // Avoid storing recoveries
+  if (status !== 'normal') {
+    updateConnectionStatus(meetingId, requesterUserId, status);
+  }
 }
diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/service.js b/bigbluebutton-html5/imports/ui/components/connection-status/service.js
index 4345a61adfb29518b88b727d475260eeff394c7d..f3cec763a72b7c99dabd6477142a5447b7831345 100644
--- a/bigbluebutton-html5/imports/ui/components/connection-status/service.js
+++ b/bigbluebutton-html5/imports/ui/components/connection-status/service.js
@@ -4,7 +4,6 @@ import Users from '/imports/api/users';
 import UsersPersistentData from '/imports/api/users-persistent-data';
 import Auth from '/imports/ui/services/auth';
 import Settings from '/imports/ui/services/settings';
-import Logger from '/imports/startup/client/logger';
 import _ from 'lodash';
 import { Session } from 'meteor/session';
 import { notify } from '/imports/ui/services/notification';
@@ -12,12 +11,7 @@ import { makeCall } from '/imports/ui/services/api';
 
 const STATS = Meteor.settings.public.stats;
 const NOTIFICATION = STATS.notification;
-const STATS_LENGTH = STATS.length;
 const STATS_INTERVAL = STATS.interval;
-const STATS_LOG = STATS.log;
-const RTT_INTERVAL = STATS_LENGTH * STATS_INTERVAL;
-// Set a bottom threshold to avoid log flooding
-const RTT_LOG_THRESHOLD = STATS.rtt[STATS.level.indexOf('danger')];
 const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator;
 
 const intlMessages = defineMessages({
@@ -50,17 +44,17 @@ const getStats = () => {
   return STATS.level[stats];
 };
 
-const setStats = (level = -1) => {
+const setStats = (level = -1, type = 'recovery', value = {}) => {
   if (stats !== level) {
     stats = level;
     statsDep.changed();
-    addConnectionStatus(level);
+    addConnectionStatus(level, type, value);
   }
 };
 
-const handleStats = (level) => {
+const handleStats = (level, type, value) => {
   if (level > stats) {
-    setStats(level);
+    setStats(level, type, value);
   }
 };
 
@@ -71,9 +65,9 @@ const handleAudioStatsEvent = (event) => {
     let active = false;
     // From higher to lower
     for (let i = STATS.level.length - 1; i >= 0; i--) {
-      if (loss > STATS.loss[i] || jitter > STATS.jitter[i]) {
+      if (loss >= STATS.loss[i] || jitter >= STATS.jitter[i]) {
         active = true;
-        handleStats(i);
+        handleStats(i, 'audio', { loss, jitter });
         break;
       }
     }
@@ -89,9 +83,9 @@ const handleSocketStatsEvent = (event) => {
     let active = false;
     // From higher to lower
     for (let i = STATS.level.length - 1; i >= 0; i--) {
-      if (rtt > STATS.rtt[i]) {
+      if (rtt >= STATS.rtt[i]) {
         active = true;
-        handleStats(i);
+        handleStats(i, 'socket', { rtt });
         break;
       }
     }
@@ -108,26 +102,17 @@ const startStatsTimeout = () => {
   }, STATS.timeout);
 };
 
-const addConnectionStatus = (level) => {
-  if (level !== -1) makeCall('addConnectionStatus', STATS.level[level]);
-};
+const addConnectionStatus = (level, type, value) => {
+  const status = level !== -1 ? STATS.level[level] : 'normal';
+
+  makeCall('addConnectionStatus', status, type, value);
+}
 
 const fetchRoundTripTime = () => {
   const t0 = Date.now();
   makeCall('voidConnection').then(() => {
     const tf = Date.now();
     const rtt = tf - t0;
-
-    if (STATS_LOG && rtt > RTT_LOG_THRESHOLD) {
-      Logger.info(
-        {
-          logCode: 'rtt',
-          extraInfo: { rtt },
-        },
-        'Calculated round-trip time in milliseconds',
-      );
-    }
-
     const event = new CustomEvent('socketstats', { detail: { rtt } });
     window.dispatchEvent(event);
   });
@@ -263,7 +248,7 @@ const startRoundTripTime = () => {
 
   stopRoundTripTime();
 
-  roundTripTimeInterval = setInterval(fetchRoundTripTime, RTT_INTERVAL);
+  roundTripTimeInterval = setInterval(fetchRoundTripTime, STATS_INTERVAL);
 };
 
 const stopRoundTripTime = () => {
@@ -323,11 +308,9 @@ const notification = (level, intl) => {
 };
 
 export default {
-  addConnectionStatus,
   getConnectionStatus,
   getStats,
   getHelp,
-  getLevel,
   isEnabled,
   notification,
   startRoundTripTime,
diff --git a/bigbluebutton-html5/imports/utils/stats.js b/bigbluebutton-html5/imports/utils/stats.js
index c4f81d02c867ff69918a1cf8d992ff77103169fb..69733cacb83284e11d487c0d4f1d29101dd3df3d 100644
--- a/bigbluebutton-html5/imports/utils/stats.js
+++ b/bigbluebutton-html5/imports/utils/stats.js
@@ -2,9 +2,9 @@ import logger from '/imports/startup/client/logger';
 
 const STATS = Meteor.settings.public.stats;
 
-const STATS_LENGTH = STATS.length;
-const STATS_INTERVAL = STATS.interval;
-const STATS_LOG = STATS.log;
+// Probes done in an interval
+const PROBES = 5;
+const INTERVAL = STATS.interval / PROBES;
 
 const stop = callback => {
   logger.debug(
@@ -47,7 +47,7 @@ const isActive = conn => {
 const collect = (conn, callback) => {
   let stats = [];
 
-  const monitor = (conn, stats, iteration) => {
+  const monitor = (conn, stats) => {
     if (!isActive(conn)) return stop(callback);
 
     conn.getStats().then(results => {
@@ -77,13 +77,13 @@ const collect = (conn, callback) => {
         }
 
         stats.push(buildData(inboundRTP || remoteInboundRTP));
-        while (stats.length > STATS_LENGTH) stats.shift();
+        while (stats.length > PROBES) stats.shift();
 
         const interval = calculateInterval(stats);
-        callback(buildResult(interval, iteration));
+        callback(buildResult(interval));
       }
 
-      setTimeout(monitor, STATS_INTERVAL, conn, stats, iteration + 1);
+      setTimeout(monitor, INTERVAL, conn, stats);
     }).catch(error => {
       logger.debug(
         {
@@ -110,10 +110,9 @@ const buildData = inboundRTP => {
   };
 };
 
-const buildResult = (interval, iteration) => {
+const buildResult = (interval) => {
   const rate = calculateRate(interval.packets);
   return {
-    iteration: iteration,
     packets: {
       received: interval.packets.received,
       lost: interval.packets.lost
@@ -130,7 +129,6 @@ const buildResult = (interval, iteration) => {
 
 const clearResult = () => {
   return {
-    iteration: 0,
     packets: {
       received: 0,
       lost: 0
@@ -178,30 +176,6 @@ const calculateMOS = (rate) => {
   return 1 + (0.035) * rate + (0.000007) * rate * (rate - 60) * (100 - rate);
 };
 
-const logResult = (id, result) => {
-  if (!STATS_LOG) return null;
-
-  const {
-    iteration,
-    loss,
-    jitter
-  } = result;
-  // Avoiding messages flood
-  if (!iteration || iteration % STATS_LENGTH !== 0) return null;
-
-  const duration = STATS_LENGTH * STATS_INTERVAL / 1000;
-  logger.debug(
-    {
-      logCode: 'stats_monitor_result',
-      extraInfo: {
-        id,
-        result
-      }
-    },
-    `Stats result for the last ${duration} seconds: loss: ${loss}, jitter: ${jitter}.`
-  );
-};
-
 const monitorAudioConnection = conn => {
   if (!conn) return;
 
@@ -211,7 +185,6 @@ const monitorAudioConnection = conn => {
   );
 
   collect(conn, (result) => {
-    logResult('audio', result);
     const event = new CustomEvent('audiostats', { detail: result });
     window.dispatchEvent(event);
   });
diff --git a/bigbluebutton-html5/private/config/settings.yml b/bigbluebutton-html5/private/config/settings.yml
index 84ed767981d386885a3cf678040236ad787d9734..1957a4dccd175150516f20e49330c21b7436116b 100755
--- a/bigbluebutton-html5/private/config/settings.yml
+++ b/bigbluebutton-html5/private/config/settings.yml
@@ -433,8 +433,7 @@ public:
     sdpSemantics: 'unified-plan'
   stats:
     enabled: true
-    interval: 2000
-    length: 5
+    interval: 10000
     timeout: 30000
     log: false
     notification: