Upload files

How to Add Heart Rate Data to a GPX File

The map is perfect. The line follows the road, the climbs are right, the pace is true. But there is no heart rate in the file — because on that ride, your heart rate strap was paired to your watch, and your watch was not the device that saved the track you kept.

This split is built into how sensors pair. A strap talks to one host at a time. If the strap talked to the watch, the watch file holds the beats. The computer's GPX holds the road. To get heart rate into the GPX, you do not edit the GPX by hand. You merge the watch file into it, by time.

This guide shows the whole path: what you need, how the time match works, how to run the merge, and how the result must be saved so that other tools can see the heart rate at all. That last step is where most tries fail, so we give it its own section.

The merge here is the twin-file case: two devices, one ride, same span of time. It is one stream of the broader job in how to combine FIT files from two devices. Here we go deep on the one stream people ask for most.

Why your GPX file has no heart rate in it

GPX began as a route format: places and times. Heart rate is not part of its core. It rides in an add-on block called an extension, which many tools write and many tools read — but a file can only hold heart rate if the device that saved it had the beats in hand. A bike computer with no strap paired saves a clean track and no pulse. The data was never in its world.

So the lack is not a fault and not a setting you missed. The beats exist — in the watch file. The fix is a data move, not a repair: line the watch file up with the track file, and copy the heart rate stream across, second by second.

How much this matters is up to you. For a log that just shows where you went, a track alone is fine. For training load, for zone work, for a coach who reads your files — the ride with no heart rate is half a ride. That is why this is the most asked-for stream merge of all.

This split is more common than riders think. A strap pairs with the unit on your wrist out of habit, while the unit on the bars is the one you watch for pace and maps. Or the pairing was set once, years ago, and no one recalls which unit hears the strap. The ride does not care. It records the same way either way: position in one place, the body in the other.

It is worth saying what is not lost in this setup. The heart rate file is whole: every beat, start to end, at the strap's full rate. The track file is whole too. Nothing has been sampled down or trimmed. You hold two complete halves of one record. That is why the fix is lossless when the clocks agree — there is nothing to invent, only a join to make.

What you need: a second file that has the beats

You need two files from the same ride. File one is the GPX with the track you want to keep. File two is any workout file — FIT, TCX, or GPX — that holds heart rate for the same span of time. The watch's own file is the usual source. A phone app that was paired to the strap works too, if it can export its file.

Diagram: four data streams shown as lanes; the heart rate lane is filled from a second file where the first file has a gap.PositionHeart ratePowerCadenceeach stream is filled from the device that recorded it best
Each stream is filled from the file that holds it. Heart rate comes from the watch.

Check the second file before you start. Its heart rate coverage should span the ride — a file that holds beats for just the first hour can only fill the first hour. Its start time should sit close to the track's start. And the beats should look like a ride: a warm rise, work at load, a fall at the end. A flat line at one value means the strap read skin, not heart, and merged junk is still junk.

How the two files are matched by time

Time is the bridge. Each point in the track file has a time stamp. Each heart rate value in the watch file has one too. The merge walks the track point by point, and for each point takes the heart rate value whose time stamp sits nearest — most tools allow a few seconds of slack, since devices tick at their own rates.

This is why the clocks matter. If the watch ran a minute fast, every beat lands a minute late, and your pulse peak sits past the hill top that caused it. For most modern gear the clocks agree to the second, since both sync to GPS or phone time. If your graph shows a fixed lag, that is the tell — and the merge is still sound once the offset is known.

Coverage in the result can never beat coverage in the source. If the watch file holds heart rate for 98% of the ride, the merged file holds it for at most 98% of the track points. The totals block on any good merge shows this rate stream by stream. Our guide on how to check merged totals and stream coverage shows how to read those numbers.

What if the spans differ by more than a blink? The strap's unit may have started late — you hit start at the first light, not the door. Then the heart rate file covers a span inside the ride's span. The merge still holds: beats attach to the seconds they match, and the first stretch of the ride simply has no heart rate. The output is honest about it. Coverage shows the rate for part of the ride, and the graph starts where the beats start.

