
MQTT vs TCP for
Telematics
Device-to-cloud links run both ways: raw TCP with custom binary frames in the style of GT06 and Concox trackers, and MQTT over TLS to a broker fleet. This guide is the engineering comparison of how trackers talk to the cloud, covering framing, QoS, keepalive, reconnection, store-and-forward, TLS overhead on cellular, bandwidth and battery cost, broker scaling, and when each protocol is the right call.
THE LINK
How a Tracker Talks to the Cloud
A GPS tracker has one job on the wire: get a position fix and a few status fields from a cellular modem to a server reliably, cheaply, and with a battery and data plan that last. Everything between the modem and the backend is the transport design, and it is where most of the field reliability of a telematics product is won or lost. The choices are narrower than they look. At the bottom you have a TCP socket, and on top of that socket you either speak your own binary protocol or you speak a standard application protocol like MQTT. There is also CoAP over UDP for the most constrained cases. The rest is detail, but the detail is what determines whether a fleet of 50,000 devices stays connected through cell handovers and tunnels or silently drops half its messages.
The reason this is a real decision and not a settled one is that the device side and the server side pull in opposite directions. The device wants the fewest bytes, the least radio-on time, and the simplest firmware. The backend wants standard tooling, easy fan-out to consumers, and operational visibility. Raw TCP optimizes the device; MQTT optimizes the backend. Picking well means understanding both sides, which is exactly the scope of device-to-cloud protocol engineering.
OPTION ONE
Raw TCP With a Custom Binary Protocol
The dominant pattern in the low-cost tracker market is a custom binary protocol over a plain TCP socket. The GT06, Concox, and Teltonika families all work this way: the device opens a TCP connection to a fixed server IP and port, sends a login packet with its IMEI, and then streams compact binary location packets. A typical GT06 location frame is on the order of 20 to 40 bytes and looks like a start marker (0x7878), a length byte, a protocol number, the packed payload (latitude and longitude as scaled integers, speed, course, satellite count, status bits), a rolling serial number, a CRC, and a stop marker (0x0D0A). Every field is exactly as wide as it needs to be, with no text, no keys, and no whitespace.
The appeal is total control and minimal overhead. You decide the framing, so a fix can be packed into 30 bytes instead of the 150-plus a JSON-over-MQTT message might take. Firmware is tiny because there is no protocol library, just a socket and a buffer. On a metered cellular plan and a battery budget, those saved bytes and that saved radio time are real money and real runtime. The cost is that the system owns everything: the framing, the acknowledgement scheme, the keepalive, the reconnection logic, and a custom server-side parser that has to tolerate every malformed and partial frame a flaky modem will produce. The server is the hard part, because TCP is a byte stream, not a message stream, and a single read can return half a frame or three frames glued together. Getting that parser right at scale is part of telematics backend and data ingestion engineering.
THE BYTE STREAM PROBLEM
Framing: Where Message Boundaries Come From
TCP guarantees that bytes arrive in order and without corruption, but it gives you no concept of a message. It is a continuous stream, so the application has to define where one message ends and the next begins. This is framing, and it is the most common source of bugs in custom tracker protocols. Two approaches dominate. Length-prefixed framing puts a byte count at the front of every message, so the parser reads the length, then reads exactly that many bytes. Delimiter-based framing marks the end of a message with a fixed byte sequence, like the 0x0D0A in GT06, and the parser scans for it. Both require the server to maintain a per-connection buffer and a small state machine that accumulates bytes until a complete frame is present, then emits it and keeps the remainder.
MQTT solves this for you. The protocol has its own fixed header with a variable-length encoded remaining-length field, so the broker handles message boundaries and your application receives whole, discrete messages on topics. That is a large amount of fiddly, error-prone code you do not write. The tradeoff is that the MQTT framing and the CONNECT handshake add bytes per message and per connection that a hand-tuned binary protocol does not spend. For a device sending one fix a minute, that overhead is negligible; for a device sending a fix a second on a tight plan, it adds up. This is the recurring theme of the whole comparison: MQTT trades a few bytes for a lot of correctness you would otherwise have to build and maintain yourself.
OPTION TWO
MQTT: QoS, Keepalive, and Reconnection
MQTT is a publish-subscribe protocol that runs over TCP. The device connects to a broker, publishes location messages to a topic such as fleet/device-id/telemetry, and any number of backend consumers subscribe to those topics without the device knowing or caring. This decoupling is the structural advantage: adding a new consumer (a live map, an analytics pipeline, an alerting service) requires no device change at all. With a raw TCP protocol, every consumer either reads from your custom server or you build the fan-out yourself.
MQTT defines three quality-of-service levels. QoS 0 is fire-and-forget, with no acknowledgement, so a message lost in a network blip is gone; it is the cheapest and fine for high-frequency telemetry where the next fix is along in a second anyway. QoS 1 guarantees at-least-once delivery using a PUBACK, so a message is retried until acknowledged, at the cost of possible duplicates the consumer must de-duplicate. QoS 2 guarantees exactly-once with a four-step handshake, which is rarely worth its overhead for telematics. Keepalive is built in: the client declares a keepalive interval at connect, and if no packet flows within 1.5 times that interval, the broker considers the client dead and fires its Last Will and Testament message, which is a clean way to publish a device-offline event automatically. Reconnection logic still lives in the firmware, but the protocol gives you the session and clean-or-persistent session flags to make it well-defined.
The Last Will mechanism deserves emphasis because it is genuinely useful for fleets. With raw TCP a dead device is detected only when the socket times out and the server notices; with MQTT the broker publishes the offline status the instant keepalive lapses. MQTT is the default transport for new platforms for exactly these reasons, and the broker and cloud integration scope is described under MQTT cloud integration.
THE THIRD OPTION AND THE SUMMARY
CoAP, and a Side-by-Side Comparison
CoAP is the third option and the right one for the most constrained cases. It runs over UDP instead of TCP, so there is no connection to maintain and no three-way handshake, which suits NB-IoT devices that sleep for hours and wake to send a single tiny report. CoAP uses a compact binary header (4 bytes) and a request-response model similar to a lightweight HTTP, with optional confirmable messages that add an acknowledgement when you need reliability. The downside is that without TCP you give up ordered, guaranteed delivery and have to handle retransmission and reordering yourself when it matters. CoAP shines on networks with high packet loss and on devices where keeping a TCP socket alive would waste precious sleep time and battery.
| Property | Raw TCP + binary | MQTT over TCP | CoAP over UDP |
|---|---|---|---|
| Transport | TCP | TCP | UDP |
| Per-message overhead | Lowest (you control it) | Low (2+ byte fixed header) | Very low (4 byte header) |
| Framing handled for you | No, you build it | Yes | Yes (datagram = message) |
| Delivery guarantees | Custom ACK scheme | QoS 0, 1, 2 | Optional confirmable |
| Fan-out to consumers | You build it | Native pub/sub | Limited |
| Best fit | Ultra cost-sensitive trackers | Most connected fleets | Sleepy NB-IoT, lossy links |
OFFLINE RESILIENCE
Store-and-Forward and Reconnection
Vehicles drive through tunnels, parking structures, and coverage gaps, so the link will drop, and what the firmware does during the drop determines whether you lose data. Store-and-forward is the answer regardless of protocol: when the connection is down, the device writes location fixes to a local buffer (RAM ring buffer or flash, depending on how long an outage must be survived), and when the link returns it flushes the backlog. The subtlety is ordering and acknowledgement. With a raw TCP protocol you design your own ACK so the device knows which buffered fixes the server has durably stored before it deletes them; with MQTT QoS 1 you get that acknowledgement from the PUBACK, which is one more reason MQTT removes custom code.
Reconnection needs care on both transports. A naive client that reconnects immediately on every drop will hammer the broker or server when a regional cell outage brings thousands of devices back at once, a thundering herd that can take down the very server they are trying to reach. Exponential backoff with jitter spreads reconnections out in time. Whether the device runs raw TCP, MQTT, or CoAP, the cellular layer underneath also has to be designed for these conditions, which is the scope of cellular connectivity design.
THE REAL COSTS
TLS Overhead, Bandwidth, and Battery on Cellular
Security is where the protocol comparison meets the cellular bill and the battery. A plain TCP tracker protocol is usually unencrypted, which is cheap but means IMEI spoofing and traffic interception are trivial; this is a real and well-documented weakness of the low-cost tracker ecosystem. Wrapping the transport in TLS fixes that but is not free. A full TLS 1.2 handshake is several round trips and several kilobytes of certificate exchange, which on a high-latency NB-IoT link can take seconds and cost more bytes than hours of actual telemetry. TLS 1.3 cuts the handshake to a single round trip and supports session resumption, and on constrained devices DTLS with pre-shared keys avoids certificate exchange entirely. The right answer is to keep the connection alive and reuse the session rather than re-handshaking on every wake, because the handshake, not the data, is the expensive part.
On bandwidth and battery, the levers are payload size and radio-on time, and they matter far more than the choice between MQTT and raw TCP. Packing fixes into compact binary instead of JSON, batching several fixes into one uplink instead of one connection per fix, and keeping the modem in a low-power state between transmissions each save more than protocol selection does. A device that re-establishes a TLS-wrapped TCP connection for every single fix will drain its battery and its data plan no matter how lean the protocol on top is. These levers are tuned together across firmware and backend in telematics software development.
MAKING THE CALL
Broker Scaling and When Each Protocol Fits
At fleet scale the backend has to hold a very large number of mostly-idle persistent connections. A modern MQTT broker (EMQX, HiveMQ, VerneMQ, or a managed cloud broker) handles hundreds of thousands to millions of concurrent connections per cluster by keeping per-connection state small and clustering horizontally, sharing subscription routing across nodes. A custom TCP server can match this, but you build the connection management, the horizontal sharding, and the backpressure handling yourself, which is months of work that the broker ecosystem gives you off the shelf. Either way the bottleneck is rarely raw throughput and usually connection count and the cost of waking idle connections, so keepalive intervals and session handling are the real tuning knobs.
The default guidance is straightforward. Choose MQTT for new connected-fleet platforms where you control both ends and value standard tooling, native fan-out, and built-in delivery guarantees; the small byte overhead is almost always worth the engineering it avoids. Choose raw TCP with a custom binary protocol when integrating with existing trackers that already speak GT06 or Concox, or when unit economics are so tight that every byte counts and owning the parser and fan-out is justified. Choose CoAP for sleepy NB-IoT asset trackers and lossy links where holding a TCP socket open is the wrong model. Most real platforms end up supporting more than one, because a fleet is a mix of device generations, and an ingestion layer can be built to normalize all of them into one clean stream.
FAQ
Frequently Asked Questions
Is MQTT always better than raw TCP for trackers?
No. MQTT is the better default for new connected-fleet platforms because it gives you framing, QoS delivery guarantees, native pub/sub fan-out, and Last Will offline detection without writing them yourself. Raw TCP with a custom binary protocol wins when you are integrating existing GT06 or Concox devices, or when unit economics are so tight that the few bytes of MQTT overhead per message actually matter at your volume.
Why does framing matter on a TCP connection?
TCP delivers an ordered byte stream with no concept of a message, so a single socket read can return half a frame or several frames glued together. The application must define message boundaries through length-prefixing or delimiters and maintain a per-connection buffer and state machine. Framing bugs are the most common defect in custom tracker protocols. MQTT handles framing for you, which is one of its main advantages.
What MQTT QoS level should a tracker use?
QoS 0 (fire-and-forget) is fine for high-frequency telemetry where the next fix arrives in a second anyway. QoS 1 (at-least-once) is the common choice when you must not lose fixes, at the cost of de-duplicating possible repeats. QoS 2 (exactly-once) is rarely worth its four-step handshake overhead in telematics. Most fleets use QoS 1 for important events and QoS 0 for frequent position updates.
How do trackers handle going through tunnels and coverage gaps?
With store-and-forward. The firmware buffers fixes to RAM or flash while the link is down and flushes the backlog when connectivity returns, deleting buffered fixes only after the server acknowledges them. With raw TCP you build a custom acknowledgement scheme for this; with MQTT QoS 1 the PUBACK gives you the acknowledgement for free. Reconnection should use exponential backoff with jitter to avoid a thundering herd after a regional outage.
Is the TLS handshake a problem on cellular?
It can be. A full TLS 1.2 handshake is several round trips and several kilobytes, which on a high-latency NB-IoT link can take seconds and cost more bytes than hours of telemetry. The fixes are TLS 1.3 with its single-round-trip handshake and session resumption, DTLS with pre-shared keys on constrained devices, and keeping the connection alive so you reuse the session instead of re-handshaking on every wake.
When should I use CoAP instead of MQTT or TCP?
Use CoAP for the most constrained cases: sleepy NB-IoT asset trackers that wake briefly to send a tiny report, and networks with high packet loss. CoAP runs over UDP, so there is no connection to keep alive and no handshake to pay for, which saves battery and bytes. The tradeoff is that you give up TCP ordered, guaranteed delivery and handle retransmission yourself when reliability matters.
KEEP READING
Related pages
Solutions
Capabilities
The Device-to-Cloud Link, Engineered End to End
From custom binary framing on the firmware to an MQTT broker fleet and a hardened ingestion pipeline, the transport is designed to stay connected through tunnels, handle store-and-forward correctly, and keep cellular and battery cost under control.
Whether the task is choosing a protocol for a new tracker, integrating existing GT06 or Concox devices, or scaling a broker to a large fleet, share your system to get a tailored approach and a realistic timeline.
Schedule a Free Consultation