iosNudge

Which Instruments tools do you use, and for what problems?

MediumAsked oftenPerformanceToolingMemory & ARC 3 min read

TL;DR

Instruments is Xcode's profiling app. Open it with Product > Profile (Cmd+I). Pick a template for your problem:

ProblemInstrument
Slow code, high CPUTime Profiler
Memory growthAllocations
Leaks and retain cyclesLeaks (plus Xcode's Memory Graph Debugger)
Scroll stuttersAnimation Hitches
Slow launchApp Launch
SwiftUI updatesSwiftUI
Tasks and actorsSwift Concurrency
NetworkNetwork
BatteryPower Profiler / Energy

Always profile a Release build on a real device.

Time Profiler

It samples the call stacks many times per second. Functions that appear often are where time is spent.

Tips:

  • Turn on Invert Call Tree to see the hottest functions first.
  • Turn on Hide System Libraries to focus on your code.
  • Select a time range around the slow moment, like a tap or a scroll.
  • Look at the main thread first. Main thread work blocks the UI.

Allocations

Shows every allocation, its size and its call stack.

The best technique is generation analysis (Mark Generation):

  1. Open and close a screen once to warm up.
  2. Mark a generation.
  3. Open and close the screen again a few times, marking each time.
  4. Objects that keep growing in each generation are leaks or caches without limits.

Leaks and the Memory Graph Debugger

The Leaks instrument finds memory that nothing in the app can reach anymore. This includes many retain cycles. It cannot find abandoned memory: objects that are still referenced (by a cache, a singleton or a closure) but never used again. Use Allocations for that.

Xcode's Debug Memory Graph button is often faster for cycles:

final class ProfileViewController: UIViewController {
    var onUpdate: (() -> Void)?
    override func viewDidLoad() {
        super.viewDidLoad()
        onUpdate = { self.reload() } // strong cycle: self -> closure -> self
    }
}

The graph shows ProfileViewController still alive after you closed it, with the closure holding it. Fix with [weak self].

Animation Hitches

Records each frame and marks hitches. It tells you if the time was spent in your app (commit) or in the render server. Use it while you scroll.

SwiftUI instrument

Xcode 26 has a new SwiftUI instrument. It shows:

  • Long view body updates.
  • How many times each view updated.
  • A cause and effect graph: which state change made which view update.

Swift Concurrency instrument

Shows tasks, their states (running, suspended, waiting) and actors. Useful to find:

  • Too many tasks created.
  • A busy actor that makes others wait (actor contention).
  • Work on the main actor that should run elsewhere.

Power and energy

The Power Profiler (Xcode 26) shows power use per subsystem: CPU, GPU, display, networking. You can also record a trace on the device itself, without Xcode, and look at it later.

Mark your own code with signposts

import os

let signposter = OSSignposter(subsystem: "com.example.feed", category: "Feed")

func loadFeed() async {
    let state = signposter.beginInterval("LoadFeed")
    defer { signposter.endInterval("LoadFeed", state) }
    await fetchAndParse()
}

Add the os_signpost / Points of Interest instrument. Your intervals appear on the timeline next to CPU and memory data.

Other useful instruments

  • System Trace: threads, blocking, context switches.
  • File Activity: disk reads and writes.
  • Core Data: fetch counts and timing.
  • Processor Trace (Xcode 26, on supported devices): records every function call, not samples.

Common follow-up questions

  • Why not profile in the Simulator? It uses the Mac CPU and memory. Numbers are very different from a phone.
  • Leaks shows nothing but memory grows. Why? It is probably abandoned memory, like an unbounded cache or an object a singleton still holds. Use generation analysis and the memory graph.
  • What is a dSYM and why does it matter here? It maps addresses to function names. Without symbols you see only hex addresses.
  • How do you track performance in production? MetricKit and the Xcode Organizer (launch, hangs, memory, battery).