Article

A session that survives a refresh

Refresh the page and most browser timers forget you. Untimer holds on, because a session is one moment written on a server and every screen shows how far away that moment is.

The timer Untimer replaces was a browser tab. It worked well until you touched it. Refresh the page and the session was gone. Leave the page and come back, gone. Open it on a phone, and the phone put the tab to sleep and the countdown stopped. The founder used that timer every day for years and lived with all three problems.

The cause was where the time lived. That timer kept “seconds remaining” in the memory of the page and counted it down in a loop. That is the obvious way to build a timer, and it breaks easily. Page memory disappears. Loops in background tabs get slowed down. The computer’s clock moves when the person changes it, when the operating system syncs it, or when a laptop lid closes for an hour.

Untimer is built the other way round. This article explains what that means for you.

A session is a moment

When you let go of the glass, the server writes down one fact: this session ends at a particular instant. 10:25:00 and some milliseconds, in the server’s own time. It writes a few other facts beside it. When it started, what it is for if you said, and how long it was planned to be. Then it stops. The server holds a moment and leaves the counting alone.

Every screen that shows the countdown does the same small sum. It takes the end moment, subtracts the time now, and draws the answer as minutes and seconds. It repeats that sum on every repaint and throws the answer away each time. What exists is a moment, and a distance to it.

This is why a refresh leaves the session where it was. The page loads and asks the server what is happening. It is told the end moment, and it draws the distance. The page had held only that.

The app anchors to the server’s clock

If the screen used your computer’s clock, a clock that runs a minute fast would show a session a minute short, and a clock that jumped during a sync would make the sand lurch. So every answer from the server carries the server’s own time, and the app anchors to that. It notes the server’s time and its own monotonic counter at the moment the answer arrived. From then on it measures elapsed time from that counter, which your machine leaves alone. The wall clock can be wrong by an hour and the sand is still right.

When a laptop wakes from sleep the counter is stale, so the app asks again. It also asks again when the tab becomes visible, when the window gets focus and when the network comes back. Each of those is one small request, and each one re anchors the clock. Using the app keeps it right.

One session, and the database makes sure

One session runs at a time. A unique rule on the table holds the database to a single live session per person. If your phone and your laptop race to start one, exactly one wins, and the other is told what is already running and adopts it. Two devices stay in agreement about which session is live, because the database has room for one answer.

Every change you make carries a small random ticket as well. If your connection drops halfway through pressing Reset and the app retries, the server recognises the ticket and applies the reset once. Retrying is always safe, and it happens out of sight.

It finishes on its own

What happens when the session reaches zero and every screen is away? The tab is closed, the laptop is shut, the phone is in a bag.

The end moment is already written down, so the session can finish on its own. The next time anything asks the server anything, the server first looks for sessions whose end moment has passed and records them as complete, ended at the moment they were due. A session that finished at 10:25 while you were in a meeting is recorded as finished at 10:25 when you open the app at 14:00. Your history comes out right with every device asleep.

The completion is the server’s to write. When the sand runs out on screen, the app asks the server to confirm, and the server hands back the record it just wrote. The line in the box at the end of a session comes from that record.

The bell is placed on the clock

There is one more place a timer usually counts, and it is the sound at the end. The obvious way is to check every second whether it is time to ring. In a tab you have hidden behind your work, browsers slow those checks to once a second, and after a few minutes to once a minute. A bell that rings a minute late is a bell you stop trusting.

So Untimer places the bell instead. The browser’s audio system keeps its own clock, and that clock keeps going in a hidden tab. When a session starts, the sound is placed on that clock at the exact moment the session ends and then left alone. Stopping takes it back. Resetting places it again. When the moment arrives it sounds, whatever the tab is doing.

There is one limit, and it is the browser’s own rule. A page makes a sound only once you have touched it. A page refreshed mid session has to be clicked or typed in before the bell can be placed. After that it is exact.

What this lets Untimer promise

Start a session at your desk and open the app on your phone: the same sand, at the same place. Refresh a hundred times. Close the tab and open it an hour later and find the session completed at the minute it was due. Let the laptop sleep. Let the clock be wrong.

Ten years of sessions keep it just as quick. Every screen reads a page at a time instead of your whole history. Your days come one page at a time, the insights come from daily totals kept as each session ends, and the milestones are checked where a session ends. The timer the founder replaced did the opposite, and it got slower every month.

All of this sits out of sight, and that is the point. A timer that holds on to you is a timer you stop thinking about, so you can think about something else.

Try it

The glass is waiting, and it asks for an email and a password.

Open Untimer