GPSTrack

HTTP or MQTT for GPS tracking? Pick by power budget

4 min read5 of 5 in Telematics

Every GPS tracking project reaches this fork, usually about an hour in. Both protocols carry the same forty bytes of latitude and longitude. Both are supported here, through the same normaliser, producing the same point.

So the choice is not about the payload. It is about what holding — or re-establishing — a connection costs the thing doing the sending.

The short answer

Your device Use
A laptop, a server, a cron job HTTP
A mains-powered Pi or mini PC HTTP
A phone or tablet HTTP — or nothing at all
A battery microcontroller (ESP32, nRF) MQTT
Anything on a metered cellular plan MQTT
Anything sending more than once a second MQTT
A thing you will build in the next 20 minutes HTTP

If you are undecided, that last row is the real answer. Start with curl, get a dot moving, and switch later — the field names are identical, so the migration is the transport and nothing else.

Why the handshake decides it

An HTTPS request that delivers one GPS point does this first:

  1. TCP three-way handshake — one round trip
  2. TLS handshake — one to two more round trips, and a few kilobytes of certificate
  3. Request headers — a few hundred bytes

Then it sends about forty bytes of actual position, and tears the whole thing down again. On a cellular link with 100 ms of latency, that is roughly a third of a second of radio-on time per point, most of it spent negotiating.

MQTT pays the same cost once. After the connection is up, a published point is a two-byte fixed header plus the topic plus the payload. No handshake, no headers, no teardown. A keepalive ping every minute or so, and that is all.

At one point every two seconds, HTTP re-negotiates 30 times a minute. MQTT negotiates once and then goes quiet between messages — which on a battery device is the difference between the radio idling and the radio working.

Where each one actually falls apart

HTTP breaks down when the radio never gets to sleep. On an ESP32 running from a lithium cell, per-point TLS handshakes are usually the largest line in the power budget — larger than the GPS module. You notice this as a tracker that lasts a day instead of a week.

MQTT breaks down when the connection is the fragile part. A vehicle drives through tunnels and dead zones; every reconnect is a fresh TLS handshake, and a client that reconnects badly can end up doing more handshakes than HTTP would have. Broker connections are also stateful in a way that shell scripts and serverless functions are genuinely bad at — there is nothing to hold the socket between invocations.

The honest summary: MQTT wins when the connection is long-lived and the device is power-constrained. HTTP wins when the sender is stateless, occasional, or being written this afternoon.

The same point, both ways

# HTTP
curl "https://gpstrack.dev/api/ingest?token=$TOKEN&lat=6.9271&lng=79.8612&speed=42"
# MQTT
mosquitto_pub -h gpstrack.dev -p 8883 --capath /etc/ssl/certs \
  -u device -P "$TOKEN" \
  -t "gpstrack/$SESSION_ID/gps" \
  -m '{"lat":6.9271,"lng":79.8612,"speed":42}'

Identical field names, identical aliases, identical bounds on custom channels. That is enforced by a test asserting both transports produce the same point from equivalent payloads, which exists because they were once two copies of the same logic and drifted.

Four differences worth knowing before you commit

Errors. HTTP tells you what went wrong — 400 with a reason, 401 for a bad token, 429 when you are over the rate limit. MQTT publish has no response channel at all, so a malformed payload, an unauthorised topic or an over-rate message is simply dropped. Debugging is meaningfully harder. Get the payload right over HTTP first, then port it.

The rate limit is the same either way: one point per second per session, burst of five. Over HTTP that is a 429 with Retry-After. Over MQTT it is silence. If MQTT points are going missing and everything looks correct, this is the first thing to check.

Topics are namespaced. A client may only publish under gpstrack/<sessionId>/. Anything else is refused.

Subscriptions are refused entirely. This is an ingest-only broker — the dashboard reads over HTTP. Denying all subscriptions is what stops one client reading another's stream, and it means MQTT here is a one-way pipe, not a bus.

Ports and TLS

Host Port Transport
HTTP gpstrack.dev 443 HTTPS
MQTT gpstrack.dev 8883 MQTT over TLS

Port 8883 is the conventional port for MQTT over TLS, and it is bound directly rather than sitting behind the web server — MQTT is raw TCP and cannot pass through an HTTP proxy's request handling.

There is no plaintext 1883 listener in production. The session token travels as the MQTT password, so an unencrypted broker would be publishing your write credential to every hop on the path.

What neither of them is for

If the device that has the GPS is also the device showing the map — a phone recording a run, a ride or a taxi journey — both protocols are the wrong answer. There is no round trip worth making. Track Me records to the phone's own storage and never contacts the server at all, which removes the queue, the token, the rate limit and the outage handling in one move.

The transport question only exists when the tracker and the display are two different machines.

Where to go next

Open the dashboard → Push points from any device over HTTP or MQTT and watch them move on a live map.
More on Telematics dashboard All 5 →
  1. Telematics

    Track anything with one HTTP request

    Put a moving thing on a live map with nothing but curl — no account, no SDK, no app. A complete GPS tracking walkthrough in two requests.

    15 June 2026 · 4 min read

  2. Telematics

    Stream GPS from an ESP32 over MQTT

    Wire a NEO-6M to an ESP32, publish fixes over MQTT with TLS on port 8883, and watch them arrive on a live map. Full sketch, no backend to write.

    18 June 2026 · 5 min read

  3. Telematics

    Live-track a Raspberry Pi with a USB GPS dongle

    Plug in a u-blox dongle, read it with gpsd, and stream fixes to a live map from a shell script. Includes the systemd unit and the m/s to km/h trap.

    20 June 2026 · 4 min read