ByteScope

Android System Monitor

Per-core load and clocks, every thermal zone, live throughput and the process table — one second at a time, straight off the cable.

Every reading is taken over the USB cable by your own browser and stays in this tab. Nothing is installed on the phone and no measurement is uploaded — there is no server behind this page.

Checking browser support…

About this tool, FAQ and related tools

About this tool

Plug an Android phone into a Chromium browser over USB and this page becomes its instrument panel: overall CPU with a sixty-second sparkline, one bar and one live clock per core, every thermal zone the device will admit to, memory with the top apps by PSS, network and disk throughput as they happen, the ten busiest processes, and a recording you can stop and export as CSV. Nothing is installed on the phone and nothing is uploaded — this page is a static file with no server behind it, and every number stops existing when you close the tab.

MemAvailable is the number you meant by free RAM

Android phones are famous for showing a few hundred megabytes free on a machine with twelve gigabytes, and every task-killer app ever written was built on that misunderstanding. MemFree is memory that nothing is using at all, and on a healthy Linux kernel that number is supposed to be small: the page cache and reclaimable slab hold the rest, because unused memory is wasted memory. MemAvailable is the kernel's own estimate of how much a new allocation could actually get — free memory plus everything it is prepared to reclaim without swapping — and it is the number a human means by "free RAM". This page uses it everywhere and says so. A kernel too old to report it (before Linux 3.14) falls back to the classic free-plus-cached estimate, and the bar is labelled estimated rather than quietly changing what it means. The per-app ranking underneath uses PSS, which counts an app's private memory plus its fair share of what it holds in common with everything else, so those numbers deliberately do not sum to the total.

Per-core clocks, and why the clusters have no names

Every core gets its own row: a load bar from /proc/stat, its live scaling_cur_freq, and a scale drawn against that core's *own* cpuinfo_min_freq and cpuinfo_max_freq. That last part is what makes the strip readable on a big.LITTLE phone — 1.8 GHz on a little core is that core flat out, and the same 1.8 GHz on a prime core is idling, so one shared axis would show you exactly the wrong thing. Cores are grouped by their frequency ceiling, which is the physical property that separates the clusters and is a silicon constant. They are labelled "Cluster 0 · max 1.80 GHz" and never "little", "big" or "prime": those are marketing names, the mapping differs by SoC and by generation, and a confident wrong label on a dashboard is worse than an honest ceiling. The governor next to each row (schedutil, walt, an OEM name) is printed verbatim, because it is what you would match against your own shell output.

Throttling levels, and what a temperature costs you

The thermal strip is the kernel's raw /sys/class/thermal/thermal_zone*/temp, and the badge beside it is Android's own thermal service reporting NONE, LIGHT, MODERATE, SEVERE, CRITICAL, EMERGENCY or SHUTDOWN. Those are the framework's words, not this page's, and they mean something specific: from MODERATE the system starts asking apps to back off, and by SEVERE the CPU and GPU are being clocked down whatever the benchmark wants. There is no universal temperature at which that happens — the trip points are per-device and per-zone, set by the OEM's thermal HAL, so a phone throttling at 42 °C skin temperature and one running to 48 °C are both behaving normally. What you can do is watch which zone climbs first and how fast the clocks fall with it. A phone can also expose ninety near-identical zones, which is why this page watches one per family plus, always, the hottest one on the device, and says on the tile how many of how many it is showing.

This page is on the graph too

Measuring a computer with the computer is not free, and a monitoring page that hides its own cost is lying about the thing it exists to show. Every tick here is **one** merged shell command rather than one per file, the thermal census runs once instead of every second, top is asked every ten seconds because toybox sleeps 250 ms inside it to compute a %CPU delta, and dumpsys meminfo — which sends a binder transaction to every running process and makes each walk its own smaps — is asked every thirty seconds and can be turned off. Only one command is ever in flight, because two concurrent shells do not halve the wall time; they double the fork storm in the same instant. When the tab goes to the background everything drops to one command every ten seconds. Even so, on a phone under a real benchmark you should expect a percent or two of what you see to belong to the measurement.

