SelfSync

45°54′01″N 6°10′58″EGarmin export DuckDB

Your Garmin history,
as a local database.

Every activity, lap and heartbeat from your Garmin export, in one .duckdb file you keep. Query it with SQL, Python, R, or hand it to your AI assistant.

Launch price€19 instead of €29, once. No account, no subscription. Payment by Stripe.

duckdb db.duckdb
D SELECT z_sport AS sport,
         count(*) AS sessions,
         round(sum(z_total_distance) / 1000, 1) AS km
  FROM z_fit_session_mesgs
  GROUP BY ALL
  ORDER BY km DESC;
sportvarcharsessionsint64kmdouble
cycling2389120.0
running6125841.0
hiking31418.0
swimming97212.0
Sample output. Yours will have more kilometres.

How it works

  1. 01

    Ask Garmin for your data

    Request an export from Garmin's data management page. Garmin emails you a download link, usually within a few hours, sometimes a few days.

  2. 02

    Paste the link here

    Copy the address behind the download button in Garmin's email and paste it above. The link expires after a few days, so don't let it sit in your inbox.

  3. 03

    Get your .duckdb file

    We unzip the export, decode every FIT file and load it into a single DuckDB database. You get an email when it's ready.

What you can do with it

A few ideas to start with. Each one is a query away, or simply a question to your AI assistant.

  • Map every run and trail

    Draw every GPS track you've ever recorded on one map. Your favourite loops, and the valleys you've never explored.

    z_fit_record_mesgs
  • Follow your heart rate

    Watch your average heart rate drift down as your fitness builds, season after season.

    z_fit_session_mesgs
  • Chart your personal records

    Track your best 5 km, 10 km or half-marathon times and see exactly when you broke through.

    z_fit_session_mesgs
  • See every training day

    Every workout on a calendar. Streaks, rest weeks, and that suspicious gap in November.

    z_fit_session_mesgs
  • Count your Everests

    Add up every metre of climbing since your first watch. How many Everests is that?

    z_fit_session_mesgs
  • Measure your efficiency

    Plot speed against heart rate to check you go faster for the same effort than last year.

    z_fit_record_mesgs
  • Balance your intensity

    Time spent in each heart-rate zone, week after week. Are your easy days really easy?

    z_fit_session_mesgs
  • Draw your power curve

    Your best power over 5 seconds, 1 minute, 20 minutes… if you ride with a power meter.

    z_fit_record_mesgs
  • Track your swim pace

    Pace per 100 m and strokes, length after length, pool session after pool session.

    z_fit_length_mesgs
  • Know your habits

    Early bird or lunch-break rider? See when, and on which days, you actually train.

    z_fit_session_mesgs

Ask the questions no product manager at Strava or Garmin ever thought you'd ask.

What's inside

One table per FIT message type, linked back to the file it came from. Every column is commented, enum values included, so your AI assistant knows what every field means without guessing.

  • filesone row per FIT file in your export
  • z_fit_session_mesgsone row per activity: sport, distance, time, HR, power…
  • z_fit_lap_mesgsevery lap and interval
  • z_fit_record_mesgssecond-by-second GPS, heart rate, cadence, altitude
  • z_fit_device_info_mesgswatches, sensors, firmware versions
  • z_fit_…_mesgsevery other FIT message type

Why DuckDB

DuckDB is an analytical database that runs inside whatever tool you use, with no server to install. Think SQLite, but designed to crunch numbers across millions of rows. That's what training data is.

Open source
MIT licensed, developed in the open by the DuckDB Foundation and a large community.
Free
No licence, no server, no cloud account. Install it in seconds and it costs nothing, forever.
Built for analytics
A columnar engine made for aggregations: summing years of laps or millions of GPS points is exactly its job.
One file, everywhere
The whole database is one file. Copy it, back it up, open it from the CLI, Python, R, Node or the browser.
.fit.fit.fit.fit.fitdb.duckdbsportstart_timedistanceheart_rate⋮ millions of rowssum(distance) only reads this column

Open it with whatever you like

SQL

$ duckdb db.duckdb
D DESCRIBE z_fit_lap_mesgs;

Python

import duckdb
con = duckdb.connect("db.duckdb")
con.sql("FROM z_fit_record_mesgs").df()

R

library(duckdb)
con <- dbConnect(duckdb(), "db.duckdb")
dbGetQuery(con, "FROM z_fit_lap_mesgs")

Your AI assistant, via MCP

"How has my easy-run pace
 changed since 2021?"

Questions

What ends up in the database?

Everything Garmin stores as FIT files: activities, laps, per-second records, devices and the rest. If it's in a FIT file in your export, it's in the database.

Is it only for developers?

Absolutely not. You don't need to write a single line of SQL. Plug the file into an AI assistant like Claude or ChatGPT and ask your questions in plain English: "What was my longest ride last year?", "Am I running faster than in 2022?". Spreadsheet and dashboard tools can open it too. No technical skills required to dig into your own data.

How long does it take?

It depends on how many years of training you have. You get an estimate right after paying, and an email when the file is ready.

Why a one-time payment?

Turning years of FIT files into a database takes real compute: downloading the export, decoding every file, building and storing the database. The payment covers that work. You pay once per export, with no account and no subscription.

My link is rejected.

Garmin's links expire after a few days. Request a new export from Garmin and paste the new link.

What happens to my data?

Your export is only used to build your database. Once you've downloaded it, everything is deleted from our servers: the Garmin export and the database itself.

Has this thing been vibecoded?

No. It was made with the help of AI, sure, but everything is handcrafted and carefully reviewed.

Why would I pay since I can do it myself with AI?

Sure, no objection. Feel free to do it yourself and share the token cost afterward. We highly recommend saving those tokens for the analytical step instead. ;)

Your training data. Finally yours.