Network Inspector: inspect requests, headers, body, and timings

Low PriorityAsked in ~35% of Flutter interviews

2 min read

DevTools

Theory — what the Network tab captures

FieldWhat you see
URL & methodFull URL + GET/POST/PUT/PATCH/DELETE
Status code200 / 4xx / 5xx — colour-coded
Request headers / bodyIncluding Authorization, Content-Type
Response headers / bodyJSON pretty-printed by default
TimingDNS, connection, request, response, total duration
InitiatorThe call site (helps with multiple sources)

Works with dart:io HttpClient and the http package out of the box. For dio, add an interceptor or use the integration plugin.


Practical workflow when a request misbehaves

  1. Open DevTools → Network.
  2. Press Record (or it may already be recording).
  3. Reproduce the action in the app.
  4. Click the failing request.
  5. Walk down the checklist:
    • ✅ Endpoint and HTTP verb match the backend contract?
    • ✅ Auth header present and not expired? (Authorization: Bearer …)
    • ✅ Request body has the expected fields and types?
    • ✅ Status code — what does the backend say went wrong? (read the response body!)
    • ✅ Timing — was the call slow, retried, or timed out?

That sequence catches ~90% of API bugs in minutes.


Useful commands and integrations

// Log all requests via http_logging_interceptor / pretty_dio_logger to also see them in the console:
final dio = Dio()
  ..interceptors.add(LogInterceptor(requestBody: true, responseBody: true));

// For raw dart:io diagnostics
HttpClient().enableTimelineLogging = true;        // shown in Network + Timeline tabs

Common mistakes to avoid

// ❌ Trusting the client-side logs over the actual response body
// Always open the request in DevTools and read the *response* body — backend errors live there.

// ❌ Forgetting to enable record before reproducing
// First-time users miss the call. Record → reproduce.

// ❌ Inspecting only the URL when the bug is in the body
// 500s and 422s are usually about the payload, not the path.

// ❌ Ignoring timing
// 8-second total with 7 seconds of "wait" usually means a retry/backoff or a serial fetch waterfall.

// ❌ Not testing on mobile — emulator/simulator works differently for CORS, DNS, and certs
// Reproduce on a real device when the Network tab "looks fine" but production is failing.

Interview follow-ups

  1. How do you debug an intermittent 401 in production? Reproduce locally with the Network tab. Compare a working request with a failing one — usually a missing/expired Authorization header, a refresh-token race, or a request fired before auth state was ready. The Initiator column shows you which code path made the call.

  2. What does the timing breakdown tell you? Total time = DNS + connect + send + wait (server) + receive. Big "wait" = backend slow. Big "send/receive" = payload size. Big "connect" = TLS/DNS issue. Big total with low everything else = retries or queued requests upstream.

  3. How do you capture requests made through dio? Recent DevTools versions hook into dart:io's HttpClient automatically, but it's still good practice to add a logging interceptor (pretty_dio_logger, dio_log) so the console shows the same details and you can copy/paste curl commands.

  4. Can the Network tab help with offline / caching bugs? Yes — set the device to airplane mode and reproduce; the failing request shows the actual error (DNS, timeout). Combined with your repository's caching layer, you can see exactly which calls fall back to cache and which fail outright.

How helpful was this content?

Please sign in to rate this article.