Does your mobile app need to work offline?
How far to take offline-first for users in Bangladesh: measured network figures, which features need queue-and-sync, what it adds to the build, how to test it.

Ookla’s July 2026 Global Index puts Bangladesh’s median mobile download at 38.56 Mbps, with 24 ms latency (Ookla Speedtest Global Index). That is not the number that decides whether you need an offline first mobile app. The tail is. In Ookla’s Q4 2025 analysis the bottom 10% of 4G samples fell below BTRC’s 10 Mbps minimum in several divisions on every operator, and Teletalk’s bottom decile in Mymensingh measured 2.22 Mbps (Ookla Research). Your users are in both halves, often on the same afternoon.
The question is how far to go: cache well, degrade honestly for some features, or build offline-first, and what each adds to the build and the test plan. No Scaledex client work appears below; every example is a public case, in the third person.
Can mobile apps work offline?
Parts of them can; the useful question is which parts. Google Maps is the clearest public case of a critical subset: a downloaded area still guides you to a destination if the whole route lies inside it, but transit, bicycling and walking directions are unavailable, there is no traffic or alternate routes, and the download expires unless refreshed, which Maps attempts on Wi-Fi when 15 days or less remain (Google Maps Help). Every offline feature is that choice: what is stored, what is refused, what goes stale.
Offline is not hypothetical here: the government ordered a nationwide shutdown of mobile internet on 18 July 2024, and mobile connectivity returned on 28 July (Cloudflare). Only what was already on the phone survived.
Three tiers cover almost every product:
| Tier | What the user gets without a server | What it requires |
|---|---|---|
| Cache and show age | The last good copy, marked with its age | A cache layer and an “as of” label |
| Degrade honestly | What is unavailable, stated plainly, with any draft kept | A connectivity-aware state for each feature |
| Queue and sync | Actions accepted on the phone and replayed later | A local store, an outbox, idempotency keys, conflict rules |
The first page of results calls the third tier offline-first. Most apps need the first two everywhere and the third in 1–2 places.
The network your users are on, as a spec
Ookla’s nationwide 4G median was 31.15 Mbps down and 12.22 Mbps up in January 2026, above the floor BTRC set in September 2025 of 10 Mbps down and 2 Mbps up. At the bottom 10th percentile, Robi missed the download floor in seven of eight divisions, Grameenphone in five, and no operator met the 2 Mbps upload floor in Barisal (Ookla Research).
Ookla’s analysis stops at the 10th percentile; for the tail below it, borrow Lighthouse’s Slow 4G profile: 1.6 Mbps down, 750 Kbps up and 150 ms round-trip time, which Lighthouse describes as roughly the bottom 25% of 4G connections and the top 25% of 3G (Lighthouse throttling). At 1.6 Mbps every 200 KB costs one second of transfer before latency. A 1 MB first screen spends 5 s in transfer alone: the same 5 s Android vitals treats as an excessive cold start, borrowed here as the budget for the first useful screen (Android vitals). Latency stacks on top: at 150 ms, six dependent requests are 0.9 s of waiting whatever the bandwidth.
What a payload budget looks like in public
Twitter Lite (2017) shipped at 600 KB over the wire against a 23.5 MB native Android install, cut data use by as much as 70% through image optimisation, and loaded in under 5 s over 3G (web.dev). Uber kept the core of m.uber (2017) to 50 kB so it would load on 2G, with a 3 s time to interaction there (Uber Engineering). Neither is offline-first. Both are budgets.
Data cost is the smaller constraint. Grameenphone lists a 20 GB pack at ৳499 for 30 days, about ৳25 per GB (US$0.20 at Bangladesh Bank’s interbank weighted-average rate of ৳122.77 on 24 August 2026) (Grameenphone, Bangladesh Bank); cable.co.uk’s 2023 tracker ranked Bangladesh 12th cheapest of 237 countries at US$0.23 per GB (cable.co.uk). A 3 MB screen costs the user under ৳0.10; a heavy screen costs time and failed loads, not money.
Which apps work offline?
Sort each feature by what a failure costs, not by how often users are offline. Three questions decide the tier: what happens if the action is applied twice, applied an hour late, or never applied?
A stale search result, price or session is worse than a refused one, so those degrade honestly. Forms, field data and messages are the natural queue-and-sync cases: the phone can accept them, the server can apply them later, and lateness costs little. Orders and bookings depend on scarcity: a table for tonight cannot be queued; a reorder of a regular item can.
Never queue a charge. A bKash payment ID is valid for one execution only; after a successful or failed response it cannot be executed again, only queried. It expires after 24 hours unused, so an execute call that drains from a queue a day later is refused (bKash Developer). SSLCommerz warns that a transaction can be pending or a customer can lose their session, requires the transaction and amount to be validated through its validation API, and returns a distinct VALIDATED status when validation is called more than once (SSLCommerz). Confirmation belongs server-to-server, through bKash’s real-time payment notification webhooks (bKash IPN); the app only ever asks for status.
How do you make an app work offline?
The first page’s architecture (local database, sync engine, conflict resolution) is right; three rules matter more than build order.
First, mint the idempotency key on the phone when the action is created, before the first attempt. Stripe stores the result of the first request made with a key and returns it to every retry, including 500 errors; it suggests V4 UUIDs and prunes keys after at least 24 hours (Stripe). Stripe reads the key from an Idempotency-Key header, the field an IETF draft, now expired, specifies for making POST and PATCH fault-tolerant (IETF draft). Your own API needs the same table: key, request hash, stored response.
Second, run the queue in something the operating system keeps alive. On Android, WorkManager keeps tasks scheduled across app restarts and device reboots, runs them only under constraints such as an unmetered network, and retries with exponential backoff (WorkManager), from a default 30 s delay with a 10 s minimum (defining work). On the web, the Background Synchronization API defers tasks to a service worker until the connection is stable, but MDN lists it as limited availability: it does not work in some of the most widely used browsers (MDN), one of the trade-offs in mobile app or PWA.
Third, write the conflict rule per entity before the code: the server wins for money and stock, the last writer wins for a personal note, fields merge for a long form.
React Native and “offline mode”
React Native has no offline layer of its own; the store and queue are yours, and WatermelonDB, SQLite-backed and billed as offline-first with sync to your own backend (WatermelonDB), is built for data sets from hundreds to tens of thousands of records. “Offline mode” in a specification usually means the Maps pattern, a user-chosen download with an expiry date: a feature, not an architecture.
What an offline-first mobile app adds to the build
Price it as rows, not a line. The third tier adds:
- a local schema and its migrations, on devices you do not control and cannot roll back;
- an outbox, a sync engine and a written conflict rule per entity;
- idempotent server endpoints with a key store;
- seven user-visible states per action (saved locally, waiting, sending, confirming, done, rejected, changed elsewhere) on each platform;
- a throttled-network and airplane-mode test pass on every release.
The state list is where the cost hides: seven states for each of three queued actions on two platforms is 42 screens to design, translate and test, before a single conflict case, and a list of eight queued actions makes it 112. That arithmetic is why a cached online-first app with truthful empty and retry states is often the better buy. When sessions are short and most actions need the server to be correct anyway, a queue carries 2–3 action types and the rest is overhead. Reserve the third tier for actions valid without the server and expensive to lose: field data, messages, long forms.
What the first page says, and where we differ
The first page of results, Android’s and Flutter’s own documentation among them, defines an offline-first app as one that performs all or a critical subset of its core functionality without internet. It is written for developers on good networks and names neither the network the users are on, nor which features earn the architecture, nor the price of the test plan. The missing decision is which features get the third tier, and the measured tail of the Bangladesh network, not the median, should make it.
A Bangladesh test protocol you can put in a proposal
Emulate the tail first. The Android emulator takes -netspeed and -netdelay flags: edge caps both directions at 473.6 kbps, umts at 384 kbps, and -netdelay gsm adds 150–550 ms of latency (Android Emulator). For a PWA, or the API alone, Chrome DevTools takes custom profiles (download and upload in Kbps, latency, packet loss, packet reordering) (Chrome DevTools); set one to Lighthouse’s 1,600 Kbps down, 750 up and 150 ms (Lighthouse throttling).
Then use real SIMs: Ookla’s Q4 2025 data covers Grameenphone, Robi, Airtel, Banglalink and Teletalk, and the bottom decile differs by operator and division (Ookla Research), so test on the two operators your analytics show most, at their peak hours, and once mid-morning for contrast.
Run five cases on every release: airplane mode mid-request, confirming nothing is applied twice; killing the app while the queue drains; a session expiring with actions queued; the same record edited on two devices; a payment started with the radio dropped before the response, confirmed by status query only.
Measure five things and write the thresholds into the proposal: cold start to first useful screen on the Slow 4G profile, held to the 5 s borrowed from Android vitals’ excessive-cold-start line (Android vitals); payload per screen against its budget; failed-request rate under the profile; time to drain the queue after reconnecting; duplicate orders and charges, which must be zero.
Copy this acceptance sheet
- Every feature has a tier written next to it.
- Every screen has a payload budget and a measured figure under Slow 4G.
- Every queued action carries a key minted on the phone; the server stores key, request hash and response.
- No charge is ever queued; payment outcomes are confirmed server-to-server and queried, never re-executed.
- Every queued action has its seven states designed on both platforms; every entity has a written conflict rule.
- Cached content shows its age.
- The five failure cases pass on the emulator profiles and on two operators’ SIMs, with zero duplicate orders or charges in the log.
What to do next
- Mark a tier against every feature; if more than three need queue-and-sync, question the list.
- Set a payload budget per screen from the 200 KB-per-second arithmetic and put the Slow 4G profile in the build pipeline.
- Ask each proposal for the offline rows priced separately, each with an acceptance test from the protocol.
- Book the SIM tests before launch, on the operators your users use, at the hours they use them.
If you want the tiers, budgets and tests turned into a buildable scope, see mobile development at Scaledex.