Field, Outdoor & Conservation

Kafila (قافلہ) — convoy tracking for zero-signal terrain

Real-time convoy tracking and group-journey coordination for off-road expeditions, purpose-built for Northern Pakistan's patchy-to-nonexistent cellular coverage. Live at kafila.datacraft.com.pk.

React 18 + Vite MapLibre GL + Protomaps Dexie.js PHP 8.1 + MariaDB Live — Phase 1

Off-road convoys lose each other, and cell towers don't help

Group off-road trips through Northern Pakistan routinely cover terrain with no cellular signal for hours at a stretch — mountain passes, riverbeds, forest tracks. Vehicles spread out, someone takes a wrong turn, and there's no way to know who's where until everyone happens to regroup at the same waypoint. WhatsApp location sharing simply stops working the moment signal drops, which is exactly when you need it most.

The requirement wasn't "build a tracking app" — plenty exist. It was build one that keeps working when the network doesn't, and that syncs cleanly the instant a bar of signal reappears.

A convoy app that assumes the network will fail

Kafila is a installable PWA where every vehicle's phone queues its own GPS trail locally and pushes it to the group the moment connectivity allows. The map (MapLibre GL over free Protomaps vector tiles) shows live positions, trails, and distance travelled for every member of the convoy, plus SOS alerts, waypoint checkpoints, geo-tagged trip notes, and refuel logging.

A public no-login "watch" link lets family back home follow the convoy live without an account — important for trips where the whole point is that someone worries.

Kafila trip analytics — speed profile, elevation profile, and time-at-speed breakdown for a completed trip

Post-trip analytics for a completed convoy trip — speed profile, elevation profile, and a time-at-speed breakdown, reconstructed entirely from the queued GPS trail.

Built around one hard constraint: no signal, no problem

Offline-first GPS queue
Every position reading lands in a Dexie (IndexedDB) queue first. A sync engine drains it to the server the moment connectivity returns — nothing is lost to a dead zone.
Polling, not WebSockets
Hostinger shared hosting doesn't support WebSockets, so live updates run on exponential-backoff polling instead — a constraint that shaped the whole real-time layer.
GPS throttling that still looks smooth
Points are queued at most once per 3 seconds and only after ≥5m of movement (with a 30s heartbeat for parked vehicles) — cutting row volume ~70% with no visible loss on the trail.
iOS background workarounds
iOS suspends JS when the screen locks, so there's no reliable background GPS. Kafila re-acquires a wake lock on visibility change and falls back to periodic polling, with a clear on-screen warning when tracking isn't guaranteed.
Garmin MapShare integration
For satellite communicators, a cron job polls Garmin's MapShare KML feed so off-grid members without a phone signal still appear on the same live map.
Public watch link, no login
A session-tracked, unauthenticated `/watch/:code` route gives family a live view of the convoy — deliberately friction-free for people who aren't part of the trip.

Under the hood

FrontendReact 18 + Vite + Tailwind + Zustand, installable PWA
MapsMapLibre GL JS + Protomaps vector tiles (free, no rate limits at this scale)
OfflineDexie.js (IndexedDB) GPS queue with a persistent sync engine
BackendPHP 8.1 + MariaDB on Hostinger shared hosting
MediaCloudinary (alert/POI photos), SendGrid (SOS email)
AuthJWT with access + refresh token rotation

Where it stands

Phase 1 — auth, convoy creation/joining, live GPS tracking, and the map — is complete and live, and post-trip analytics (speed, elevation, time-at-speed) already ships too. Phase 2 (messaging, SOS, checkpoints, Garmin) is backend-ready; POIs and trip replay are planned for future trips.

← Back to all work Next case studyNexus Finance →

Have a workflow problem like this one?

If your team, department, or field operation needs something that keeps working when the infrastructure around it doesn't, let's talk about it.