You avoid duplicates by checking, before every upload, whether the destination already holds a ride of the same sport that starts within two minutes and lasts and measures almost the same. Nabe does exactly that against your Garmin Connect list, and if it finds a match it skips the upload with the reason “Garmin already has this ride”.
The usual case is a Wahoo on the bars and a Garmin watch on your wrist during the same ride. Both devices record, both send the ride to their own service, and a tool that blindly copies Wahoo rides to Garmin hands you the same ride twice.
When are two recordings the same ride?
Nabe treats two activities as the same ride when all of these hold:
| Value | Tolerance |
|---|---|
| Sport | identical |
| Start time | within ±120 seconds |
| Duration | within ±2 % |
| Distance | within ±2 % or ±500 m, whichever is larger |
If one side has no distance, for example an indoor workout without a speed sensor, the sport and start time rules stay and the duration may differ by ±2 % or ±60 seconds, whichever is larger. A ride with no distance is never uploaded while such a match exists at the destination.
Why ranges and not a rounded fingerprint?
A rounded key breaks exactly at its edges. Round the start time to the minute and 17:00:59 and 17:01:01 land in different buckets, two seconds apart. Round the distance to 0.1 km and 51.749 km and 51.751 km do the same. These are not rare cases, because a bike computer and a watch start and stop at slightly different moments and measure distance with different sensors. A range comparison has no edges of that kind: it asks whether the difference is small, not whether two rounded numbers are equal.
Which duration does Nabe compare?
Every duration it has, on both sides. Services measure time differently: Strava’s interface gives moving time and elapsed time, and a FIT session from Garmin carries timer time, elapsed time and moving time. Nabe counts two activities as matching when any time from one side lies within ±2 % of any time from the other.
We learned this on our own history. On 587 real rides, a comparison that used only one kind of time per side declared 11 rides missing from Garmin that were in fact there, about 1.9 %. Comparing all available times removed those false alarms.
What happens with very short entries?
Activities shorter than 2 minutes stay visible in the history but never count as missing and are never uploaded, not even when you pick older activities by hand.
What does “skipped” look like in practice?
On 13 September 2026 we imported a Wahoo ride that Garmin Connect already had. Nabe loaded Garmin’s list once (20 entries covering 25 July to 11 September), found the ride within the tolerances above and marked the transfer as skipped with the reason “Garmin already has this ride”. The app’s network log showed zero upload requests for the whole run.
What if the same ride comes from two of my sources?
Then it is one activity with two sources. If your Wahoo ride also reaches Strava, Nabe recognises both as the same ride with the rule above, shows it once with both sources and transfers it only once, from the original recording: the recording from the device or its own service, such as Wahoo, goes before a copy, such as Strava. If a ride exists only as a copy, the copy is sent.
Does Nabe check again right before uploading?
Yes. Before every upload to Garmin, Nabe runs a fresh duplicate check against Garmin. When you send an older ride by hand, Nabe asks Garmin about the day of that ride and does not upload if Garmin has it or holds an activity of the same sport starting within ±120 seconds. Because this check comes last, an interrupted transfer ends up waiting, never doubled.