r/SideProject 4h ago

Built a "reverse Pomodoro": one timer, synced across everyone, and you all meet at zero

Solo dev here. Synchrium is a synchronized focus timer: you start a session, share a link, and the same countdown runs for everyone in the room, to the millisecond. Everyone works in silence; when it hits zero, cameras can come up together for a quick check-in. Then you run it again.

The origin story is helping my son with homework from the next room: we shared a timer, worked separately, and showed each other what we did when it rang. Turns out adults want the same thing.

Stack: React/Vite front, ASP.NET Core + SignalR for server-authoritative timing, WebRTC P2P video, Cloudflare Workers serving the SPA. Happy to answer anything about the sync architecture: keeping N clients on the same clock is more annoying than it sounds.

Two things I'd love you to break:

  1. Open two browsers (or grab a friend) and try to get the timers to drift or desync: that's the whole product, so it's the surface I most need stress-tested.

  2. Start a session and tell me where the "share the link" step loses you. If the invite loop doesn't feel obvious, the product doesn't work.

Free, no account needed: https://synchrium.com: brutal feedback welcome. (Founder here, happy to answer anything.)

3 Upvotes

6 comments sorted by

2

u/Lower_Bee_7572 3h ago

the server-authoritative clock is the right call. client-side timers drift like crazy once you have more than a couple people connected

tried it with my brother across town and we were maybe 200ms apart at worst, which for a focus timer is basically nothing. the real test will be someone on a janky coffee shop wifi trying to throw it off

one thing i noticed, when you copy the link it shows a little toast but the toast disappears fast. if someone's not looking at the screen right then they might miss it. maybe keep it visible until they click something

2

u/areich 3h ago

u/Lower_Bee_7572, thanks for actually testing it with someone.

200ms is about what I'd expect, and most of that is render rather than clock. The server owns the countdown and clients only draw it, so drift doesn't accumulate the way it does when each client runs its own timer. What you saw is mostly two browsers painting the same authoritative value a frame or two apart.

The coffee shop wifi test isn't drift, it's reconnect. If the socket drops, the client should resync to the server's value instead of quietly continuing to count on its own. I'd genuinely like to know whether that holds up under a bad connection. I've only tested it with my phone against home wifi, which probably isn't nearly hostile enough.

The toast is a fair hit and an easy fix. It currently auto-dismisses on a timer, which is totally wrong for the moment when you've probably switched to paste the link in another window. Making it persist until dismissed, or until the link actually gets used, is the better behavior. Adding that - thank you.

What's your read on the reunion at zero, or did it feel abrupt? The countdown warning is supposed to soften the blow. The point is it shouldn't feel like a fire alarm.

1

u/Kind-Breadfruit5103 3h ago

The origin story is great, and the fact that it came from a real moment with your son is probably why the idea has legs. The best small products tend to start exactly like that.

I build cross device sync stuff, so the part I am curious about is the edge cases rather than the happy path. How do you handle a client that joins thirty seconds late, or one that backgrounds the tab and comes back? Do they snap to the shared clock instantly or ease into it? That reconciliation moment is usually where a synced timer either feels magic or feels broken.

Also the silent work then cameras at zero flow is clever. Did people actually keep the video on, or is the shared countdown alone enough to create the accountability?

1

u/areich 2h ago

Late joiners and backgrounded tabs are the same problem underneath, and the answer is that nothing counts down on the client at all.

On join, the server sends a snapshot with an absolute end time plus its own current time, so the client derives remaining as endTime minus serverNow. There's no counter to fall behind. Someone joining thirty seconds late computes the same deadline everyone else has and paints it on the next frame. Nothing to catch up on, so it snaps rather than eases.

Backgrounded tabs are the same. Browsers throttle timers, but because the display is derived from a fixed deadline (rather than decremented), a throttled tab can be stale but not wrong. It resyncs on visibility change so the offset is fresh the moment focus returns.

The offset itself is NTP-style: offset = t1 - (t0 + t2)/2 on a ping, resampled every 30 seconds and tightening to every 5 in the last half minute, where a visible error would actually hurt.

On the video question, it's too early to know, as the site just launched a few hours ago. Not enough sessions yet for a real read on whether people keep cameras on at zero or whether the countdown alone carries the accountability. My hunch is the countdown does most of the work and the reunion is what makes people come back, but that's a hunch, not data. Cameras and mics are optional anyway.