2 September 2026
GPS Vehicle Tracking in Belize: A9G Modules to Live Map
I have spent a good part of the last couple of years building a GPS vehicle tracking platform from the ground up, starting with hardware that costs less than a decent lunch and ending with a live map that updates while you watch it. The platform is RideYa Tracker (rideya.bz), and a version of it runs garbage route tracking for the Belmopan City Council. This post is about how the pieces fit together, and about the parts that are harder than the tutorials suggest.
Why start with cheap hardware?
Commercial trackers are fine. They arrive sealed, they speak a documented protocol, and somebody else has already worried about the antenna. They are also priced for markets where a fleet manager signs off on a per-unit budget without blinking.
In Belize the arithmetic is different. A council department, a bus operator, a small delivery outfit: they want to know where the vehicles are, and they want the cost per vehicle to be small enough that fitting twenty units is not a capital project.
So I went the other way. Inexpensive GSM/GPS modules, the A9G family in particular, combine a 2G modem and a GPS receiver on one small board. You get a serial interface, an AT command set, a SIM slot and a battery connector. Everything else is your problem, which is exactly the point: if the firmware and the server are mine, I can change the behaviour when the field tells me something I did not expect.
What is an A9G module, and why use it here?
The A9G is a low-cost module that pairs a GPRS radio with a GNSS receiver. You talk to it over a serial UART using AT commands. You ask it to attach to the network, you ask it to power up the GPS, you ask it for a fix, and you push the result out over a data connection.
It suits Belize for three practical reasons:
- 2G coverage still reaches places where a data-hungry LTE tracker would sulk. Along the Hummingbird, out past the villages, on cane roads, a low-bandwidth radio is an advantage rather than a compromise.
- The payloads are tiny. A position report is a few dozen bytes. Data cost per vehicle per month stays negligible.
- The parts are replaceable. If a unit dies in a truck bed after a season of vibration and heat, swapping it is a minor expense, not an incident.
The trade-off is honesty about what you are holding. It is a hobby-grade board doing an industrial job, and the software has to compensate.
Talking to the module: AT commands over 2G
The firmware loop is unglamorous and that is a virtue. Bring up the radio. Attach to the packet network. Start GPS. Poll for a fix. When you have one, format a report and send it. Sleep. Repeat.
The interesting work is in the failure paths, because on a moving vehicle almost everything fails eventually:
- The module answers an AT command with something other than what the datasheet promised.
- The network attaches but the data context refuses to activate.
- GPS reports a fix with a horizontal dilution of precision so poor that the point lands in the sea.
- The unit reboots mid-transmission because the supply sagged when the engine cranked.
My rule is that the device never assumes success. Every command has a timeout, every state has a recovery path, and the fallback for anything unresolvable is a full radio reset. A tracker that reboots itself once an hour and keeps reporting is worth far more than a clever one that hangs silently on a Sunday.
Ingesting positions with FastAPI
On the server side I use FastAPI for ingestion. The endpoints that receive positions are deliberately boring: authenticate the device, validate the payload, timestamp it on arrival as well as trusting the device clock, write it, respond fast.
What goes into a position report?
Latitude, longitude, speed, heading, satellite count or fix quality, battery level, and the device's own timestamp. That last field matters more than people expect. Devices buffer readings when the network is unavailable and flush them later, so arrival order is not chronological order. If your database assumes it is, your map will draw a vehicle teleporting backwards across town.
Storage is a plain relational table with a spatial index and an aggressive retention policy for raw points, plus derived tables for trips and route summaries. Raw position history grows quickly. Deciding early what you keep at full resolution and what you roll up saves a painful migration later.
How do you handle GPS signal gaps?
You stop treating the track as a continuous line and start treating it as a series of observations with holes in it.
What has worked for me:
- Buffer on the device. If the data context is down, store readings in local memory and send them when the radio comes back. A short queue covers most of the gaps you will actually see.
- Reject nonsense at ingestion. Impossible speeds, points that jump hundreds of kilometres between consecutive fixes, and fixes with too few satellites get flagged rather than trusted.
- Draw gaps as gaps. On the live map I would rather show a dotted segment and an honest "last seen" time than interpolate a straight line through a place the vehicle never went.
- Separate "offline" from "stopped". A parked vehicle in a metal shed and a vehicle with a dead unit look identical unless you track heartbeat and fix quality independently.
Power, battery and the vehicle reality
Battery is where cheap hardware bites. A small lithium cell keeps the unit alive through cranking and short power interruptions, but heat inside a parked vehicle in Belize is unkind to cells, and a swollen battery is a hazard, not an inconvenience.
My approach is to run from vehicle power with proper protection, use the cell as a bridge rather than a primary source, and report battery state in every position message so degradation is visible on the dashboard before it becomes a callout. Reporting interval is the other lever: a tracker that reports every ten seconds while moving and every few minutes while stationary uses a fraction of the power and data of one that never varies.
Delivering the live map
The front end subscribes to updates rather than polling on a fixed timer, and each client only receives the vehicles it is entitled to see. For route subscriptions the model is simple: a route has a schedule and a set of vehicles, and a subscriber follows the route rather than the vehicle.
That framing is what made the municipal use work. For garbage collection tracking, it doesn't matter which truck is assigned today. They care whether the route covering the street has been serviced. The same data, framed around the route instead of the asset, answers a completely different question.
Practical takeaways
If you are building fleet tracking on low-cost modules:
- Design the firmware around recovery, not around the happy path.
- Timestamp on the device and on the server, and reconcile the two.
- Validate positions at ingestion; bad data is worse than missing data.
- Report battery and fix quality with every message.
- Decide your data retention policy before you have a year of raw points.
- Model the thing your users actually care about, which is often the route rather than the vehicle.
If you are running vehicles in Belize and weighing up whether to buy tracking or build it, I am happy to talk through the trade-offs. You can reach me through mark-dev.com.