GarminDB: Garmin Connect data in a local SQLite database
Download and parse data from Garmin Connect or a Garmin watch, FitBit CSV, and MS Health CSV files into and analyze data in Sqlite serverless databases with Jupyter notebooks.
At a glance
- What is it?
- GarminDB downloads Garmin Connect daily monitoring, sleep, weight and activity files and parses them into SQLite databases for Jupyter analysis. It is a command line tool for people who want their health history on their own disk, and its cost is a config file, a rebuild step and a GPL-2.0 licence.
- Who is it for?
- Adopt GarminDB if you want your Garmin Connect history in SQLite and you are willing to keep a JSON config file and a local data directory in sync with the downloader. Do not adopt it if you need a supported product, a web interface, or a schema that will not change under you.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 13 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What GarminDB does with your Garmin Connect history
Garmin Connect shows you charts. It does not hand you a queryable copy of the numbers behind them. GarminDB is a set of Python scripts that log in to Garmin Connect, download the daily monitoring files (all day heart rate, activity, climb and descend, stress, intensity minutes), the sleep, weight and resting heart rate records, and the activity files, then parse all of it into SQLite databases. SQLite needs no server, so the whole thing is a few files on your disk plus a Python environment.
The audience is narrow and specific. You already own a Garmin watch or have an export from FitBit or MS Health, you are comfortable in a terminal, and you want to write SQL or open a Jupyter notebook against your own data rather than click through a vendor dashboard. The README points at SQLite Studio, HeidiSQL and DB Browser for SQLite for browsing, and the repository ships a Jupyter directory with notebooks. If you do not want to touch a terminal, this is the wrong tool, and no amount of notebook polish changes that.
How the download, parse and analyze pipeline is wired
The flow has three stages that the command line exposes as flags: --download, --import and --analyze. Download fetches from Garmin Connect. Import parses the downloaded files into the databases. Analyze computes the daily, weekly, monthly and yearly summary tables. The README's one-shot command runs all three over every data type, and adding --latest restricts the run to data after what is already in the database.
What makes the design defensible is that the downloaded JSON and FIT files are retained. The README states that the DB can be regenerated without connecting to or redownloading from Garmin Connect. That matters because the schema does change: the README warns that after updating the code you may get a DB version exception, and the fix is to rebuild the databases from the previously downloaded files. So the download is the expensive, rate-limited, credential-bearing step, and everything after it is local and repeatable. The scripts also create default views in the databases, and the config has a course_views setting whose steps element lists course ids for which per-course views are generated, so you can compare all activities from the same course.
Two other pieces sit on top. Plugins extend which data types get processed and stored, and the project maintains a separate plugin repository for third-party Connect IQ apps and data fields. The Makefile automates the same pipeline for source installs and handles the ordering between download and database generation.
Installing GarminDB with pip and running your first import
Releases are on PyPI and require Python 3.x. Install with pip:
pip install garmindbBefore the first run you need a config file. The README says to copy GarminConnectConfig.json.example to ~/.GarminDb/GarminConnectConfig.json, then edit it to add your Garmin Connect username and password and to adjust the start dates so they match the dates of your data in Garmin Connect. The example file is in the garmindb directory of the repository. Nothing downloads until those start dates are set, because they define the window the scripts walk.
The first real run downloads everything in that window and builds the databases:
garmindb_cli.py --all --download --import --analyzeAfter that, update incrementally with --latest, which only pulls data after what is already stored:
garmindb_cli.py --all --download --import --analyze --latestThe README recommends running garmindb_cli.py --backup occasionally to back up the database files, and upgrading with pip install --upgrade garmindb. When a run finishes, a summary is written to stats.txt with the date ranges covered and the record counts for daily monitoring, activities, sleep, resting heart rate and weight. Read that file. It is how you tell whether the download actually captured the period you asked for; if the ranges look short, adjust the dates in GarminConnectConfig.json and download again.
Building from source and the make targets
The source route is documented separately and is not a wrapper around the pip route. Clone the repository using the SSH clone method, because the README states the submodules require SSH and not HTTPS. Then:
make setup
make create_dbsmake setup prepares the scripts, and make create_dbs fetches and processes your data once. After that the README says you keep everything current by periodically running a single command:
makeThe Makefile defines a wider set of targets than the README names: setup_repo, setup_install, download_all, build_dbs, rebuild_dbs and update_dbs among them, with the master target all pointing at update_dbs. It also creates a virtual environment under .venv and resolves the CLI to .venv/bin/garmindb_cli.py, so the source install and the pip install do not share an environment. If you go this route, the Makefile is the interface you will actually maintain, and it is the file to read before you change anything about how data is fetched.
Where GarminDB breaks: schema churn, Garmin's side, and platform gaps
The most concrete failure mode is documented in the README itself. A code update can raise a DB version exception, which means the schema changed and the databases must be rebuilt with garmindb_cli.py --rebuild_db. The rebuild regenerates from previously downloaded files, so no data is lost, but any SQL of your own that references the old schema needs revisiting. If you build dashboards on top of these tables, budget for that.
The second dependency is Garmin Connect itself. Everything starts with a username and password in a config file and a login against a service this project does not control. The downloader relies on garminconnect, pinned in requirements.txt, and when that service or its endpoints change, the download step is what stops. The import and analyze steps keep working on data you already have, which is the saving grace of retaining the raw files.
The third limitation is stated plainly: the scripts were developed on macOS, and the README asks for information or patches on using them on other platforms. That is not a claim of cross-platform support. If you are on Linux or Windows, treat the platform as unverified until you confirm it yourself. There is also no web interface and no hosted service; the output is database files and notebooks.
GarminDB compared with garminconnect and garminexport
The closest alternatives sit at different layers. python-garminconnect, the garminconnect package pinned in requirements.txt, is a Python client for the Garmin Connect API. It gives you authentication and raw responses. It does not give you a schema, summary tables, or notebooks. If you want to pull one endpoint into a script you already own, using the client directly is less machinery than adopting GarminDB's whole pipeline.
garminexport takes another angle: it is about exporting activities out of Garmin Connect, typically as FIT or GPX files. That is a file extraction job, not a database job. GarminDB does export activities as TCX files as one of its features, but its center of gravity is the SQLite schema and the daily, weekly, monthly and yearly summaries built on top of it.
The practical split: pick the API client if you are writing your own application, pick an exporter if you only need the activity files, and pick GarminDB if the thing you want to query is the daily monitoring and sleep and weight record set, joined together, in SQL. GarminDB also handles FitBit CSV and MS Health CSV imports through the same package, which the narrower tools do not.
Licence, maintenance and the cost of upgrading
GarminDB is GPL-2.0. That is a copyleft licence, and it matters if you plan to redistribute a modified version or ship it inside a product. Reading the source, running it locally against your own data, and writing your own notebooks are not the same activity as distributing a derivative work, but the boundary is a legal question and this article is not legal advice. If you intend to redistribute anything built on this code, check the licence terms against your plan before you start.
The repository is not archived, and the last push was on 2026-09-16, with releases v3.7.0 on 2026-03-11, v3.8.0 on 2026-05-14 and v3.9.0 on 2026-08-23. The upgrade cost is the schema rebuild described above: pip install --upgrade garmindb, then expect the possibility of a DB version exception and a run of garmindb_cli.py --rebuild_db against your local files. That is cheap if you have kept the downloaded JSON and FIT files and expensive if you have not, which is the main reason to leave the download directory alone. The project also asks for bug reports through make bugreport or garmindb_bug_report.py with the generated bugreport.txt, and points at garmindb.log as the first place to look when something fails.
Editorial conclusion
Adopt GarminDB if you want your Garmin Connect history in SQLite and you are willing to keep a JSON config file and a local data directory in sync with the downloader. Do not adopt it if you need a supported product, a web interface, or a schema that will not change under you. Verify three things first: that the GarminConnectConfig.json start dates cover the period you care about, that stats.txt reports the record counts you expect, and that you have run garmindb_cli.py --backup before your first schema upgrade.
Frequently asked questions
How do I install GarminDB?
Install the release from PyPI with pip install garmindb on Python 3.x. Then copy GarminConnectConfig.json.example to ~/.GarminDb/GarminConnectConfig.json and fill in your Garmin Connect username, password and start dates before running anything.
How do I download my Garmin data with GarminDB?
Run garmindb_cli.py --all --download --import --analyze for a first full download, or add --latest to fetch only data after what is already in the database. The downloaded JSON and FIT files are retained so the databases can be rebuilt without redownloading.
What does GarminDB store in its SQLite databases?
Garmin daily monitoring files such as all day heart rate, activity, climb and descend, stress and intensity minutes, plus sleep, weight and resting heart rate data and activity files, with daily, weekly, monthly and yearly summary tables on top.
Which platforms does GarminDB run on?
The README states the scripts were developed on macOS and asks for information or patches on using them on other platforms, so Linux and Windows are not documented as verified.
What licence is GarminDB under?
The repository is licensed GPL-2.0. That is a copyleft licence, so redistribution of modified versions carries obligations that local personal use does not.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tcgoetz-garmindb)