Skip to content
Bugwise
Menu
Mobile Testing

Network Conditions

Real users are on slow 3G, flaky hotel Wi-Fi and in elevators. Learn how networks misbehave, what a resilient app does about it, and how to simulate bad networks on iOS, Android and the web.

35 min beginner Mobile

Friday evening. Marta orders dinner in a food delivery app while walking to the train. She taps Place order, the spinner spins, and she steps into the station elevator. The spinner keeps spinning. She taps again. Back on the street, two confirmation emails arrive: two dinners, charged twice.

Nothing was “broken” on the developer’s desk, where the office Wi-Fi is fast and never drops. The bug only exists on a real street, with a real phone, on a real network. That’s why testing network conditions is one of the most valuable things a mobile tester does.

Why it matters

  • Most users are not on fast Wi-Fi. They’re on mobile data, moving between cell towers, in basements, on trains and in crowded stadiums.
  • Network bugs cost money and trust. Double orders, lost photos, prices that are hours out of date, and “Something went wrong” with no way out.
  • Developers rarely see them. A spinner that never stops looks fine for the 80 ms it’s visible on office Wi-Fi.

Wi-Fi, mobile data and the “G”s

A phone connects to the internet in one of two ways: Wi-Fi (a local router, often fast but sometimes overloaded or behind a login page) or mobile data (the cellular network). Mobile data comes in generations:

NetworkTypical real-world speedTypical latencyWhere you still meet it
2G / Edge0.1–0.25 Mbps500–1000 msRural areas, basements, fallback when 4G is overloaded
3G0.5–5 Mbps100–500 msOlder networks (many countries are switching it off), weak signal areas
4G / LTE5–50 Mbps30–100 msThe everyday mobile network for most users
5G50–1000+ Mbps10–30 msCities; drops back to 4G indoors and at the edge of coverage
Wi-Fi10–500+ Mbps5–50 msHome, office, cafés, hotels (quality varies wildly)

Latency, bandwidth and packet loss

These three words describe how a connection is bad. Each one breaks apps in a different way.

Latency

milliseconds (ms)

How long one trip to the warehouse and back takes.

What users feel: Every tap waits a moment before anything happens. Apps that make many small requests feel sluggish.

Bandwidth

Mbps / kbps

How much the van can carry per trip.

What users feel: Small requests are fine, but images, videos and big downloads crawl.

Packet loss

% of packets lost

Some parcels fall off the van and have to be sent again.

What users feel: Random stalls, requests that hang and then fail, video that freezes even though "signal looks fine".

A useful rule of thumb: latency hurts chatty apps (many small requests in a row), low bandwidth hurts heavy apps (big images, videos, uploads), and packet loss hurts everything unpredictably (requests stall, then fail or succeed seconds later).

Real-life situations to recreate

Bad networks aren’t just “slow”. Here are the situations that find the most bugs:

SituationWhat happens to the networkWhat to watch in the app
OfflineNo connection at allClear offline message, cached content, actions queued or blocked politely
Airplane modeWi-Fi and cellular off (Wi-Fi can be turned back on separately)Same as offline; also test turning it off again: does the app recover by itself?
Switching networks mid-requestWi-Fi → cellular when leaving home; the device gets a new IP address and open connections breakIn-flight requests fail or hang; uploads and payments must not be lost or duplicated
Elevator / tunnelConnection disappears for 10–60 s, then comes backSpinner forever? Automatic retry? Data lost?
Captive portal (hotel, airport, train Wi-Fi)Wi-Fi is “connected” but every request returns the portal’s login page (HTML, not JSON)App shows a helpful error instead of crashing on unexpected HTML
VPNExtra latency, different country/IP, some hosts blockedRegion-specific content, login, payments and maps still work
Data Saver / Low Data ModeThe OS limits background data (Android Data Saver, iOS Low Data Mode)Background sync, autoplay video and prefetching respect the setting; the app still works
Weak signal / crowded networkHigh latency and packet lossTimeouts, retries, double submits

What a good app does

