Concept renderMonthly data is reports per month times on-wire bytes per report, plus handshake and keep-alive bytes, rounded up to the carrier billing increment. A CoAP header is a fixed 4 bytes and an MQTT PINGREQ is a 2-byte fixed header, but IP, transport and TLS sizes are not published here, so capture them on your own modem.
A location report can be a few fields long, and the data plan still charges for everything around it. The headers, the security layer, the handshake and the billing rounding each add to the payload. This guide gives a formula and a sheet layout you can rebuild in any spreadsheet. It uses only the sizes that the standards publish and marks every other input as yours to measure. It contains no Duobay price and no measured result.
It covers trackers for assets, vehicles and adults who know they carry the device. It is an engineering write-up of data sizing. It does not give legal advice.
Which sizes do the standards publish?
These are the facts we can quote, each from the specification itself. All pages were read on October 31, 2026.
| Item | What the source says | Where | Source |
|---|---|---|---|
| CoAP message header | A fixed 4-byte header starts every message. Token and options come after it. | RFC 7252, message format | RFC 7252, as of October 31, 2026 |
| CoAP message size guidance | A message should fit in one IP packet to avoid IP fragmentation. Section 4.6 gives 1152 bytes as a good upper bound for message size. | RFC 7252, section 4.6 | RFC 7252, as of October 31, 2026 |
| MQTT keep-alive packet | PINGREQ has no variable header and no payload, so it is the 2-byte fixed header. Keep Alive is a configurable interval in seconds. | MQTT 3.1.1 specification | MQTT 3.1.1 spec, as of October 31, 2026 |
| DTLS after NAT rebinding | A NAT rebinding without a Connection ID breaks the connection, and the cost is a new handshake. The Connection ID extension exists to avoid that. | RFC 9146 | RFC 9146, as of October 31, 2026 |
| TLS 1.3 record padding | Endpoints can pad TLS records, so record sizes can exceed the payload they carry. | RFC 8446 | RFC 8446, as of October 31, 2026 |
What this article does not give you
These inputs matter for the total, and we have no verified number for them. Each is marked for you to measure.
| Input | Status |
|---|---|
| IP and UDP or TCP header bytes on your link | Not taken from a source in this article. Read them from a capture on your modem. |
| TLS and DTLS record header and per-record overhead | Not read from the RFC sections for this article. Measure on your stack. |
| Handshake size for DTLS 1.2, DTLS 1.2 with Connection ID, and MQTT over TLS | Vendor and library dependent. It changes with certificates and cipher suites. No single published number fits your setup, so measure it. |
| Carrier billing increment and minimum session charge | No carrier increment is verified for this article. Treat it as an input and read the carrier pricing or terms page for the plan you buy. |
| Price per MB | Your plan. Prices change, so write down the date you read it. |
How do you compute bytes per report and per month?
Start with one report on the wire, add the amortized handshake and the keep-alive traffic, then apply the billing rounding.
B_report = P + H_app + H_net + H_sec
R = T_month / T (reports per month)
S = R / n (sessions per month)
K = T_open / KA (keep-alive exchanges per month)
B_month = R × B_report + S × HS + K × B_ping
billed (per session) = S × ceil(B_session / I) × I
billed (per transfer) = R × ceil(B_report / I) × I
monthly cost = billed / 1,000,000 × price (use the carrier's MB definition)Units: P, H_app, H_net, H_sec, HS, B_ping, I and every B term are in bytes. T, T_month, KA and T_open are in seconds. R, S, K and n are counts. Price is in currency per MB. The amortized handshake per report is HS / n, so a longer session spreads the same handshake over more reports.
Worked example with symbols
We do not supply example byte counts for the headers, because a made-up number would look like a fact. These cases use symbols, and each result was recomputed from the formulas above.
- If B_report equals half of I and each report is billed alone, billed bytes per report are I, which is I / (I / 2) = 2 times the on-wire bytes.
- If B_report equals I / 4 and you hold four reports to send in one transfer, the transfer is I bytes before any shared overhead, so you pay I for four reports. That is I / 4 per report, the same as the on-wire size, and one quarter of what four separate transfers would cost at I each.
- If a session has HS = B_report and n = 1, the handshake doubles the bytes for that report. At n = 4 the handshake adds one quarter of a report to each report. At n = 10 it adds one tenth.
Fill the sheet below with your captured values and run it at least three ways: your planned reporting interval, a case where the interval is halved, and a case where sessions are shorter because the network drops them.
The sheet layout
Create one input cell for each variable in the table below, then one formula cell per row of the second table. Spreadsheet function names such as CEILING work in common spreadsheet programs.
| Input cell | Meaning | Unit | Status and what to do |
|---|---|---|---|
| P | Application payload per report | bytes | Yours. Count the encoded fields you send, such as position, time, battery and flags. |
| H_app | Protocol header: CoAP 4 B plus token and options, or MQTT 2 B fixed header plus topic and packet identifier bytes | bytes | Yours for token, options, topic and identifier length. The 4 B and 2 B come from the table above. |
| H_net | IP plus UDP or TCP header | bytes | Replace after a capture. Not sourced here. |
| H_sec | TLS or DTLS record overhead per report (0 when security is off) | bytes | Replace after a capture. Record padding can add more. |
| HS | Handshake bytes per session, both directions | bytes | Replace after a capture for each security mode you will ship. |
| n | Reports sent per session before the connection is closed or lost | count | Yours. This depends on your firmware design and your network. |
| T | Reporting interval | seconds | Yours. |
| T_month | Seconds in the billing month you model | seconds | Pick one value and keep it for every scenario. |
| KA | Keep-alive interval (MQTT Keep Alive) | seconds | Yours. Applies only while a connection stays open. |
| T_open | Seconds per month the connection is held open | seconds | Yours. Zero for a design that connects, reports and disconnects. |
| B_ping | Bytes of one keep-alive exchange, including network and security overhead | bytes | The PINGREQ itself is 2 B. Add H_net, H_sec and the reply size from your capture. |
| I | Billing increment | bytes | Yours to replace from the carrier terms for your plan. |
| price | Price per MB on your plan, with the carrier definition of MB | currency per MB | Yours. Record the date you read it. |
| Output cell | Formula | Note |
|---|---|---|
| B_report | P + H_app + H_net + H_sec | On-wire bytes for one report. |
| R | T_month / T | Reports per month. |
| S | R / n | Sessions per month. |
| K | T_open / KA | Keep-alive exchanges per month. |
| B_month | R × B_report + S × HS + K × B_ping | On-wire bytes per month before billing rounding. |
| B_session | HS + n × B_report + (keep-alives inside that session) × B_ping | Bytes in one session. |
| Billed (per session) | S × CEILING(B_session / I) × I | Use when the carrier rounds each session. |
| Billed (per transfer) | R × CEILING(B_report / I) × I | Use when each report is its own billed transfer. Keep-alive and handshake need their own rows. |
| Monthly cost | Billed / 1,000,000 × price | Use the carrier definition of MB. Replace 1,000,000 if it differs. |
Add a security-mode selector with four states: none, DTLS, DTLS with Connection ID, and TLS. Each state gets its own H_sec and HS from your capture. The selector lets you compare modes on the same payload.
What are the common cost traps?
These follow from the specifications quoted above and from the formula. They are engineering reasoning. None describes an incident at any company.
- A small payload sits inside a larger message. Every report carries the protocol header, the network and transport headers and any record overhead. CoAP alone starts with a fixed 4-byte header before token and options. When P is small, the fixed parts can be most of B_report, so a payload-only estimate understates the bill.
- A lost session repeats the handshake. RFC 9146 says a NAT rebinding leads to connection failure and the cost of a new handshake. If your device sleeps between reports and the carrier NAT forgets the mapping, each wake-up may pay HS again. The Connection ID extension is the documented answer, and you need to test that your stack and server support it.
- Keep-alive costs bytes while nothing is reported. An MQTT connection that stays open sends a PINGREQ every Keep Alive interval. The packet is 2 bytes by itself, and each exchange also carries network and security overhead and a reply. A short Keep Alive on a connection that reports rarely makes keep-alive a visible share of B_month.
- Large messages can fragment. RFC 7252 recommends that a CoAP message fit in one IP packet and gives 1152 bytes as a good upper bound. A report batch that grows past the path limit risks fragmentation, which the RFC advises avoiding. This is engineering reasoning from the RFC text.
- Record padding changes the size you counted. RFC 8446 lets endpoints pad TLS records. If your library pads, the on-wire size can exceed the payload you encoded. Take the size from a packet capture of the link.
- Billing rounding can dwarf a tiny report. When the increment I is larger than B_report and each report is billed alone, you pay I for every report. This is arithmetic on the formula above. Whether your carrier rounds this way is an input you must read from the plan terms.
What should you measure on your own board?
We have not captured traffic for your device, and this page reports no measured result. Run these on your own hardware and backend, then paste the numbers into the sheet.
| What to measure | How to instrument or collect it | Raw data to record |
|---|---|---|
| On-wire bytes per report for each protocol | Run the tracker or a test client against your backend with a packet capture on the link. Send reports with the same payload encoding you will ship. Capture CoAP over UDP, DTLS with and without Connection ID, and MQTT over TLS. | Raw pcap files, bytes per report at the IP layer, payload length, protocol and security mode, firmware build, module firmware version. |
| Handshake bytes | Capture a cold connection from the first packet to the first application report. Repeat after a forced IP change or NAT timeout to see what a reconnect costs. | Handshake bytes in each direction, certificate chain size, cipher suite, whether a session or Connection ID was reused, number of packets. |
| Keep-alive traffic | Hold a connection open at the Keep Alive interval you plan and capture a quiet period with no reports. | Keep Alive value, bytes of each ping and reply with overhead, count over the capture window. |
| Reports per session in the field | Log session open and close events on the device and on the server during a bench or drive test. | Timestamps of connect, each report and disconnect, reason for each disconnect, reconnect count. |
| Billed usage compared with on-wire usage | Run a SIM on the plan you intend to buy for a fixed test period with a known report count. Compare the carrier usage record with your capture totals. | Report count, on-wire total from your capture, usage shown by the carrier portal or invoice, plan name and the date you read its terms. |
| Behavior when the network changes | Force a NAT rebinding or an address change during a session, with and without Connection ID. | Whether the session survived, bytes spent on recovery, time to the next successful report. |
Set the pass line from your product requirements and write down the reason for it before you run each test.
What should you ask before you choose a protocol and a plan?
Take this list to your firmware team, your connectivity provider and any supplier who proposes a design.
- What does the carrier plan document say about billing increments and minimum charges per session or per transfer, and on what date did we read it?
- Is the increment applied per session, per transfer or per day, and how does our firmware map reports onto those units?
- Which security mode do we ship, and have we captured its handshake on our own module?
- Does our stack and our server support the DTLS Connection ID, and what happens to a session after a NAT rebinding?
- How many reports do we send per session, and what in the firmware decides when a session ends?
- Is the connection held open between reports, and what Keep Alive interval does that need?
- What is the largest message we can send, and does any batching mode risk IP fragmentation?
- Who owns the SIM contract and the data pool, and who sees the usage records?
- Which numbers in our sheet come from a capture on our board, and which are still assumptions?
- Who is the person carrying the tracker, and have they been told that the device reports location? This page covers adult and asset tracking only.
Questions about tracker data sizing
Can I size the plan from payload size alone?
No. Each report also carries a protocol header, network and transport headers and any security record overhead, and sessions carry handshake and keep-alive bytes. The payload is one term in the formula above. The other terms need a capture from your own modem.
Does CoAP always use less data than MQTT?
This article does not claim that. The sources give a 4-byte CoAP header and a 2-byte MQTT fixed header for keep-alive, which are only fragments of the total. Topic names, tokens, options, security mode and session design change the result. Measure both on your hardware. RFC 7252, MQTT 3.1.1 specification, as of October 31, 2026. For which protocol to choose, see MQTT vs HTTP vs CoAP for battery devices.
What is the DTLS Connection ID for?
RFC 9146 describes it as a way to avoid the cost of a new handshake after a NAT rebinding breaks the connection. Whether it helps your product depends on how often your device sleeps and how your carrier NAT behaves, which you need to test. RFC 9146, as of October 31, 2026.
Which carrier rounds up, and by how much?
This article does not state any carrier's rounding rule, because we have not read and verified one from an official pricing or terms page. Treat the increment as an input, read the terms of the plan you intend to buy and record the date.
Does this cover LLM or audio traffic?
No. This page covers location telemetry. For a device that streams audio or calls a model, see the cellular data cost article for LLM devices.
If you want a connectivity budget checked against your tracker design, tell us about your device. You can also read about our LTE and GNSS tracker development.
Primary sources
All pages below were accessed on 2026-10-31. Specifications can be revised, so confirm on the live pages.
- IETF, RFC 7252, The Constrained Application Protocol (CoAP): https://www.rfc-editor.org/rfc/rfc7252.txt (accessed 2026-10-31)
- IETF, RFC 9146, Connection Identifier for DTLS 1.2: https://www.rfc-editor.org/rfc/rfc9146.txt (accessed 2026-10-31)
- OASIS, MQTT Version 3.1.1: https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html (accessed 2026-10-31)
- IETF, RFC 8446, TLS 1.3: https://www.rfc-editor.org/rfc/rfc8446.txt (accessed 2026-10-31)
Planning a tracker? Tell us what it needs to do. A Duobay engineer replies within 1 business day. Send a project brief →