diff --git a/static_src/timer.js b/static_src/timer.js
index 9ddf460b4341c3a2bcc01d4a7a099cc58930ebf5..31525f5ba020bd33cad17e167cc51aca33d756c0 100644
--- a/static_src/timer.js
+++ b/static_src/timer.js
@@ -12,8 +12,8 @@ const enableInputs = () => {
     $("#pause_play,#minutes,#seconds,#update_time").prop("disabled", false)
 }
 
-const updateTimeText = (timer) => {
-    const timeValues = timer.getTimeValues()
+const updateTimeText = () => {
+    const timeValues = window.timer.getTimeValues()
 
     const hours = String(timeValues.minutes + timeValues.hours * 60 + timeValues.days * 1440).padStart(2, '0')
     const seconds = String(timeValues.seconds).padStart(2, '0')
@@ -21,15 +21,15 @@ const updateTimeText = (timer) => {
     $('#timer .timer-values').html(`${hours}:${seconds}`)
 }
 
-const assignEventListeners = (timer) => {
-    timer.addEventListener(
+const assignEventListeners = () => {
+    window.timer.addEventListener(
         'secondsUpdated',
         (event) => {
-            updateTimeText(timer)
+            updateTimeText()
         }
     )
 
-    timer.addEventListener(
+    window.timer.addEventListener(
         'targetAchieved',
         (event) => {
             $("#is_counting").prop("checked", false)
@@ -37,20 +37,41 @@ const assignEventListeners = (timer) => {
         }
     )
 
-    updateTimeText(timer)
+    updateTimeText()
 }
 
-const updateTimer = (timer, data, continuePlaying) => {
-    console.info(`Updating timer: ${JSON.stringify(data.sync_time)}`)
+const updateTimer = (data, options) => {
+    const timerValues = timer.getTimeValues()
+    const minutes = data["sync_time"]["minutes"]
+    const seconds = data["sync_time"]["seconds"]
+
+    if (window.timerIsRunning && (minutes === 0 && seconds <= 5)) {
+        // Don't update the time if we're running in the final 5 seconds.
+        return
+    }
+
+    if (options.minuteTolerance !== undefined && options.secondTolerance !== undefined) {
+        if (
+            (Math.abs(timerValues.minutes - minutes) < options.minuteTolerance)
+            && (Math.abs(timerValues.seconds - seconds) < options.secondTolerance)
+        ) {
+            // Don't annoy the user with time changes when there is only a 1-2 second difference.
+            return
+        } else {
+            console.warn("Timer out of sync!")
+        }
+    }
+
+    console.info(`Updating timer: ${minutes}:${seconds}, used to be ${timerValues.minutes}:${timerValues.seconds}`)
 
     window.startingTime = {
-        minutes: data["sync_time"]["minutes"],
-        seconds: data["sync_time"]["seconds"]
+        minutes: minutes,
+        seconds: seconds
     }
 
-    timer.removeAllEventListeners()
+    window.timer.removeAllEventListeners()
 
-    timer = new Timer({
+    window.timer = new Timer({
         countdown: true,
         startValues: {
             minutes: window.startingTime.minutes,
@@ -58,18 +79,16 @@ const updateTimer = (timer, data, continuePlaying) => {
         }
     })
 
-    assignEventListeners(timer)
+    assignEventListeners()
 
     if (window.timerIsRunning) {
-        timer.start()
+        window.timer.start()
     }
-
-    return timer
 }
 
-const syncTime = (timerSocket, timer) => {
+const syncTime = (timerSocket) => {
     timerSocket.send(JSON.stringify({
-        "sync": timer.getTimeValues()
+        "sync": window.timer.getTimeValues()
     }))
 }
 
@@ -80,8 +99,7 @@ $(window).ready(
         // --- BEGIN Timer ---
 
         window.timerIsRunning = false
-
-        let timer = new Timer({
+        window.timer = new Timer({
             countdown: true,
             startValues: {
                 minutes: window.startingTime.minutes,
@@ -118,25 +136,22 @@ $(window).ready(
                 const data = JSON.parse(event.data)
 
                 if ("sync_time" in data) {
-                    // Only update if there is any real difference.
-
-                    const remainingTime = timer.getTimeValues()
-
-                    if (
-                        data.sync_time.minutes !== remainingTime.minutes ||
-                        data.sync_time.seconds !== remainingTime.seconds
-                    ) {
-                        timer = updateTimer(timer, data)
-                    }
+                   updateTimer(
+                        data,
+                        {
+                            minuteTolerance: 1,
+                            secondTolerance: 2
+                        }
+                    )
                 }
 
                 if ("is_running" in data) {
                     if (data["is_running"]) {
                         // Reset if we are playing again.
-                        const remainingTime = timer.getTimeValues()
+                        const remainingTime = window.timer.getTimeValues()
 
                         if (remainingTime.seconds === 0 && remainingTime.minutes === 0) {
-                            timer = new Timer({
+                            window.timer = new Timer({
                                 countdown: true,
                                 startValues: {
                                     minutes: window.startingTime.minutes,
@@ -144,16 +159,16 @@ $(window).ready(
                                 }
                             })
 
-                            assignEventListeners(timer)
+                            assignEventListeners()
                         }
 
-                        timer.start()
+                        window.timer.start()
 
                         $("#is_counting").prop("checked", true)
                         $("#pause_play > .btn__body").html("⏸︎")
                         window.timerIsRunning = true
                     } else {
-                        timer.pause()
+                        window.timer.pause()
 
                         $("#is_counting").prop("checked", false)
                         $("#pause_play > .btn__body").html("⏵︎")
@@ -165,15 +180,23 @@ $(window).ready(
             let interval = null
 
             timerSocket.onopen = () => {
-                syncTime(timerSocket, timer)
+                syncTime(timerSocket)
 
-                interval = setInterval(syncTime, 5000, timerSocket, timer)
+                interval = setInterval(syncTime, 1000, timerSocket)
 
                 // --- BEGIN Controls ---
 
                 $("#pause_play").on(
                     "click",
                     (event) => {
+                        const timeValues = window.timer.getTimeValues()
+
+                        if (timeValues.minutes == 0 && timeValues.seconds == 0) {
+                            alertify.error("ProsĂ­m, nastav ÄŤas.")
+
+                            return
+                        }
+
                         $("#is_counting").click()
                     }
                 )
@@ -206,7 +229,7 @@ $(window).ready(
                     (event) => {
                         disableInputs()
 
-                        timer.pause()
+                        window.timer.pause()
 
                         let minutes = Number($("#minutes").val())
                         let seconds = Number($("#seconds").val())
@@ -231,14 +254,14 @@ $(window).ready(
 
                 alertify.error("Ztráta spojení, pokoušíme se o zpětné připojení.")
 
-                setTimeout(connectToSocket, 5000)
+                setTimeout(connectToSocket, 1000)
                 clearInterval(interval)
                 $("#is_counting,#pause_play,#update_time").unbind("click")
             }
         }
 
         connectToSocket()
-        assignEventListeners(timer)
+        assignEventListeners()
 
         // --- END Timer ---
     }
diff --git a/timer/consumers.py b/timer/consumers.py
index c750a381a37b918770c7abdf1ac79edef47167a5..0aac79dde09ca4f4452c41b01529d391411853fb 100644
--- a/timer/consumers.py
+++ b/timer/consumers.py
@@ -3,7 +3,7 @@ import datetime
 import json
 import threading
 import time
-from timeit import default_timer
+import timeit
 
 from asgiref.sync import sync_to_async
 from channels.generic.websocket import AsyncWebsocketConsumer
@@ -12,16 +12,20 @@ running_timer_threads = []
 
 
 def tick_timer(timer, iteration: int, total_seconds: int) -> None:
+    print("ticking", timer)
+
     second_compensation = 0
 
-    start_time = default_timer()
+    start_time = timeit.default_timer()
 
     timer.refresh_from_db()
 
-    end_time = default_timer()
+    end_time = timeit.default_timer()
     second_compensation = end_time - start_time
 
     while not timer.is_running:
+        print("waiting to run ...")
+
         time.sleep(0.05)
 
         timer.refresh_from_db()
@@ -32,15 +36,30 @@ def tick_timer(timer, iteration: int, total_seconds: int) -> None:
             running_timer_threads.remove(timer.id)
             return
 
-    start_time = default_timer()
+        if timer.minutes == 0 and timer.seconds == 0:
+            # Stop the thread if we have reached the end
 
-    if iteration != timer.iteration:
-        # Stop the thread if there is a new timer
+            running_timer_threads.remove(timer.id)
+            return
+
+    start_time = timeit.default_timer()
+
+    print(timer.minutes, timer.seconds)
+
+    if timer.minutes == 0 and timer.seconds == 0:
+        # Stop the thread if we have reached the end
+
+        timer.is_running = False
+        timer.save()
 
         running_timer_threads.remove(timer.id)
+
         return
 
-    if total_seconds < 1:
+    if iteration != timer.iteration:
+        # Stop the thread if there is a new timer
+
+        running_timer_threads.remove(timer.id)
         return
 
     total_seconds -= 1
@@ -53,11 +72,11 @@ def tick_timer(timer, iteration: int, total_seconds: int) -> None:
 
     timer.save()
 
-    end_time = default_timer()
+    end_time = timeit.default_timer()
     second_compensation += end_time - start_time
 
     threading.Timer(
-        interval=1 - second_compensation,
+        interval=max(0, 1 - second_compensation),
         function=tick_timer,
         args=(
             timer,
@@ -118,6 +137,8 @@ class TimerConsumer(AsyncWebsocketConsumer):
         ).start()
 
     async def receive(self, text_data: str) -> None:
+        await sync_to_async(self.timer.refresh_from_db)()
+
         json_data = json.loads(text_data)
 
         response = {}
@@ -141,8 +162,6 @@ class TimerConsumer(AsyncWebsocketConsumer):
         if reset_timer or (self.timer.id not in running_timer_threads and self.timer.is_running):
             await self.run_timer()
 
-        await sync_to_async(self.timer.refresh_from_db)()
-
         response.update(
             {
                 "sync_time": {