Back to Articles
Android Perfetto Tracing Guide for Performance

Android Perfetto Tracing Guide for Performance

1. Adding Custom Trace Events (Kotlin/Java)

// build.gradle
implementation("androidx.tracing:tracing-ktx:1.3.0")

// Usage — Kotlin inline function wraps begin/end
import androidx.tracing.trace

fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    return trace("MyAdapter.onCreateViewHolder") {
        MyViewHolder.newInstance(parent)
    }
}

fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    trace("MyAdapter.onBindViewHolder") {
        trace("MyAdapter.queryDatabase") {
            val rowItem = queryDatabase(position)
            dataset.add(rowItem)
        }
        holder.bind(dataset[position])
    }
}

Raw android.os.Trace API

import android.os.Trace

fun processData() {
    Trace.beginSection("processData")
    try {
        // ... work ...
    } finally {
        Trace.endSection()
    }
}

// Async trace (cross-thread)
Trace.beginAsyncSection("networkRequest", requestId)
// ... later, possibly on another thread ...
Trace.endAsyncSection("networkRequest", requestId)

// Counter (shows as a graph in Perfetto UI)
Trace.setCounter("itemsInCache", cacheSize.toLong())

Enable on non-debuggable builds

// Call early in Application.onCreate()
Trace.forceEnableAppTracing()

2. Native NDK Tracing (C/C++)

#include <android/trace.h>

void handleButtonPress(const char* buttonName) {
    char label[64];
    snprintf(label, sizeof(label), "User tapped %s", buttonName);
    ATrace_beginSection(label);
    // ... work ...
    ATrace_endSection();  // closes most recent beginSection on same thread
}

3. Perfetto C++ SDK (Full Programmatic Control)

For complete in-app control over trace sessions:

#include <perfetto.h>

// Define trace categories
PERFETTO_DEFINE_CATEGORIES(
    perfetto::Category("rendering").SetDescription("Graphics events"),
    perfetto::Category("network").SetDescription("Network stats"));
PERFETTO_TRACK_EVENT_STATIC_STORAGE();

// Initialize
void initTracing() {
    perfetto::TracingInitArgs args;
    args.backends |= perfetto::kInProcessBackend;  // self-contained
    args.backends |= perfetto::kSystemBackend;      // or connect to traced
    perfetto::Tracing::Initialize(args);
    perfetto::TrackEvent::Register();
}

// Start a trace session
std::unique_ptr<perfetto::TracingSession> startTrace() {
    perfetto::TraceConfig cfg;
    cfg.add_buffers()->set_size_kb(1024);
    auto* ds_cfg = cfg.add_data_sources()->mutable_config();
    ds_cfg->set_name("track_event");
    auto session = perfetto::Tracing::NewTrace();
    session->Setup(cfg);
    session->StartBlocking();
    return session;
}

// Stop and save
void stopTrace(std::unique_ptr<perfetto::TracingSession>& session) {
    session->StopBlocking();
    std::vector<char> data = session->ReadTraceBlocking();
    // Write data to .pftrace file
}

// Instrument functions — scoped (RAII)
void DrawPlayer() {
    TRACE_EVENT("rendering", "DrawPlayer");
    // slice spans until end of scope
}

// Non-scoped
void LoadGame() {
    TRACE_EVENT_BEGIN("io", "Loading");
    LoadAssets();
    TRACE_EVENT_END("io");
}

// With debug annotations
void DrawPlayer(int id) {
    TRACE_EVENT("rendering", "DrawPlayer", "player_id", id);
}

4. Jetpack Compose Composition Tracing

// build.gradle
implementation("androidx.tracing:tracing-perfetto:1.0.0")
implementation("androidx.tracing:tracing-perfetto-binary:1.0.0")
// WARNING: Don't ship tracing-perfetto-binary in production (large binary)

Android Studio captures this automatically. For terminal capture, add a track_event data source to your Perfetto config.

5. Start/Stop Trace via ADB

# Record a 10-second trace with app events
adb shell perfetto \
  -c - --txt \
  -o /data/misc/perfetto-traces/trace.perfetto-trace \
<<EOF
buffers: { size_kb: 102400, fill_policy: RING_BUFFER }
duration_ms: 10000
data_sources: {
  config {
    name: "linux.ftrace"
    ftrace_config {
      atrace_categories: "view"
      atrace_categories: "gfx"
      atrace_categories: "am"
      atrace_apps: "*"
    }
  }
}
EOF

# Pull the trace
adb pull /data/misc/perfetto-traces/trace.perfetto-trace .
# Open at https://ui.perfetto.dev

6. Method Tracing (Java/Kotlin)

// Captures every method call (high overhead, use for targeted profiling)
android.os.Debug.startMethodTracing("myTrace")
// ... code to profile ...
android.os.Debug.stopMethodTracing()
// Output: /sdcard/Android/data/<pkg>/files/myTrace.trace
// Open in Perfetto UI or Android Studio

Quick Reference

ApproachLanguageWhat it doesSession control
androidx.tracing.trace {}Kotlin/JavaCustom trace sectionsSystem/IDE controls session
android.os.TraceKotlin/JavaCustom sections + counters + asyncSystem/IDE controls session
ATrace_* (NDK)C/C++Native custom sectionsSystem/IDE controls session
Perfetto C++ SDKC++Full trace events + categoriesFull programmatic start/stop
Debug.startMethodTracingKotlin/JavaEvery method call capturedProgrammatic start/stop
adb shell perfettoShellSystem-wide traceCLI start/stop

Sources