How to Read Shadowrocket Data Page Traffic Stats: Per-Server and Per-App Readings

Shadowrocket's Data page splits traffic into two sets of readings: one by server, one by app. The two use different counting scopes, so the totals not matching is normal. Below we explain what each set measures, how to read the units, why they differ from iOS system stats, and give a troubleshooting order you can repeat.

Quick summary

If you are already connected to your own server but the per-server and per-app numbers on the Data page do not match, or you notice they fall short of the usage figures in iOS Settings, this guide walks through every reading in the order entry point → units → the two scopes → causes of the gap → troubleshooting sequence, and gives a repeatable diagnostic flow. It is written for readers who have already imported a subscription and want to use the readings to see where their traffic goes. Everything here assumes you have your own provider and subscription; the server names and numbers shown are only layout examples.

Where the Data page is and what the two sets of readings measure

Open Shadowrocket; Data in the bottom tab bar is the traffic statistics page. The top of the page shows the total for the current period, with upload and download listed separately; details are grouped below, and switching groups at the top of the page toggles between the by-server and by-app views. When the connection switch is off, traffic does not go through the tunnel and the numbers on the page will not grow, so if the readings look frozen, go back to Home and check the connection switch at the top.

The two sets of readings do not count the same thing. By server counts the connection bytes attributed to a given server entry; only connections actually forwarded through that server appear in this column. By app counts the app that opened the connection: as long as the connection went through the tunnel, it is recorded under that entry whether it ended up proxied or direct. So over the same period the two totals usually do not match; the difference comes from connections matched by DIRECT, DNS queries, and connections rejected by REJECT.

2 groups
Reading groups: by server / by app
Base 1024
Unit conversion: B → KB → MB → GB
Upload / Download
Each reading shows sent and received bytes separately
1 switch
The connection switch at the top of Home decides whether anything is counted

Which group to look at first depends on the question you are asking: to find out which server the traffic landed on, look at by server; to find out which app started it, look at by app. Used together, the two groups let you match a given app to a given server.

Units and how to read them: making upload, download, and totals add up

Every reading is split into upload and download. Upload is the bytes your device sent, download is the bytes it received; the two are never merged into one number because they mean different things when troubleshooting: unusual download usually means something is downloading or syncing, while unusual upload is more likely tied to uploads, backups, or heartbeat requests.

Units step up in base 1024 — B, KB, MB, GB — and the display picks the appropriate one automatically, so the same row may show MB at one moment and GB at another. The readings count bytes inside the tunnel, including the extra overhead from encryption and encapsulation, so they are usually slightly larger than the actual content size; downloading a 1 MB file and seeing 1.0x MB is normal.

Overview   ↑ 15.6 MB     ↓ 412.3 MB
By server  Server A      ↑ 12.4 MB     ↓ 386.2 MB
By server  Server B      ↑ 1.8 MB      ↓ 24.9 MB
By app     Safari        ↑ 3.1 MB      ↓ 208.7 MB

The layout above is only an illustration; the numbers are not measured values. In the real list each row also shows its share of the total, which makes it easy to spot the largest item at a glance; reading the share together with the absolute value makes anomalies easier to catch than looking at the total alone.

By-server readings: which server the traffic landed on

Each row in the by-server list corresponds to an entry in the server list on the Home page, with the same name shown there. After you switch servers, new traffic is recorded under the new entry; the old entry's historical readings do not reset automatically unless you clear the readings manually on the Data page or delete that entry.

This set of readings answers two questions directly: whether current traffic is landing on the server you expect, and whether a given server keeps generating traffic when you are not doing anything. The first helps you verify that Global Routing and Config rules behave as intended; the second helps you spot entries you forgot about in your configuration.

Reading groupWhat it countsIncludesExcludes
By serverConnections attributed to a server entryUpload and download bytes forwarded through that serverConnections matched by DIRECT, DNS queries, connections rejected by REJECT
By appThe app that opened the connectionAll connections handled through the tunnel for that app, including those matched by DIRECTTraffic generated while the connection switch is off

If you see an entry you do not recognize, go back to Home and check the server list first. Entry names match Home and normally come from a configuration you imported or a server you added manually; entries do not appear out of nowhere.

By-app readings: which app the traffic came from

The by-app list attributes traffic to the process that opened the connection. Requests to the same domain from different apps are counted separately, so it can answer who is using the traffic — something system-level statistics cannot do: iOS usage stats aggregate by network interface and cannot attribute bytes to a specific app.