And if one unit ran long — left on through the post-ride coffee — trim is the cure, on the long file only. Cut the tail past the ride's end, then merge. The rule never changes: shape the inputs until their shared span is the ride, and the beats will fall where they belong.

Step by step: add the heart rate

In FitMerge, upload the GPX track file and the watch file. The health check shows which streams each file holds — you should see heart rate in the watch file and not in the track file. Choose the overlap merge, and set the heart rate source to the watch file. Leave position set to the track file. Run the merge.

Read the totals before you download. Heart rate coverage in the output should sit close to the coverage in the watch file. Points out should match the track file's points — you are adding a stream, not points. If the output has far more points than the track, you picked a stitch, not an overlap merge. Go back and change the mode.

Download in the form you need. GPX with the heart rate in its extension block is fine for most training sites. If the file is bound for a Garmin or for a tool that wants full streams, FIT is the safer home — the format split is laid out in FIT vs GPX vs TCX: which format keeps your data.

Step one has a small gotcha worth its own lines: the strap's file may not say “heart rate” anywhere in its name. Device files are named by date and time, and two units produce two files with near-twin names. Open them by their health check, not by the name. The file with a heart rate stream shows it in the list; the file without does not. Pick by streams, every time, and the wrong-file fault never gets a chance to start.

A note on size: heart rate files are small next to tracks. A rate sampled each second adds one short value per point. The merged file will be close to the track file's size, not the sum of both in bulk. If your merged file comes out twice the size of the track alone, something else went in — a clue worth one look at the totals before you post.

Why the output form can hide your heart rate

Here is the trap. Heart rate in GPX lives in an extension block with a set name and shape. Tools that know the block read it. Tools that do not, skip it in silence — the file loads, the map shows, and the heart rate looks gone, though it sits in the file the whole time. Before you blame a merge, open the output in a tool you trust and look for the stream there.

Output formHow heart rate is storedWho reads it back
GPXExtension block on each track pointMost training sites and newer tools
TCXA heart rate field on each track pointTraining tools built on the TCX form
FITA field in each record, by designGarmin, Wahoo, and most training sites

If a site shows your track with no heart rate after a sound merge, try the FIT form of the same output before you redo any work. Nine times in ten, the data was fine and the reader was blind.

Why pair at all, if the beats can be moved later? Because the in-ride view matters to many riders: pace and beats on one screen, on the day. Merging is the cure for the past; pairing is the cure for the next ride. Both belong in your kit. Just do not let a clean pairing setup talk you out of keeping the raw files — devices fail in pairs too, on the worst days, and the merge path is the one that still works then.

One more pairing route exists: the bridge app that hears the strap and speaks to both units at once. These work, and they add a phone to the chain. Each link is a chance to drop. For a race, simple wins: one strap, one unit that hears it, one file with all — and the twin merge in your back pocket for the days when simple breaks.

One more form case: the heart rate file is a TCX from an old training unit, and the track is a GPX from a phone. The merge is the same, and the output should be TCX or FIT — the forms that hold beats as a core stream. Pairs like this are why the merge asks for streams, not forms: it reads what each file holds and writes the union in the form you pick.

When it cannot be done

Honesty helps here. If no second file exists — the watch was off, or its file was lost — there is no heart rate to add. No tool can rebuild beats from a track. Speed and climb can hint at effort, but a made-up pulse is worse than a blank one, since a coach or a load model will trust it.

The other dead end is a time base that cannot be matched: a watch file with no time stamps, or a track drawn as a route with no times. Routes and rides are not the same thing. And if the only heart rate file is an indoor session with no track at all, that case has its own path — see how indoor workout files work, with no GPS track.

The short version

Heart rate lives in the watch file; the track lives in the GPX. Line them up by time, copy the stream across, and save the result in a form your tools can read. Add heart rate to your GPX — the health check shows both files' streams side by side before you merge.

Sources and further reading

← All guides