The stall is the silence on the main thread. You never scrub to find it.
logcat.ai opens the trace as structured, queryable data and reads across frames, scheduling, binder and power to the cause.
sched 4 @ 4.1717
3 queries, 41 rows
The stall is the silence on the main thread. You never scrub to find it.
A trace holds millions of slices across every thread, CPU and counter. logcat.ai opens it as structured, queryable data, reads across frames, scheduling, binder and power to the cause, and plays the answer back on the tracks that matter.
The data is all there. Finding the one stall is the problem.
A trace is the ground truth for performance on the device, and also the hardest artifact to read by hand. Four reasons, each drawn on the tracks.
A few seconds of tracing yields millions of slices across hundreds of threads and every CPU. The UI renders it; finding the regression in it is on you.
Real answers live in SQL over the trace tables: joins across slice, sched and thread_state. Powerful, but a language and schema most engineers touch once a quarter.
A janky frame is a render slice, blocked on a binder call, waiting on a lock held by a thread the governor descheduled. The cause is four tracks away from the symptom.
Only a couple of people on the team read a trace fluently. Which tables and tracks matter rarely leaves their head, and leaves with them.
Reading traces by hand, on the clock.
Red is time. Each bar is a recurring cost of triaging performance without a tool that reads the trace for you.
Every track on the device, down to the nanosecond.
Perfetto is the system-wide tracing format for Android and Linux. A single capture records scheduling, frame rendering, binder IPC, locks, power rails and app startups. The ten tracks below are what one 8.0 s take holds, at whole-take density; the amber line is where the hero zoomed in.
From a binary trace to cited findings, in one pass.
Queried live over the trace, no lossy flattening. The engine reads the trace directly, so anything in the Perfetto trace format, Android system traces and Linux ftrace-backed captures included, is in scope. The playhead sits where the answer lands.
The trace is never flattened to text. It opens as structured, queryable tables and is profiled on open across frames, startups, CPU, binder, memory, power, contention and ANRs. That baseline is the same for every trace, before anything is asked of it.
"Why did the UI jank at 4.2 s?" No SQL, no schema. The investigation queries the live trace round after round: query, read the rows, refine the hypothesis, correlate across slices, sched and thread_state.
Each finding names the slice and track it came from. Every query it ran is auditable, and the run closes by naming the concrete next angles a deeper investigation would pursue.
Large multi-hundred-megabyte traces are streamed straight into the engine rather than loaded into memory wholesale. Queries are bounded, so analysis stays responsive on big captures.
Illustrative. Synthetic data.Reasoning over the live trace, not a flattened export.
Four things the panel in the hero was quietly doing. Each is drawn on the same tracks.
Every trace is profiled on open across frames, startups, CPU, binder, memory, power, contention, ANRs and more. Each area returns a headline and cited findings. That baseline is the same for every trace, before anything is asked of it.
Ask "why did the UI jank at 4.2 s?" with no SQL or schema knowledge. Grounded in what your trace actually contains, the investigation digs round after round against the live trace and correlates across slices, sched and thread_state to localize the cause. Every query it ran is auditable.
The trace projects into a dashboard: frame timing, CPU residency, thread states, power. Generated from the trace, never hand-built, and every value traces back to a query.
Delta correlates two traces, before and after a change, or a fast device against a slow one, and isolates which subsystem regressed. The fastest way to prove a fix actually worked: the silence on the main lane is gone.
The full investigation, end to end.
Not a highlight. The entire deep-research run, ranking the worst frames and following the one it can attribute to a 149 ms binder wait on YouTube's main thread beside a system_server lock storm. The lateness is queueing, not slow drawing.
Profiled on open. A finding per track, named to the process behind it.
A dozen processors read the trace on open (frames, scheduling, binder, contention, power), each returning a cited finding. These are the per-process findings from one live trace; the bar is how loud each track was.
A sample of what comes back.
Built automatically from the trace, every figure tied to the slices behind it.
Three kinds of slow, and what the trace says about each.
A trace is captured because something felt slow. Each kind leaves a different shape on the tracks.
The app stutters and the trace is a million slices wide. The analysis pulls the dropped frames out of the noise and ties each one to the thing blocking the main thread. No manual zoom-and-hunt.
Cold start drags, a screen hangs, and "it feels slow" is not a bug report. The investigation localizes the stall in time and names the lock, binder call or scheduler gap behind it, cited to the slice.
You captured it on a phone or an embedded target and do not want to live in the timeline. The dashboard reads the trace's structure and what was actually regressing, then builds the charts that fit it: the hot subsystems, the stalls, the frames that dropped.
Everything you need to know about Perfetto trace analysis.
Formats, mechanism, what it detects, whether you need SQL, size and security. Read down the lane.
Standard Perfetto traces (.perfetto-trace and .pftrace) captured by on-device System Tracing, the Perfetto command-line tools, or record_android_trace. Because we read the trace directly rather than flattening it to text, anything in the Perfetto trace format (Android system traces and Linux ftrace-backed captures included) is supported.
We never flatten the trace to text. The file is opened directly as structured trace tables and queried with SQL. Every trace is profiled for frames, startups, scheduling, binder, power, memory, contention, ANRs and more; then an investigation runs SQL across the live trace to answer your specific question, self-correcting across multiple rounds.
Jank and dropped frames with the render slice and the blocking cause, slow cold and warm startups with a phase breakdown, main-thread stalls from lock contention or binder latency, CPU contention and frequency capping, power-rail drain on supported devices, low-memory kills and memory pressure, and ANRs with the blocked thread. Findings are cited back to the slices and tracks they came from.
No. Ask questions in plain English and the agent writes the SQL for you, runs it against your trace, and explains what it found. If you do know SQL, the queries it ran are right there in the cited findings to build on.
Large multi-hundred-megabyte traces are handled by streaming the file straight into the engine rather than loading it into memory wholesale. Queries are bounded and run against the live trace, so analysis stays responsive on big captures.
Your trace data is encrypted in transit (TLS 1.3) and at rest (AES-256), processed in your own tenant, and never used to train AI models. Traces are queried live in the engine rather than converted into stored, searchable chunks, so their contents are not persisted as an index. Files are deleted after 90 days, or immediately from your dashboard. Enterprise plans offer on-premise deployment for regulated or air-gapped environments.
Stop living in the timeline.
Upload a trace and let logcat.ai surface the stall behind the jank. The panel reads to the end of the take; you read the finding.
Perfetto is one surface.
The same engine reads your logs, bugreports and kernel traces.