The Global Routing mode directly changes how the two sets of readings are distributed. In Config mode, connections matched by rules count toward the corresponding server, while those matched by DIRECT appear only in the by-app list; in Proxy mode all connections funnel into the currently selected server, so the by-server list is basically one row that keeps growing; in Direct mode the by-server readings stop growing while the by-app readings keep accumulating.

Config

Recommended

Rule-based routing: connections matched by rules go through the corresponding server and count toward it; connections matched by DIRECT appear only in the by-app list.

Best for: everyday use, when you need to see which traffic goes through the proxy

Proxy

All connections go to the currently selected server, so the by-server list collapses into a single row — handy for checking totals and tunnel overhead.

Best for: temporary global mode, checking total readings

Direct

All connections go direct; by-server readings stop growing while by-app readings keep accumulating, making the gap between the two most obvious.

Best for: verifying rules are not matching by mistake, quick comparisons

When checking whether a rule is matching by mistake, Direct mode is a clean control: switch to Direct and repeat the same action — if the by-app reading grows by the same amount as before, that traffic was direct all along and has nothing to do with your rules.

Why the numbers do not match iOS system stats

iOS Settings → Cellular shows cellular data usage for the current billing period; it counts every byte on the cellular interface, including connections from all apps, whether or not they go through the tunnel. Shadowrocket's Data page counts bytes that pass through the tunnel, over both Wi-Fi and cellular. The two sample at different points and cover different scopes, so different numbers are inevitable.

Common sources of the difference:

Conclusion: use the Data page for relative comparisons only

The absolute values on the Data page do not need to line up with system stats; their value is the relative distribution over the same period. When judging an anomaly, look at whether a row's increase matches what you just did, not whether the total equals the number in iOS Settings.

Troubleshooting order for tracing unusual traffic with the Data page

The sequence below answers the question of whether some app is quietly using traffic. It relies on two preconditions: establish a clean baseline first, then perform only one action, so multiple variables do not mix.

  1. Confirm the connection is on

    Check at the top of Home that the connection switch is on. When it is off, traffic does not go through the tunnel and the Data page produces no new readings, which makes the following steps meaningless.

  2. Clear the baseline

    Clear both sets of readings on the Data page and note the time you cleared them, so you can compare with system usage.

  3. Perform a single action

    Go back to the app you want to observe and do one clear action, such as opening a page and waiting for it to finish loading, while leaving other apps alone.

  4. Check by app first

    Switch to the by-app group and see which row grew the most; that row is the source of this action.

  5. Then check by server

    Switch to the by-server group and confirm the increase landed on the server you expected; if there is no increase at all, the connection matched DIRECT.

  6. Compare against the routing mode

    If the increase shows up on an unexpected server, go back to Home and check the Global Routing mode and Config rules to see whether a rule matched earlier than intended.

Repeat steps 3 to 5 two or three times. If the increase lands on the same row every time, you can be fairly confident about the source; if it varies, the app's background refresh or push notifications may be opening connections at the same time — in that case, send the app to the background and observe another round.

Conclusion: classify by magnitude first, then decide what to investigate

When the two sets of readings do not match, look at the size of the gap first: a gap of a few MB usually comes from DNS queries and connections rejected by REJECT; a gap of hundreds of MB more likely means some app's traffic matched DIRECT. Classify before you act — doing it in the wrong order turns normal behavior into a fault.

Common questions

The by-server rows add up to less than the total — is data being lost?

No. The total counts every byte inside the tunnel, while by server counts only the part attributed to a specific server; connections matched by DIRECT, DNS queries, and connections rejected by REJECT appear only on the by-app side. Comparing the by-app sum with the total usually gets you closer.

The Data page numbers stay at 0 — how do I get them moving?

First go back to Home and confirm the connection switch is on, then check that Global Routing is not stuck on Direct. If both are fine, open any web page to trigger a connection and the readings will appear.

After switching servers, do the old server's readings reset automatically?

No. Readings accumulate per server entry; switching servers only records new traffic under the new entry. To clear them you need to reset manually on the Data page or delete the corresponding entry.

Why are there entries in the by-app list that I do not recognize?

Some connections are opened by system services or background processes with no foreground app to attribute them to, so they show up as system or unknown entries. These are usually tiny; if one keeps growing, go back to Home and check the server list and Config rules.

App Store verification