Building a Mobile App With GPS Tracking and Geofencing: Feasibility, Cost and the Parts Nobody Quotes For
Adding real GPS tracking and geofencing to an existing mobile app typically runs $15,000 to $60,000 over 4 to 9 weeks in our delivery experience. As part of a first release it is $50,000 to $130,000 in 10 to 16 weeks. A full fleet or workforce platform with historical playback, reporting and admin tooling runs $150,000 to $350,000 over 6 to 12 months. The number moves on one thing more than any other: whether tracking has to survive with the app killed and the phone in a pocket for nine hours.
What GPS tracking becomes once real users touch it
The demo is a map, a blue dot, a circle, and a notification when the dot enters the circle. It works because the phone is in your hand, the screen is on, the app is in the foreground and you are standing outside with a clear view of the sky. All four conditions are false in production.
A field service company shipped a driver app where payroll was computed from geofence entry and exit at customer sites. Week three, a technician spent four hours at a site and the timesheet said eleven minutes. The phone was in a jacket pocket in a metal van, iOS suspended the app once the technician stopped interacting with it, and the significant-location-change API only woke the app after 500 meters of movement. Entry fired at 9:04. Exit never fired, because iOS coalesced it with the next region crossing 40 minutes later at a different address, so the app reported the exit timestamp as the moment it woke up, in a parking lot two miles away. The technician was not paid. The union got involved.
The capability is a state machine that produces a defensible, auditable timeline of where a person or asset was, reconstructed from an event stream the operating system deliberately makes lossy, delayed and out of order to save battery. The map is the last four percent of the work.
Background location: the OS is not on your side
Both platforms treat continuous location as hostile and degrade it. Which API you are on decides what you can promise.
iOS. Three modes, and picking wrong is the most common architectural mistake in code we inherit. Standard location updates with the location background mode give continuous high-accuracy fixes but require an Always grant, show the blue status bar pill, and die if the user swipes the app away. Significant location change monitoring survives termination and relaunches your app, but fires roughly every 500 meters and up to every 5 minutes, useless for a 100 meter fence. Region monitoring via CLCircularRegion is the only true geofence primitive, and iOS caps you at 20 monitored regions per app install. If your customer has 300 job sites you cannot monitor them. You build a dynamic region-swapping layer that monitors the nearest 19 sites plus one large re-evaluation region, re-sorted every time the user moves. That layer is two to three weeks and nobody quotes it.
Android. Since Android 10, ACCESS_BACKGROUND_LOCATION is a separate second prompt, and since Android 11 the user cannot grant it from the standard dialog at all, so you deep-link them into system settings. Android 14 added FOREGROUND_SERVICE_LOCATION and a mandatory foreground service type declaration. Then Doze mode, and worse, vendor battery managers: Samsung, Xiaomi, Huawei and OnePlus ship app-killers that ignore the standard exemptions. The site dontkillmyapp.com exists for this reason. On a Xiaomi device with default settings, your foreground service with a persistent notification still gets killed. The fix is a per-vendor onboarding flow that routes the user to a different settings screen depending on manufacturer, and it is a two-week feature.
Declare up front which product you are building: opportunistic tracking, which is cheap, lossy and fine for roughly where are my drivers, or evidentiary tracking, which is expensive and required when money or safety depends on the timeline.
Geofencing is not a circle, and the events lie
The naive version compares the current GPS point to the fence center and checks distance. Then the real failures arrive.
Accuracy is a radius, not a point. Every fix carries a horizontal accuracy value, and in a downtown core with multipath reflection off glass towers that value routinely exceeds 100 meters. If your fence is 100 meters and your accuracy is worse than that, you have no information. Code that ignores the accuracy field fires entry and exit events all night for a phone sitting still on a charger. That is fence flapping, and it is the number one cause of "the tracking is broken" tickets.
The fix is dwell and hysteresis. Use a larger radius for exit than entry, typically entry at R and exit at R times 1.3, and require a dwell period before confirming entry. Android's Geofencing API gives you GEOFENCE_TRANSITION_DWELL with a configurable loitering delay natively, one of the few places it is ahead. On iOS you build dwell yourself. Discard any fix whose horizontalAccuracy exceeds a threshold, typically 100 meters, and any fix where the OS reports negative accuracy, which means the fix is invalid entirely and is the check people forget.
Fences are rarely circles. Customers want polygons: this warehouse yard, not a circle covering the neighbor's yard. Neither platform's native API supports polygons. You monitor a circumscribing circle natively as a cheap wake-up trigger, then run point-in-polygon yourself on wake. For that and for the server side you want PostGIS with ST_Contains and a GIST index, or the H3 hexagonal indexing library for coarse fast bucketing at scale. Polygon containment in application code against an unindexed table is fine at 50 fences and falls over at 5,000.
Spoofing. If anything financial hangs on location, someone will fake it. Android exposes Location.isMock() and isFromMockProvider(). iOS has no equivalent, so you infer: impossible velocity between fixes, accuracy values that are suspiciously constant, altitude of exactly zero, timestamps that do not drift. Play Integrity API on Android and DeviceCheck or App Attest on iOS raise the bar. This is a line item on any workforce app where geofence events touch payroll.
Offline buffering, and why your timeline has duplicates
Vehicles enter parking garages and tunnels. Rural routes lose signal for 40 minutes. The phone keeps recording and cannot send, so you buffer, and buffering is where the data model gets hard.
Every point has two timestamps: when the GPS chip took the fix, and when it arrived at your server. Those can be hours apart, so your API and database need both, and every query, report and geofence evaluation must be explicit about which one it uses. Index on server-received time and a driver who was offline all morning appears to teleport across the city at 2pm.
Then retries. The device uploads a batch of 300 points, the network drops after the server has written them but before the ACK lands, the device retries, and the driver's odometer doubles. The answer is an idempotency key on every batch, a client-generated UUID per point, and a unique constraint at the database level so the second write is a no-op. Do it at the database, not in application logic, because two workers processing the same retry concurrently both pass an application-level existence check.
Points also arrive out of order, and geofence evaluation that assumes a monotonic stream produces nonsense on replay. Either evaluate server side against a sorted window after a settling delay, or evaluate on device where order is guaranteed and treat the server copy as an audit record. We generally do both and reconcile: on-device gives instant notifications, server-side gives a timeline you can defend in a dispute.
Volume is the other unplanned item. One vehicle at a 5 second sampling rate is 17,280 points per day, about 6.3 million per year. A hundred vehicles is 630 million rows a year. Postgres handles this with TimescaleDB or native time partitioning plus a retention and downsampling policy: full resolution for 30 days, one point per minute for 12 months, trip summaries forever. That policy is a business decision, and it has to happen in week one because it changes the schema.
Batteries, app store review, and the legal surface
Battery is a requirement, not a nice to have. On driver apps we have measured continuous high-accuracy GPS drawing north of 20 percent of a typical phone battery per hour. Field staff revoke permission or delete the app by day three if it kills their phone before lunch. What works: adaptive sampling driven by the accelerometer and activity recognition APIs, so you sample at 5 seconds while driving and 5 minutes while stationary; distance filters rather than time filters; batched delivery rather than one HTTP request per fix, since the radio is the real drain. Taking a driver app from 22 percent per hour to 6 percent per hour is normal and takes about two weeks of measurement and tuning that most quotes omit.
App store review will reject you. Apple's guideline 5.1.1 and the related location rules mean an Always permission request with a weak justification string gets rejected. You need a purpose string naming the concrete user benefit, an in-app pre-permission screen before you trigger the system dialog, and a documented consent flow if you track employees. Apple also requires background location to have a visible, user-understandable feature attached. Budget at least one rejection round on any app requesting Always location, realistically two weeks of calendar time, and it is the most common cause of a missed launch date here.
The legal layer is jurisdictional. Location is special-category-adjacent under GDPR and explicitly covered under CCPA and CPRA as precise geolocation. In the EU, tracking employees requires a documented lawful basis and, in several member states, works council consultation. Several US states restrict off-duty tracking. The build consequence: a hard on-off boundary tied to shift status rather than a setting, plus an audit log of who viewed whose location. That audit log is a feature nobody quotes.
What this costs
These bands are Digital Heroes delivery experience across 2,000-plus projects, not industry survey figures.
$15,000 to $60,000, 4 to 9 weeks: adding tracking and geofencing to an app you already ship. The bottom is foreground-only or opportunistic tracking, circular fences, under 20 fences per user, no payroll dependency. The top is background tracking that survives app termination on both platforms, dynamic region swapping past the iOS 20-region cap, offline buffering with idempotent upload, and vendor-specific Android battery onboarding.
$50,000 to $130,000, 10 to 16 weeks: tracking and geofencing as a core part of a first release, including the admin map, fence authoring UI, permission onboarding, notifications and a reporting view.
$150,000 to $350,000, 6 to 12 months: a full platform. Historical playback, trip detection and stitching, route replay, driver behavior scoring, multi-tenant admin, role-based access to location data, payroll or dispatch integration, and the retention and downsampling pipeline.
What drives this capability's number up, in rough order of impact:
- Whether money or safety depends on the timeline. The jump from roughly where are they to this timestamp will be defended in a payroll dispute brings in spoof detection, dual evaluation, audit logs and reconciliation. Assume it doubles the tracking portion.
- Fence count per user. Under 20 is easy. Over 20 means the dynamic swapping layer on iOS, two to three weeks, and where subtle bugs live for months.
- Polygon fences. Adds PostGIS, a fence drawing UI and on-device containment testing. Two to four weeks.
- Shift-length tracking on cheap Android hardware. Vendor battery managers turn a clean implementation into a per-manufacturer support matrix.
- Retention volume. Ten vehicles is a table. A thousand is a time-series architecture with a downsampling job and a cost model.
- Map SDK billing model. Not build cost, but the same P&L. Google Maps Platform bills per map load and per routing request; Mapbox bills per monthly active user on mobile. At 500 tracked devices those are different orders of magnitude, so model it for an hour before you pick.
When you should not build this
If you track vehicles and only vehicles, and you want a dashboard showing where the trucks are with hours-of-service and driver scoring, do not build a mobile app. Buy Samsara, Motive or Verizon Connect. The hardware plugs into the OBD-II port and draws power from the vehicle, so battery is a non-issue, and they already hold the FMCSA electronic logging device certification you legally need in the US and do not want to build. A custom fleet app that does what Samsara does costs you $200,000 and is worse.
If you want geofenced marketing notifications, a push when a customer walks past a store, use the geofencing already built into Braze, Airship or OneSignal. It is a few days of integration against a feature that would otherwise be six weeks, and conversion on proximity push rarely justifies a custom build.
If you track assets rather than people, a phone is the wrong device. A dedicated LTE-M or LoRaWAN tracker runs a year on a battery. No app store, no permission prompts, no user who turned location off.
Build custom when the geofence event is the input to a business rule that is yours: your dispatch logic, your compliance workflow, your chain-of-custody, your pricing model. Or when tracking rides inside an app your users already have and a second app would kill adoption. That case is strong. It is just narrower than most vendors admit.
How to brief and vet a developer
Brief on failure conditions, not the feature. Instead of "we need geofencing", write: "we need a defensible entry and exit timestamp accurate to within two minutes, on Android and iOS, when the phone is in a pocket for a nine hour shift, where GPS accuracy is 60 meters, with an hour of no connectivity, and the timestamp feeds payroll." That paragraph changes the quote by a factor of three, and the vendors it scares off are the ones you want scared off.
- "How many geofences can iOS monitor at once, and what do you do about it?" The number is 20. Not knowing it instantly means they have never shipped iOS geofencing. Then ask what happens at 200 sites: you want dynamic region swapping and an outer re-evaluation region.
- "What do you do with a fix that has horizontal accuracy of 150 meters against a 100 meter fence?" Discard it, plus a hysteresis and dwell strategy. "We use the point" means you are buying fence flapping.
- "The phone was offline for an hour and uploads 400 buffered points. Which timestamp do the geofence events use, and what stops the batch being double-counted on retry?" Two timestamps and an idempotency key with a database unique constraint. Anything vaguer is a duplicate-records incident waiting for you.
- "Our field staff use Xiaomi and Samsung devices. What breaks?" No mention of vendor battery managers or dontkillmyapp means they have never supported a real Android fleet.
- "What battery drain per hour do you commit to, and how will you measure it?" A real answer names a number and a method.
- "Walk me through your Always-location purpose string and what happens if Apple rejects it." You want to hear that they expect a rejection round and have a pre-permission screen.
- "At 200 devices sampling every 5 seconds, what does the database look like in year two?" Partitioning, a downsampling policy and a retention decision, not "Postgres will be fine."
- "How do we know a driver is not spoofing location?" If tracking touches money and they have no answer, they have not thought about your problem.
Then ask them to show a location app they shipped and tell you what broke in production. Anyone who has done this has a story about a battery complaint, an App Store rejection, or a timestamp that cost somebody money. A vendor with no scar tissue here is about to learn on your budget.
The evidence behind this guide
Independent findings on why this investment pays off. Every link goes to the primary source.
- Technical debt is the number-one frustration at work for professional developers, cited by about 63% of respondents - roughly twice the rate of the next-most-common frustration (complexity of tech stack, ~33%). Source: Stack Overflow (2024) →
- Industry analysis aggregating vendor data concludes mobile apps consistently outperform mobile web on engagement and conversion, with the large majority of mobile time spent in apps rather than browsers and app users viewing far more products per session. Source: MobiLoud (2025) →
- Digital Champions expect to achieve about 16% in cost savings and around 15% in revenue gains from digital operations over five years; the study surveyed 1,155 manufacturing executives across 26 countries. Source: PwC / Strategy& (2018) →
- SaaS spend averaged $4,830 per employee (up 21.9% year over year), with large enterprises (10,000+ employees) spending roughly $284M annually and running about 660 apps, while organizations wasted an average of $21M annually on unused licenses. Source: Zylo (2025) →
Rohan advises mid-market and enterprise teams on ERP, CRM and custom software, and has led delivery on dozens of business-software builds.
Writes for Digital Heroes, shipping business software for 2,000+ brands across 55+ countries since 2017.