Convert a .fit file to CSV

Convert in the page. Nothing is uploaded, there is no account, and the file never leaves your machine.

Open your file

Drop your file here

the .fit file to convert

No account. No upload. The file is read on this device and never leaves it.

Nothing has been sent anywhere. 0 requests to this site, for the page's own code.

What you get — stated plainly

A CSV with one row per field in your file, and the number of records carrying it:

"key","records"
"fit:record.heart_rate","4182"
"fit:record.position_lat","4104"
"fit:record.altitude","4182"

This is the field inventory, not a per-record dump. We say so here rather than in a footnote because "convert fit to csv" means different things to different people, and a page that implies one and delivers the other has wasted your time.

The inventory is what you want if you are deciding whether a file is worth processing, checking whether a field you need is present, or working out why a downstream tool ignored part of your data. If you want every heart-rate reading as a row, that is the full ingestion path rather than this page.

Why the field names look like that

fit:record.heart_rate is message.field, namespaced by format. The message part matters: record.heart_rate is a reading taken during an activity, while session.avg_heart_rate is the device's own average of those readings. Flattening both to "heart_rate" is how a summary ends up being compared with its own inputs.

On file size

Files are read in chunks rather than loaded whole, so size is not the constraint people expect. The corpus averages 8.6 KiB per file and its largest member is 4.7 MB, but size is not what decides whether a parse fits in memory: a 130 MiB synthetic file streams through in 52 MB of resident memory, and the figure is flat in the input because nothing is held.

FIT is dense: 149,952,107 data points from 602 MB across the corpus, roughly 255 values per KiB. A small file can hold a great deal.