Delivering fluid user experiences on Android requires rendering interfaces consistently at 60 Hz, 90 Hz, or 120 Hz display refresh rates. When a frame takes longer than the available hardware refresh budget to compute, draw, and upload to the GPU—typically 16.6 milliseconds on 60 Hz panels or 8.3 milliseconds on 120 Hz displays—the system drops the frame, resulting in noticeable stutter known as “jank”. Android’s rendering pipeline (HardwareRenderer / RenderThread) records extensive statistical histograms for every running application package through the GraphicsStatsService. Using Android Debug Bridge (ADB) and dumpsys graphicsstats, performance engineers and mobile developers can query historical frame-rendering distributions, identify UI thread bottlenecks, and track jank metrics across regression benchmarks.
Architecture of the Android Graphics Pipeline and Jank Tracking
The Android UI rendering architecture processes visual updates across distinct stages:
- UI Thread (Choreographer & View Traversal): Handles input events, measures views (
measure()), arranges layouts (layout()), and records drawing display lists (draw()). - RenderThread: A separate thread that compiles display lists into OpenGL ES or Vulkan GPU commands, handles asset uploading, and submits buffers to the SurfaceFlinger compositor.
- VSYNC: Hardware vertical synchronization pulses signaling the display hardware is ready for the next frame buffer.
- Jank: A missed frame presentation deadline caused by prolonged CPU computation, complex view trees, memory garbage collection pauses, or GPU overdraw.
Dumping Graphics Stats via ADB
To inspect aggregated graphics performance for an application, ensure USB debugging is enabled, launch the target application, and query dumpsys graphicsstats:
adb shell dumpsys graphicsstats com.google.android.apps.photos
The diagnostic dump provides a structured historical summary detailing frame counts, missed deadlines, percentile latencies, and a high-resolution duration histogram.
Analysing Summary Metrics and Jank Percentages
In the terminal output, examine the high-level summary block:
Package: com.google.android.apps.photos
Stats since: 1729480000000ns
Total frames rendered: 2450
Janky frames: 78 (3.18%)
50th percentile: 6ms
90th percentile: 11ms
95th percentile: 14ms
99th percentile: 21ms
Number Missed Vsync: 22
Number High input latency: 4
Number Slow UI thread: 42
Number Slow bitmap uploads: 8
Number Slow issue draw commands: 12
Number Frame deadline missed: 64
Key indicators to evaluate include:
- Janky frames: The total count and percentage of rendered frames that failed to meet their presentation deadline. A jank rate above 2% produces perceptible stutter during scrolling interactions.
- Percentile Latencies (50th, 90th, 95th, 99th): Reflects the cumulative distribution of frame computation time. Even if median latency (50th percentile) is excellent (6 ms), a high 99th percentile (21 ms) reveals periodic hitching.
- Number Missed Vsync: Frames where the UI thread was delayed in responding to the Choreographer VSYNC pulse.
- Number Slow UI thread: Frames where measure/layout traversals or long-running computation on the main application thread held execution beyond the frame deadline.
- Number Slow bitmap uploads: Frames stalled while transferring uncompressed pixel textures to the GPU, indicating missing asynchronous pre-decoding.
- Number Slow issue draw commands: Indicates that RenderThread took excessive time submitting OpenGL/Vulkan draw calls to the GPU driver.
Interpreting the Frame Duration Histogram
Following the summary metrics, dumpsys graphicsstats provides a detailed histogram plotting frame completion durations across millisecond buckets:
HISTOGRAM: 5ms=1100 6ms=620 7ms=280 8ms=140 ... 16ms=45 17ms=22 18ms=15 ...
By parsing this distribution, automated CI/CD benchmark runners can track rendering regressions between app releases without needing manual video recordings or high-speed cameras.
Resetting Graphics Stats for Isolated Profiling Sessions
Because Android aggregates graphics metrics continuously over a rolling 24-hour window, testing a specific user flow (such as opening a complex recycler list or animating a sheet dialogue) requires clearing prior counters.
To flush existing metrics and start a fresh benchmark measurement:
adb shell dumpsys graphicsstats --reset com.google.android.apps.photos
Perform the interaction test on the handset (e.g. rapid fling scrolling through a long media list), then query the metrics immediately:
adb shell dumpsys graphicsstats com.google.android.apps.photos
Automating Jank Auditing with Shell Scripts
To integrate graphics auditing into continuous automated test suites, extract the jank percentage programmatically via PowerShell or Bash:
adb shell dumpsys graphicsstats com.google.android.apps.photos | grep -E "Total frames rendered|Janky frames|90th percentile|95th percentile"
If the calculated jank rate exceeds established performance budgets (such as 2.5%), build pipelines can automatically flag the regression before code enters production.
Auditing UI frame distributions with dumpsys graphicsstats enables Android developers to systematically eliminate rendering bottlenecks, optimise layout hierarchies, and deliver seamless visual fluidity.