01A different problem, not a slower one
An app tested on office Wi-Fi meets a different world in the field: a driver moving between towers, a rider in a basement car park, a request that left the phone and whose answer never came back. The question is not “how do we make it faster” but “what should happen when we do not know if it worked”.
There is no single answer to that, so on Drivio every API call is classified before it is written. Three classes, three different behaviours.
02Class A — safe to do in the background
Test: if it failed silently, would anything be wrong? Saving a place, flipping a preference, marking a notification read. No.
These update the screen on the same frame and go into a sync queue that delivers them when the network allows. The user never waits for them, and never sees a spinner for something that is not really a wait.
03Class B — reads that may be slightly stale
Test: does failure only mean old data? A ride history, a list of saved places, a configuration screen. These render instantly from cache and refresh behind it. The one restriction is absolute: cached data is for showing, never for deciding. Nothing involving money or ride state is computed from it.
04Class C — the backend decides
Test: does money move, does a ride change hands, does the server decide what happens next? Booking, accepting a ride, an offer, a payment, a cancellation.
These are never queued. The app sends them, waits, and covers the screen with a single loader until the backend answers — and it never shows success before that answer arrives. A queued booking that silently fails twenty minutes later is a rider standing on a kerb with no car.
05Where the retry line is drawn
The sync queue retries, so whatever goes into it must be safe to deliver twice.
- Whole-value writes — “this setting is now X” — are idempotent. Delivered twice, the result is the same. These retry.
- Anything that appends, increments, charges or creates is not. Delivered twice, it happens twice. These get exactly one attempt.
The line is drawn per operation, by the person writing it, at the time they write it — because no generic layer can know whether an operation is safe to repeat.
06The exception: uploads
A driver registering uploads eight documents. Covering the whole screen for each one would hide which document is actually going up. So a file upload shows progress on its own tile, which is disabled while busy so it cannot be tapped twice — and the final submit that uses those files is Class C, and covers the screen like any other.
07Applying it
Ten questions decide the class of any new call, and they are asked before the call is written, not in a performance pass afterwards. If you are building an app for users on mobile networks in Pakistan, we would be glad to help — mobile app development.
Building something like this?
We design, build and run mobile apps and backends for businesses in Pakistan and abroad. Tell us what you are working on.
