All posts
7 October 2026

Building apps that survive a bad network

Software built on fast wifi breaks in the places it gets used: a classroom, a shop counter, a delivery van. Designing for the bad connection is not an optimisation, it is the requirement.

Most software is built in conditions its users will never experience. Good laptop, fast connection, one browser tab that matters. Then it ships to a teacher marking a register in a classroom with one bar, or a cashier at a counter when the router has gone down. If the app stops when the network does, people stop using the app. They go back to paper, and the data you were collecting disappears. ## Decide what must work offline Not everything needs to. Be specific about the few actions that cannot be allowed to fail: - Taking a payment at a till - Marking attendance - Recording a delivery - Writing a note at a patient's bedside These are moments where the person cannot wait, cannot try again later, and will not come back to redo it. Everything else, reports, settings, browsing history, can reasonably require a connection. ## Write locally first, sync second The pattern that works: the action completes against local storage immediately, the interface confirms it, and a background process pushes it to the server when there is a connection. The user never waits on the network for the thing they must do. This introduces conflicts, and you have to decide the rules in advance. For a till, the sale is final and sync order does not matter. For a register, the last edit wins. For stock counts across two devices, you need a rule that a human can understand, because a human will have to explain it to someone. ## Save in one request, not thirty A register of thirty pupils should be one save, not one request per pupil. On a weak connection, thirty requests means some succeed and some do not, and you end up with a half-marked register and no clear way to tell which half. Batch the work. One request either lands or it does not, and retrying it is safe. ## Make retries safe to repeat Any request that moves money or creates a record should carry an identifier the server can recognise, so that the same request arriving twice creates one record, not two. Without this, every retry risks a duplicate sale. ## Show the truth about state People tolerate a slow connection. They do not tolerate uncertainty. Show what is saved, what is queued, and what failed. A small indicator saying three sales waiting to sync is enough, and it stops the panic that makes someone enter the same sale again. ## Keep the payload small Large images, uncompressed responses and chatty APIs are what turn a weak connection into a broken one. Send less. Compress what you send. Load the heavy parts only when asked. This also decides whether your app works on the phone your user actually owns, which is usually a mid-range Android two or three years old, not the latest device on your desk. ## Test on the real thing Throttle your connection. Turn wifi off halfway through a save. Try it on a cheap phone. The bugs that matter only appear under those conditions, and they are the bugs that decide whether people keep using what you built.

AppsOfflineMobile

Have something like this to build?

Tell me what the system has to do and who uses it, and you get a fixed scope, a timeline and a price before anything starts.

Start a project