The recording is the reason to keep the tab open: start it, run your stress test or your game or your upload, stop it, and take every series away as one table — CSV for a spreadsheet, JSON if you would rather script it, both built in this tab and never uploaded. The column set is frozen when you press Start, so a core going offline halfway through leaves empty cells rather than a file with rows of two different widths, and a measurement that failed is an empty cell and never a zero. From here, the Web ADB hub has the rest of the toolkit, the battery page reads the same pack at 1 Hz with cycle count and capacity, and the storage analyzer shows what is filling the phone this page only shows the I/O of.

Frequently asked questions

How do I see how much memory an app is using on Android?

Look at the PSS ranking in the memory tile: it lists the five processes holding the most proportional set size, which is the number Android itself uses when it decides what to kill. PSS counts an app's private pages in full plus its share of every page it holds in common with other processes — so if three apps share a 30 MB library, each is charged 10 MB. That is why the column does not add up to the phone's total, and why it is the fairest single number for "what is this app costing me". The RSS column in the process table below is a different measurement: it charges every shared page to every process that maps it, so those numbers add up to far more than the phone has. Both are read over USB with no app installed on the phone.

Is 100% CPU usage bad on a phone?

Not by itself. A phone at 100 % for a few seconds is a phone doing what you asked — decoding video, compiling shaders, installing an app — and finishing sooner at full clocks usually costs *less* battery than dawdling. What matters is what happens next. Sustained 100 % with nothing on screen means something is running in the background that should not be, and the process table names it. Sustained 100 % with the temperature climbing and the throttling badge moving off `NONE` means the phone is about to be slower than it was at 60 %, because the clocks are being pulled down. And 100 % that never comes back to idle after you close everything is the classic signature of a wakelock-holding app, which the process table plus the foreground field in the header row will usually identify in under a minute.

How hot does an Android phone get before it throttles?

There is no single number, and anyone who gives you one is quoting their own phone. Trip points are set per device and per zone by the manufacturer's thermal HAL: skin temperature usually starts mattering somewhere between 39 °C and 45 °C, the SoC's internal zones run much hotter than the case, and battery charging has its own separate limits that are stricter than the CPU's. What is portable is the *shape*: watch the zone that climbs first, watch the throttling badge move from `NONE` to `LIGHT` to `MODERATE`, and watch the per-core clocks fall while the load stays flat. That last combination — load pinned, clocks dropping — is thermal throttling, and it is unambiguous whatever the absolute temperature says.

Why do the network numbers here not match Android's data usage screen?

They are counting different things. This page reads `/proc/net/dev`, which is the kernel's per-interface byte counters since boot, and it sums the real interfaces while deliberately leaving out loopback and tunnel devices — a VPN carries the same payload twice (once on `wlan0`, once on `tun0`) and USB tethering would count this very debugging session. The tile prints exactly which interfaces it summed, so you can check. Android's data usage screen is a different accounting system entirely: it attributes traffic per app and per network type, applies its own billing-cycle boundaries, and does not count everything the kernel sees. Neither is wrong; the kernel's number is the one that answers "what is actually moving through the radio right now".

What can I do with the exported CSV?

It is one wide table, one row per second, with a millisecond timestamp, a UTC ISO timestamp and an elapsed-seconds column at the front — so it opens directly in Excel, Numbers, `pandas` or R with no reshaping. Typical uses: run a game or a benchmark for ten minutes and plot clocks against temperature to find the exact second throttling started; record two firmware builds doing the same task and diff the CPU-seconds; leave it recording during a suspected battery drain and correlate the foreground-app column with the power column. Cells for measurements that failed are empty, never zero, so an average taken across them is not silently dragged down. Recording stops at 1800 rows, which is thirty minutes, and it keeps the beginning rather than the end because for a stress run the baseline is the part worth having.