diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
index 19ef3291256f90a288b721c9292db48709024325..c08cb4ad4a7523d93e95ec91ed77d73ee70fb8a7 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
@@ -26,6 +26,13 @@ case class MonitorNumberOfUsersInternalMsg(meetingID: String) extends InMessage
  */
 case class SendTimeRemainingAuditInternalMsg(meetingId: String) extends InMessage
 
+/**
+ * Parent message sent to breakout rooms to trigger updating clients of meeting time remaining.
+ * @param meetingId
+ * @param timeLeftInSec
+ */
+case class SendBreakoutTimeRemainingInternalMsg(meetingId: String, timeLeftInSec: Long) extends InMessage
+
 case class SendRecordingTimerInternalMsg(meetingId: String) extends InMessage
 
 case class ExtendMeetingDuration(meetingId: String, userId: String) extends InMessage
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala
new file mode 100755
index 0000000000000000000000000000000000000000..c3decbbf73fc59bb3fdfcdfae7cacf40061944d1
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala
@@ -0,0 +1,15 @@
+package org.bigbluebutton.core.apps.breakout
+
+import org.bigbluebutton.core.api.SendBreakoutTimeRemainingInternalMsg
+import org.bigbluebutton.core.running.{LiveMeeting, OutMsgRouter}
+import org.bigbluebutton.core2.message.senders.MsgBuilder
+
+trait SendBreakoutTimeRemainingInternalMsgHdlr {
+  val liveMeeting: LiveMeeting
+  val outGW: OutMsgRouter
+
+  def handleSendBreakoutTimeRemainingInternalMsg(msg: SendBreakoutTimeRemainingInternalMsg): Unit = {
+    val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, msg.timeLeftInSec.toInt)
+    outGW.send(event)
+  }
+}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
index adcea570d7c4eeaafc0fbc130969a36b66884e35..a26f62c5419a7040c1ca9d40eedcaa5bd3b7cf7d 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
@@ -86,6 +86,7 @@ class MeetingActor(
   with DestroyMeetingSysCmdMsgHdlr
   with SendTimeRemainingUpdateHdlr
   with SendBreakoutTimeRemainingMsgHdlr
+  with SendBreakoutTimeRemainingInternalMsgHdlr
   with ChangeLockSettingsInMeetingCmdMsgHdlr
   with SyncGetMeetingInfoRespMsgHdlr
   with ClientToServerLatencyTracerMsgHdlr
@@ -238,16 +239,23 @@ class MeetingActor(
 
     case msg: ExtendMeetingDuration           => handleExtendMeetingDuration(msg)
     case msg: SendTimeRemainingAuditInternalMsg =>
-      state = handleSendTimeRemainingUpdate(msg, state)
+      if (!liveMeeting.props.meetingProp.isBreakout) {
+        // Update users of meeting remaining time.
+        state = handleSendTimeRemainingUpdate(msg, state)
+      }
+
+      // Update breakout rooms of remaining time
       state = handleSendBreakoutTimeRemainingMsg(msg, state)
     case msg: BreakoutRoomCreatedInternalMsg     => state = handleBreakoutRoomCreatedInternalMsg(msg, state)
     case msg: SendBreakoutUsersAuditInternalMsg  => handleSendBreakoutUsersUpdateInternalMsg(msg)
     case msg: BreakoutRoomUsersUpdateInternalMsg => state = handleBreakoutRoomUsersUpdateInternalMsg(msg, state)
     case msg: EndBreakoutRoomInternalMsg         => handleEndBreakoutRoomInternalMsg(msg)
     case msg: BreakoutRoomEndedInternalMsg       => state = handleBreakoutRoomEndedInternalMsg(msg, state)
+    case msg: SendBreakoutTimeRemainingInternalMsg =>
+      handleSendBreakoutTimeRemainingInternalMsg(msg)
 
     // Screenshare
-    case msg: DeskShareGetDeskShareInfoRequest   => handleDeskShareGetDeskShareInfoRequest(msg)
+    case msg: DeskShareGetDeskShareInfoRequest => handleDeskShareGetDeskShareInfoRequest(msg)
 
     case msg: SendRecordingTimerInternalMsg =>
       state = usersApp.handleSendRecordingTimerInternalMsg(msg, state)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala
index 7a428f058938575f06f0c0582a47ec2f4689ae9f..55116e21836cbbbfb986c17bfe4131669d9550ef 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala
@@ -1,30 +1,37 @@
 package org.bigbluebutton.core2.message.handlers
 
 import org.bigbluebutton.common2.msgs._
-import org.bigbluebutton.core.api.SendTimeRemainingAuditInternalMsg
+import org.bigbluebutton.core.api.{ EndBreakoutRoomInternalMsg, SendBreakoutTimeRemainingInternalMsg, SendTimeRemainingAuditInternalMsg }
+import org.bigbluebutton.core.bus.BigBlueButtonEvent
 import org.bigbluebutton.core.domain.MeetingState2x
-import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
+import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter }
 import org.bigbluebutton.core.util.TimeUtil
 
 trait SendBreakoutTimeRemainingMsgHdlr {
+  this: MeetingActor =>
+
   val liveMeeting: LiveMeeting
   val outGW: OutMsgRouter
 
   def handleSendBreakoutTimeRemainingMsg(msg: SendTimeRemainingAuditInternalMsg, state: MeetingState2x): MeetingState2x = {
-
     for {
       model <- state.breakout
       startedOn <- model.startedOn
     } yield {
-      if (!liveMeeting.props.meetingProp.isBreakout) {
-
-        val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + TimeUtil.minutesToSeconds(model.durationInMinutes)
-        val timeRemaining = endMeetingTime - TimeUtil.millisToSeconds(System.currentTimeMillis())
+      val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + TimeUtil.minutesToSeconds(model.durationInMinutes)
+      val timeRemaining = endMeetingTime - TimeUtil.millisToSeconds(System.currentTimeMillis())
 
+      if (!liveMeeting.props.meetingProp.isBreakout) {
+        // Notify parent meeting users of breakout rooms time remaining
         val event = buildBreakoutRoomsTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt)
-
         outGW.send(event)
       }
+
+      // Tell all breakout rooms of time remaining so they can notify their users.
+      // This syncs all rooms about time remaining.
+      model.rooms.values.foreach { room =>
+        eventBus.publish(BigBlueButtonEvent(room.id, SendBreakoutTimeRemainingInternalMsg(props.breakoutProps.parentId, timeRemaining.toInt)))
+      }
     }
 
     state
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala
index b79f000b77c2acb44ab782b844c13e9068b1be7d..e17880b90cf7315b0369b9aa94f7bbd6e7950207 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala
@@ -1,10 +1,10 @@
 package org.bigbluebutton.core2.message.handlers
 
-import org.bigbluebutton.common2.msgs._
 import org.bigbluebutton.core.api.SendTimeRemainingAuditInternalMsg
-import org.bigbluebutton.core.domain.{ MeetingState2x }
-import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter }
+import org.bigbluebutton.core.domain.MeetingState2x
+import org.bigbluebutton.core.running.{BaseMeetingActor, LiveMeeting, OutMsgRouter}
 import org.bigbluebutton.core.util.TimeUtil
+import org.bigbluebutton.core2.message.senders.MsgBuilder
 
 trait SendTimeRemainingUpdateHdlr {
   this: BaseMeetingActor =>
@@ -13,26 +13,14 @@ trait SendTimeRemainingUpdateHdlr {
   val outGW: OutMsgRouter
 
   def handleSendTimeRemainingUpdate(msg: SendTimeRemainingAuditInternalMsg, state: MeetingState2x): MeetingState2x = {
-
     if (state.expiryTracker.durationInMs > 0) {
       val endMeetingTime = state.expiryTracker.endMeetingTime()
       val timeRemaining = TimeUtil.millisToSeconds(endMeetingTime - TimeUtil.timeNowInMs())
 
-      def buildMeetingTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
-        val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
-        val envelope = BbbCoreEnvelope(MeetingTimeRemainingUpdateEvtMsg.NAME, routing)
-        val body = MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec)
-        val header = BbbClientMsgHeader(MeetingTimeRemainingUpdateEvtMsg.NAME, meetingId, "not-used")
-        val event = MeetingTimeRemainingUpdateEvtMsg(header, body)
-
-        BbbCommonEnvCoreMsg(envelope, event)
-      }
-
       if (timeRemaining > 0) {
-        val event = buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt)
+        val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt)
         outGW.send(event)
       }
-
     }
 
     state
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
index 1104852f6d5247675df4c599fb8968b8fc4f6600..93c7a550caa8d17decda5a99c728d8722d0dae5c 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
@@ -494,4 +494,14 @@ object MsgBuilder {
 
     BbbCommonEnvCoreMsg(envelope, event)
   }
+
+  def buildMeetingTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
+    val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
+    val envelope = BbbCoreEnvelope(MeetingTimeRemainingUpdateEvtMsg.NAME, routing)
+    val body = MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec)
+    val header = BbbClientMsgHeader(MeetingTimeRemainingUpdateEvtMsg.NAME, meetingId, "not-used")
+    val event = MeetingTimeRemainingUpdateEvtMsg(header, body)
+
+    BbbCommonEnvCoreMsg(envelope, event)
+  }
 }