A resilient app doesn’t need a perfect network. It needs good answers to the question “what if this request is slow, fails, or never comes back?”

  1. Shows a loading state. A loading stateLoading stateWhat the UI shows while it waits for data or an action to finish, such as a spinner or skeleton.Open in glossary → (spinner or skeleton) appears right away, so the user knows the tap worked. Buttons that send something are disabled while waiting, to prevent a double submitDouble submitA bug where an action runs twice because the user tapped or clicked twice quickly.Open in glossary →.
  2. Uses timeouts. Every request has a time limit. Without one, a request that lost its packets can hang forever, and the spinner spins forever with it.
  3. Retries sensibly. Safe requests (loading a list) are retried automatically a few times, waiting a bit longer each time (“backoff”). Payments and orders are only retried if the server can recognize a repeat. This is called idempotencyIdempotencyAn action that gives the same result no matter how many times it is repeated.Open in glossary →.
  4. Explains errors in human words. “You’re offline. Check your connection and try again.” plus a working Try again button. Never NSURLErrorDomain -1009 or a stack trace. See error messagesError messageText that tells the user something went wrong and, ideally, how to fix it.Open in glossary →.
  5. Shows cached content. The last loaded data stays visible offline, clearly marked (“Last updated 2 h ago”), instead of an empty screen. Learn more about the cacheCacheStored copies of data or files that make apps and websites load faster.Open in glossary →.
  6. Queues actions offline. A sent message, a liked post or a photo upload is saved and sent when the connection returns, with a visible “Waiting to send” state. Or the action is clearly blocked, never silently dropped.
  7. Recovers on its own. When the network comes back, the app refreshes, hides the offline banner and continues queued work without needing a restart.

Try it: the network lab

This food delivery app loads a list of restaurants. Start on 3G, then try Lossy with the timeout set to Never. Then switch on Timeout, Retry and Cache one by one and compare the timeline.

🧪 Network lab

Pick a network, then switch the app’s resilience features on and off. Each change reloads the feed.

Network profile

RTT 300 ms · 750 kbps ·High latency and low bandwidth. Every round trip costs a third of a second.

Timeout

Give up on a request after…

9:41

Deliver to · Home

Near you

Content visible

—

Requests sent

0

Result

Loading

Request timeline

0 s0.5 s1 s
Latency (handshakes) Download Waiting, nothing arrives Failed / timed out

