Sound familiar?
Garmin watches record every activity, but if you also use a Karoo cycling computer, Hevy for gym logging or another app that syncs to Strava, you end up with duplicates. Garava blocks the Garmin versions of activities you have a better source for.
Garmin watch + Karoo. You wear a Garmin for training load and ride with a Karoo. Both record the ride. The Karoo has your power meter and richer cycling data -- that's what you want on Strava. But Garmin pushes its version too and you get a duplicate (or Strava picks the wrong one).
Garmin watch + Hevy. You wear a Garmin during gym sessions for training load but log sets and reps in Hevy. Hevy syncs detailed workout data to Strava. Garmin also syncs a generic "Strength Training" entry with nothing but heart rate. Two entries, one is useless.
The fix is the same. Garava replaces Garmin's native Strava sync and blocks the activity types you have a better source for. Everything else still syncs automatically.
How it works
Garava runs in the background on macOS, Linux or a server, syncing on the quarter hour (:00, :15, :30, :45). It fetches activities from Garmin Connect, checks them against your blocklist, downloads original FIT files for allowed activities and uploads them to Strava. If your machine is asleep, it picks up when it wakes.
Fetch
Pulls your latest activities from Garmin Connect. Syncs on the quarter hour — :00, :15, :30, :45.
Filter
Checks each activity against your blocklist. Block activity types you have a better source for -- cycling (Karoo handles it), gym (Hevy handles it), whatever applies to your setup.
Sync
Downloads the original FIT file and uploads it to Strava. Heart rate, power, GPS — everything comes through.
What else it does
Garava tracks every processed activity in a local SQLite database to prevent duplicates, automatically refreshes expired Garmin and Strava tokens, and supports deployment via launchd, systemd, cron or Docker.
You Pick the Blocklist
One environment variable, comma-separated list. Block cycling types if you ride with a Karoo, gym types if you log with Hevy, or whatever fits your setup.
Original FIT Files
Uploads the actual FIT file from Garmin, not a summary. Heart rate, power, GPS — it all comes through.
No Duplicates
Tracks every activity in a local database. If it already synced something, it won't sync it again.
Handles Its Own Errors
If a token expires or an upload fails, it sorts itself out. Failed activities get retried next cycle.
Run However You Want
One-off sync or continuous polling. Works with launchd, systemd, cron or Docker.
Docker If You Want It
Dockerfile and docker-compose included if you want to run it on a home server or VPS.
Get started
Garava requires Python 3.9+, a Strava API application and your Garmin Connect credentials. Before installing, disable Garmin's native Strava sync — Garava replaces it entirely, continuing to sync runs, hikes, swims and everything not on your blocklist.