Event log0.00 s

    Simulated, replayed at 2× speed. Times are typical, not exact.

    What to test

    Loading and slowness

    • Every screen that loads data shows a loading state on slow 3G. No frozen UI, no blank screen.
    • Buttons that send data (Pay, Send, Save) are disabled or show progress while waiting. Tapping twice doesn’t create two orders.
    • Screens remain usable while images load slowly (text first, images later).
    • Long operations show progress, and the user can cancel or leave safely.

    Offline and errors

    • Opening the app offline: cached content with an offline indicator, or a friendly offline screen.
    • Every error message is human-readable and offers a next step. Try again actually tries again.
    • Requests time out in a reasonable time. No endless spinners.
    • The app recovers automatically when the connection returns (or after one tap on Try again).

    Interruptions and switching

    Special networks

    • Captive portal Wi-Fi (connected, but no real internet).
    • VPN on, especially with a VPN server in another country.
    • iOS Low Data Mode / Android Data Saver on.
    • Very high latency (1–2 s) with normal bandwidth, and good latency with very low bandwidth.

    Common bugs

    #BugWhat you seeTypical severity
    1Infinite spinnerSpinner never stops offline or on a lost request; no timeout, no errorHigh
    2Double submit on slow networkUser taps Pay again because nothing happened; two orders or two paymentsCritical
    3Technical error textNSURLErrorDomain Code=-1009, SocketTimeoutException, stack tracesMedium
    4Silent data lossA photo, message or form disappears after the connection drops, with no messageHigh
    5Stale data shown as currentOld cached prices, balances or stock with no “offline” or “last updated” hintHigh
    6Dead retry button“Try again” does nothing, or only works after restarting the appMedium–High
    7No recoveryThe app stays in the offline state after the network returnsMedium
    8Crash on unexpected responseCaptive portal HTML or a truncated response crashes the appHigh
    9Too-short timeoutWorks on Wi-Fi, always fails on 3G or Edge although the server answersHigh
    10Race condition after reconnectingOld responses arrive late and overwrite newer data. See race conditionsRace conditionA bug that depends on the timing or order of events, so it only happens sometimes.Open in glossary →Medium

    Find the bug

    This sports shop app has six network bugs. Use the Device network switch under the phone like you’d use airplane mode or a throttling tool. Try every screen on Wi-Fi, on Slow 3G and offline, switch networks in the middle of things, and watch the network log.

    🐞 Bug hunt: Sports shop on a bad network

    This demo has 6 hidden bugs. Explore it like a tester, then check your findings.

    Found0/6
    9:41

    Shop

    Device network

    Network log

    • Requests will appear here…
    1. 1

      Hint: Go offline, then open the Orders tab.

    2. 2

      Hint: Switch to Slow 3G, open a product and tap Buy now twice.

    3. 3

      Hint: Go offline and tap the refresh button in the Shop.

    4. 4

      Hint: Start changing your profile photo, then go offline before it reaches 100%.

    5. 5

      Hint: Note the prices on Wi-Fi. Go offline, tap Restart app, and compare.

    6. 6

      Hint: Go offline, tap Buy now, go back online and tap Retry.

    How to simulate bad networks

    You don’t need to ride an elevator all day. Every platform has tools to fake bad networks. Use them to find bugs quickly, then confirm the important ones in the real world.

    Network Link Conditioner on a real iPhone

    1. Enable the Developer menu: connect the iPhone to a Mac with Xcode once, then turn on Settings → Privacy & Security → Developer Mode (iOS 16 and later) and restart.
    2. Open Settings → Developer → Network Link Conditioner.
    3. Pick a profile such as 3G, Edge, Very Bad Network, High Latency DNS or 100% Loss, and turn Enable on.
    4. Test, then turn it off again. It stays on until you do, and it slows down every app on the phone.

    You can also add your own profile with exact bandwidth, latency and packet loss values.

    From Xcode: open Window → Devices and Simulators, select the connected device and use Device Conditions → Network Link to start a profile.

    For the iOS Simulator: the simulator uses your Mac’s network. Install Network Link Conditioner from Apple’s Additional Tools for Xcode download and enable it in System Settings. Remember that it slows down your whole Mac.

    Android Emulator

    1. Open the emulator’s Extended controls (the ⋯ button in the side toolbar).
    2. Go to Cellular and set Network type (e.g. GSM, EDGE, UMTS/3G, LTE, 5G), Signal strength and Data status (e.g. turn data off).
    3. For offline tests, pull down the quick settings inside the emulator and turn on Airplane mode, or turn Wi-Fi and mobile data off separately.

    You can also start the emulator with network options, e.g. emulator -avd Pixel_8 -netdelay gprs -netspeed edge.

    Real Android devices have no built-in throttling, so use airplane mode, Wi-Fi/mobile data toggles, Data Saver (Settings → Network & internet), a proxy tool, or a router that can limit speed. In Developer options, Mobile data always active keeps cellular on while Wi-Fi is connected, which affects how quickly the phone can switch networks; test with it on and off if network switching matters.

    Many apps show some screens as web pages inside the app (web views), and mobile websites are tested in the browser.

    1. Open Chrome DevTools → Network (or the Network conditions panel).
    2. Use the throttling dropdown: presets like Slow 4G, 3G and Offline, or add a custom profile with your own download, upload and latency values.
    3. For an Android web view, connect the device (debug build with web view debugging enabled) and open chrome://inspect in desktop Chrome. For iOS web views, use Safari → Develop on the Mac (the app must allow inspection).

    Throttling in DevTools only affects that browser tab, not the rest of the app. See DevToolsDevToolsDeveloper tools built into browsers for inspecting pages, network traffic and errors.Open in glossary →.

    Proxy tools like Charles and Proxyman can throttle all traffic from a phone that goes through them:

    • Charles: Proxy → Throttle Settings… → enable throttling and choose a preset (e.g. 3G) or set bandwidth and latency yourself. You can limit it to specific hosts.
    • Proxyman: Tools → Network Conditions → create a rule for a domain with a preset or custom speed.

    Proxies can also return errors, empty responses or HTML pages (great for captive-portal tests). Read the next lesson: Proxy Tools: Charles and Proxyman.

    Simulators are great, but nothing beats reality. Plan a short “walking test” for critical flows like checkout, sending messages or uploading:

    Write down where you were and what the phone showed, because real-world bugs can be hard to reproduce.

    Example test cases

    TC-NET-001Feed shows a loading state on 3G

    Preconditions

    • Network Link Conditioner set to "3G"

    Steps

    1. Force-quit and open the app
    2. Watch the home feed while it loads

    Expected result

    A skeleton or spinner is shown within 0.5 s. Content appears when loaded. No blank screen, no frozen UI.

    TC-NET-002Opening the app offline shows cached content with an offline banner

    Preconditions

    • The app was used online before
    • Airplane mode is on

    Steps

    1. Open the app
    2. Look at the home screen and prices

    Expected result

    Previously loaded content is shown with a visible "You’re offline" banner and a "Last updated" time. Prices are clearly marked as possibly outdated.

    TC-NET-003Order is not duplicated when tapping Pay twice on a slow network

    Preconditions

    • Network throttled to Edge
    • Basket contains 1 item

    Steps

    1. Tap "Pay"
    2. Immediately tap "Pay" again
    3. Wait for the result
    4. Open Order history

    Expected result

    The button is disabled after the first tap. Exactly one order exists and the card is charged once.

    TC-NET-004Request times out with a friendly message when packets are lost

    Preconditions

    • Network Link Conditioner set to "100% Loss"

    Steps

    1. Pull to refresh the feed
    2. Wait up to 60 seconds

    Expected result

    Within the agreed timeout (e.g. 15–30 s) the spinner stops and a human-readable error with a working "Try again" button is shown.

    TC-NET-005Photo upload survives a network switch

    Preconditions

    • Phone connected to Wi-Fi with mobile data available

    Steps

    1. Start uploading a 10 MB photo
    2. At about 50%, turn Wi-Fi off
    3. Wait for the upload to continue or fail

    Expected result

    The upload continues over mobile data or clearly fails with a Retry option. The photo is never silently lost.

    TC-NET-006App recovers automatically when the connection returns

    Preconditions

    • App open on the home screen in airplane mode, offline banner visible

    Steps

    1. Turn airplane mode off
    2. Wait 10 seconds without touching the app

    Expected result

    The offline banner disappears and the content refreshes without restarting the app.

    TC-NET-007Captive portal Wi-Fi does not crash the app

    Preconditions

    • Connected to a Wi-Fi with a login page that has not been accepted (or a proxy rule returning HTML)

    Steps

    1. Open the app
    2. Try to refresh the home screen

    Expected result

    No crash. The app shows a message like "Can’t reach FitShop. You may need to log in to this Wi-Fi network."

    Tip: click a test case to expand it.

    Checklist

    Network conditions checklist

    0 of 12 checked

    Check your understanding

    Quick quiz

    0/5 answered · 0 correct

    1. 1.A screen with many small requests feels slow on 3G, even though each response is tiny. What is most likely the problem?

    2. 2.The spinner never stops when the network loses packets, and the "Retry" setting makes no difference. What is missing?

    3. 3.On a slow network, a user taps "Pay" twice and is charged twice. Which fixes help? (Pick the best answer.)

    4. 4.The hotel Wi-Fi shows full bars, but the app crashes on launch. What is a likely cause?

    5. 5.Which tool slows down the network for every app on a real iPhone?

    Key takeaways

    • Test how the app behaves on slow, flaky and missing networks, not the network itself.
    • Latency slows down chatty apps, bandwidth slows heavy content, packet loss causes random hangs and failures.
    • Good apps show loading states, use timeouts and sensible retries, explain errors in plain words, cache content (clearly labeled) and queue offline actions.
    • The biggest risks are infinite spinners, double submits, silent data loss and stale data shown as current.
    • Simulate with Network Link Conditioner (iOS), emulator cellular settings (Android), DevTools (web views) and proxy throttling, then confirm critical flows in the real world.
    • Always switch simulation tools off when you’re done. Related: network throttlingNetwork throttlingDeliberately slowing the connection to test how an app behaves on poor networks.Open in glossary →.

    Finished this page?Nice work, this page is complete!

    Mark it as done to track your progress. It's saved in this browser, no account needed.

    Its review cards are now in Bites ⚡
    Esc

    Type to search the whole site.