Instruments

RSS for tag

Instruments is a performance-analysis and testing tool for iOS, iPadOS, watchOS, tvOS, and macOS apps.

Posts under Instruments tag

200 Posts

Post

Replies

Boosts

Views

Activity

CoreImage memory build up on real device but not on simulator
I'm trying to benchmark a Core Image filter chains memory footprint and notice a weird quirk in instruments. On a real device, even with a simple Core Image chain, the memory balloons each time I ran the filter. See attached screen shots. Running on iPhone 17 Pro: Running on simulator (M2 Macbook Pro) As you can see there's a huge build up of 4MB "VM: IOSurface" memory on the real device, but the simulator seems to clean it up correctly. Here's my basic code: func processImage() { guard let inputImage = ContentViewModel.loadImageFromBundle(name: "kitty.HEIC") else { print("Failed to load sample_image from bundle") return } var outputImage = inputImage outputImage = outputImage.applyingFilter("CIBloom", parameters: [ kCIInputRadiusKey: 20, kCIInputIntensityKey: 0.8 ]) DispatchQueue.global(qos: .userInitiated).async { let data = self.context.jpegRepresentation(of: outputImage, colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!) if let data = data, let uiImage = UIImage(data: data) { DispatchQueue.main.async { self.displayImage = Image(uiImage: uiImage) } } } } Why is this happening? Seems like a bug to me or I need to release an object. At the very least makes it challenging to measure memory usage. Any help is greatly appreciated. Alex
1
0
728
Nov ’25
SwifUI Performance With Rapid UI Updates
The code below is a test to trigger UI updates every 30 seconds. I'm trying to keep most work off main and only push to main once I have the string (which is cached). Why is updating SwiftUI 30 times per second so expensive? This code causes 10% CPU on my M4 Mac, but comment out the following line: Text(model.timeString) and it's 0% CPU. The reason why I think I have too much work on main is because of this from instruments. But I'm no instruments expert. import SwiftUI import UniformTypeIdentifiers @main struct RapidUIUpdateTestApp: App { var body: some Scene { DocumentGroup(newDocument: RapidUIUpdateTestDocument()) { file in ContentView(document: file.$document) } } } struct ContentView: View { @Binding var document: RapidUIUpdateTestDocument @State private var model = PlayerModel() var body: some View { VStack(spacing: 16) { Text(model.timeString) // only this changes .font(.system(size: 44, weight: .semibold, design: .monospaced)) .transaction { $0.animation = nil } // no implicit animations HStack { Button(model.running ? "Pause" : "Play") { model.running ? model.pause() : model.start() } Button("Reset") { model.seek(0) } Stepper("FPS: \(Int(model.fps))", value: $model.fps, in: 10...120, step: 1) .onChange(of: model.fps) { _, _ in model.applyFPS() } } } .padding() .onAppear { model.start() } .onDisappear { model.stop() } } } @Observable final class PlayerModel { // Publish ONE value to minimize invalidations var timeString: String = "0.000 s" var fps: Double = 30 var running = false private var formatter: NumberFormatter = { let f = NumberFormatter() f.minimumFractionDigits = 3 f.maximumFractionDigits = 3 return f }() @ObservationIgnored private let q = DispatchQueue(label: "tc.timer", qos: .userInteractive) @ObservationIgnored private var timer: DispatchSourceTimer? @ObservationIgnored private var startHost: UInt64 = 0 @ObservationIgnored private var pausedAt: Double = 0 @ObservationIgnored private var lastFrame: Int = -1 // cache timebase once private static let secsPerTick: Double = { var info = mach_timebase_info_data_t() mach_timebase_info(&info) return Double(info.numer) / Double(info.denom) / 1_000_000_000.0 }() func start() { guard timer == nil else { running = true; return } let desiredUIFPS: Double = 30 // or 60, 24, etc. let periodNs = UInt64(1_000_000_000 / desiredUIFPS) running = true startHost = mach_absolute_time() let t = DispatchSource.makeTimerSource(queue: q) // ~30 fps, with leeway to let the kernel coalesce wakeups t.schedule( deadline: .now(), repeating: .nanoseconds(Int(periodNs)), // 33_333_333 ns ≈ 30 fps leeway: .milliseconds(30) // allow coalescing ) t.setEventHandler { [weak self] in self?.tick() } timer = t t.resume() } func pause() { guard running else { return } pausedAt = now() running = false } func stop() { timer?.cancel() timer = nil running = false pausedAt = 0 lastFrame = -1 } func seek(_ seconds: Double) { pausedAt = max(0, seconds) startHost = mach_absolute_time() lastFrame = -1 // force next UI update } func applyFPS() { lastFrame = -1 } // next tick will refresh string // MARK: - Tick on background queue private func tick() { let s = now() let str = formatter.string(from: s as NSNumber) ?? String(format: "%.3f", s) let display = "\(str) s" DispatchQueue.main.async { [weak self] in self?.timeString = display } } private func now() -> Double { guard running else { return pausedAt } let delta = mach_absolute_time() &- startHost return pausedAt + Double(delta) * Self.secsPerTick } } nonisolated struct RapidUIUpdateTestDocument: FileDocument { var text: String init(text: String = "Hello, world!") { self.text = text } static let readableContentTypes = [ UTType(importedAs: "com.example.plain-text") ] init(configuration: ReadConfiguration) throws { guard let data = configuration.file.regularFileContents, let string = String(data: data, encoding: .utf8) else { throw CocoaError(.fileReadCorruptFile) } text = string } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { let data = text.data(using: .utf8)! return .init(regularFileWithContents: data) } }
1
0
663
Nov ’25
iPhone 17, IOS 26 - No option to enable ‘Processor Trace’
According to the documentation for Processor Trace, it should be available on the iPhone 16 or later. Going off of the Optimize CPU performance with Instruments WWDC session, the toggle for it should be under Developer > Performance, but I don’t see this option anywhere on my iPhone 17. I can’t run a Processor Trace in Instruments without this feature turned on, because it claims my iPhone’s CPU is unsupported. Has anyone else managed to enable Processor Trace on the A19 chips?
5
1
1.3k
Oct ’25
How do I capture localhost traffic in instruments?
I'm currently exploring Instruments for profiling and tracing on macOS 15.6.1. I know there is the "network connections" instrument which records TCP/UDP information, however it seems to not include the "lo0" (loopback) interface. Is there a way to configure it so that localhost traffic is included in the recording? as the application I'm tracing uses that and I want that information to be included in traces. The documentation for network-interface-detection schema makes no mention of how it detects interfaces. Thanks in advance.
8
0
1.5k
Sep ’25
Regarding the issue of Xcode not displaying Apple Watch devices
My version is iOS 18.6.2 (22G100), watchOS 10.6.1 (21U580), macOS 15.3.1 (24D70), Xcode Version 16.4 (16F6). My iPhone can connect to Xcode and complete app installation testing. I have connected the iPhone to Xcode via USB, and both the iPhone and Apple Watch have been set to trust this device. The iPhone has Developer Mode enabled, but I cannot find Developer Mode in the Privacy & Security settings on the Apple Watch. As shown in the image, the Devices section in Xcode's Developer Documentation displays my iPhone but not the Apple Watch. However, the Open Console for the displayed iPhone shows my Apple Watch—actually two of them, though I only have one Apple Watch (the other might be from a previous backup). The iPhone app installs and tests normally, but the Apple Watch app cannot select a target device and fails to start installation. How can I resolve this issue?
1
0
596
Sep ’25
Where is the instruments command line tool?
I was reading through this documentation about instruments command line tool https://help.apple.com/instruments/mac/current/#/devb14ffaa5 and how it can be launched from the command line. However, unlike what the documentation states, there's no such instruments command anywhere on my macos M1 (OS version 15.6). That command gives: $> instruments zsh: command not found: instruments I do have XCode installed which has the Instruments.App (GUI app) but not the command line utility: $> ls Xcode.app/Contents/Applications/ ... Instruments.app Is that linked documentation up-to-date (it does say "latest" in the URL)? Is there some other way to install this command line utility?
3
0
963
Aug ’25
Instruments Failure in Xcode 16.4
Updated Xcode from 16.2 to 16.4, running Time Profile in Instruments, it launches the trace, but does not install or load on connected device, breaks the functionality. I am unable to debug... ERROR: Connection with the remote side was unexpectedly closed : <dictionary: 0x1f3c8b6d0> { count = 1, transaction: 0, voucher = 0x0, contents = "XPCErrorDescription" => <string: 0x1f3c8b850> { length = 22, contents = "Connection interrupted" } } Domain: IXRemoteErrorDomain Code: 6 User Info: { DVTErrorCreationDateKey = "2025-08-09 00:47:53 +0000"; } -- Connection with the remote side was unexpectedly closed : <dictionary: 0x1f3c8b6d0> { count = 1, transaction: 0, voucher = 0x0, contents = "XPCErrorDescription" => <string: 0x1f3c8b850> { length = 22, contents = "Connection interrupted" } } Domain: IXRemoteErrorDomain Code: 6 IOS 18.5
1
0
1k
Aug ’25
Widget Memory Limit - Per Widget Kind/Size or Per Target?
I am building a widget that supports 2 different widget kinds, each supporting systemSmall, systemMedium, and systemLarge size families. My widget does download and display images so I expect memory usage to be on the higher end, but in debugging some memory issues, I notice that when I build my widget scheme to a physical device, things start off reasonable at ~12MB of memory usage. But as I change the widgets intent, add the other widget kind, or add different widget size families, this memory usage grows until it ultimately hits the 30MB cap. My question is, is the 30MB memory limit spread across all my supported widget kinds/sizes? Or does each individual widget get its own 30MB cap? i.e., if I have systemMedium Widget A and systemLarge Widget B, are they sharing that 30MB memory limit?
1
0
299
Aug ’25
Question about Metrics Analysis in Xcode 26
Hello, I have recently been using the new Power Profiler tool introduced in Xcode 26 to analyze the power consumption of my app. My app primarily operates in the background. During a profiling session of 5 hours and 30 minutes, I observed that the app was active in the background for 2 hours and 30 minutes, while it remained in a suspended state for the remaining 3 hours. While the Power Profiler allows me to identify spikes in CPU, networking, and other resource usage at specific points, it is difficult to determine whether these values are objectively considered high. For example, in my case, the total QoS Execution Time of CPU Impact recorded during the 5 hours and 30 minutes was 12.18 seconds. I am wondering whether this is considered a good metric. Could you please advise on the following points? 1. Is there a commonly accepted or recommended ratio between app active time and CPU time that developers should aim for? 2. Are there any guidelines or reference materials on how to interpret CPU usage and other resource metrics for apps that primarily run in the background? Any insights or advice would be greatly appreciated. Thank you.
1
0
468
Aug ’25
React native app crash on TestFlight
Good day everyone. I have a react native app which works on dev mode on my device - Iphone 13 pro version: 18.5, but when deployed to TestFlight and installed on same device it crashes when ever I click on any TextInput. I downloaded the crash file but finding it difficult to pinpoint the problem. I want to know what the problem is, if it's related to an installed package or code base or any other. Any help will be appreciated!!! Thanks. crashlog.crash
3
0
251
Jul ’25
Datadog Mobile Vitals equivalent in Instruments
Hello We use Datadog Mobile Vitals in our app and I'm trying to run some tools in Instruments for comparison. I'm not sure what tool should I use for some of those metrics: Slow Renders Description: With slow renders data, you can monitor which views are taking longer than 16ms or 60Hz to render. Instruments equivalent: Hangs including microhangs (?) CPU ticks per second Description: RUM tracks CPU ticks per second for each view and the CPU utilization over the course of a session. The recommended range is <40 for good and <80 for moderate. Instruments equivalent: CPU Profiler (?) Frozen Frames - Description: Frames that take longer than 700ms to render appear as stuck and unresponsive in your application. These are classified as frozen frames. Instruments equivalent: Hangs with > 500ms (?) Memory Utilization Description: The amount of physical memory used by your application in bytes for each view, over the course of a session. The recommended range is <200MB for good and <400MB for moderate. Instruments equivalent: Allocation (?)
0
0
458
Jul ’25
Request for PMU Counter Support on Context Switches in Instruments
Hi, My name is Hani Nemati, and I work at Microsoft, where we support several macOS applications such as Microsoft Edge and Teams. I’m also the primary contributor to Microsoft Performance Tools for Apple (https://github.com/microsoft/Microsoft-Performance-Tools-Apple), an open-source project aimed at improving trace analysis across platforms. We are exploring ways to enhance our performance tracing capabilities on macOS and are particularly interested in the ability to attach PMU (Performance Monitoring Unit) counters to context switch events during trace collection. For reference, this capability is supported on Linux via LTTng using the add-context option (https://lttng.org/man/1/lttng-add-context/v2.13), and on Windows through Windows Performance Recorder (WPR), which allows PMU counters to be added at the start and end of context switches, enabling delta computation. Would it be possible to introduce similar support in Instruments for macOS? I’d appreciate any guidance or suggestions you might have on this request. Thank you, Hani Nemati Email: hanemati@microsoft
2
0
698
Jul ’25
What is causing the Freeze in this SwiftUI View?
I made a small project that freezes after the following steps: Run the app Turn on VoiceOver Tap on "Header" once so it is read out loud Turn off VoiceOver Scroll up and down really quickly Using the Time Profiler, the items in the Main Thread followed by significant drops are: 19.11 s 85.1% 0 s closure #2 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) 13.05 s 58.1% 4.00 ms ViewGraph.updateOutputs(async:) 7.97 s 35.5% 83.00 ms AG::Graph::UpdateStack::update() 5.76 s 25.6% 19.00 ms LayoutScrollableTransform.updateValue() 1.73 s  7.7% 2.00 ms specialized NativeDictionary.setValue(:forKey:isUnique:) 579.00 ms  2.6% 58.00 ms 0x100a8c908 311.00 ms  1.4% 165.00 ms __thread_stack_pcs I see the memory usage increase by about 0.6 MB per second while frozen. And there are a few things that prevent the freeze: Changing LazyVStack for VStack Removing the VStack from the Section Removing the header: parameter from the Section Reducing the range of the ForEach Move the Text(verbatim: "Text at same level as ForEach containing Section") outside of the LazyVStack However, these are all things I need to keep for my actual app. So what is causing this hang? Am I using SwiftUI in any way it's not intended to be used? import SwiftUI struct ContentView: View { var body: some View { VStack { VStack(alignment: .leading) { Image(systemName: "pencil.circle.fill") Text("Title") Text("Label") } ScrollView { LazyVStack { Section { VStack { ForEach(0..<70) { _ in Text(verbatim: "A") } } } header: { Text(verbatim: "Header") } Text(verbatim: "Text at same level as ForEach containing Section") } } } } } AppDelegate: @main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let window = UIWindow(frame: UIScreen.main.bounds) window.rootViewController = UINavigationController(rootViewController: MainViewController()) window.makeKeyAndVisible() self.window = window return true } } MainViewController: import UIKit import SwiftUI final class MainViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let swiftUIView = ContentView() let hostingController = UIHostingController(rootView: swiftUIView) addChild(hostingController) hostingController.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(hostingController.view) NSLayoutConstraint.activate([ hostingController.view.topAnchor.constraint(equalTo: view.topAnchor), hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) hostingController.didMove(toParent: self) view.backgroundColor = .white } }
1
0
324
Jun ’25
Instruments Time Profiler Call Stacks & Percentages Differ Between Xcode 16.0 (16A242d) and 16.3 (16E140) – How Can I Get Consistent Metrics?
I’m seeing inconsistent call stacks and usage percentages in the Time Profiler between two Instruments builds: • Xcode 16.0’s Instruments Version 16.0 (16A242d) • Xcode 16.3’s Instruments Version 16.0 (16E140) When I open an old .trace file recorded with the 16A242d profiler in the newer 16E140 Instruments, the call trees and percentage breakdowns no longer match. It looks like the latest Instruments now exposes or collapses different frames (e.g. system libraries, inline code) by default. I rely on these call stacks as a baseline to track performance regressions and verify optimizations over time. Unfortunately, every Xcode/Instruments update changes what I see, making it impossible to compare profiles across versions. My questions: Is there a way in Instruments 16.0 (16E140) to restore the exact call-tree view and percentage calculations that 16A242d produced? Failing that, is there a recommended workflow or tool for capturing CPU profiles in a way that remains stable and comparable, regardless of Xcode or Instruments version? Any guidance on achieving consistent, version-independent performance measurements would be greatly appreciated!
2
0
485
Jun ’25
(iOS 26) - PowerProfiler trace file cannot be opened
I kept CoreLocation’s startUpdatingLocation running for a full day and used Performance trace - PowerProfiler to track the power usage during that time. The trace file was successfully generated on the iOS device, and I later transferred it to my MacBook. However, when I tried to open the .atrc file, I received the following warning: The document cannot be imported because of an error: File ‘/Users/jun/Downloads/PowerProfiler_25-06-16_181049_to_25-06-17_091037_001.atrc’ doesn’t contain any events. Why is this happening? Is there a known issue with PowerProfiler in iOS 26, or am I missing something in the tracing setup? Note: The .aar file and the extracted .atrc file are not attached here, as forum uploads do not support these formats.
1
0
456
Jun ’25
RealityKit Trace Metric Max/Range for VisionOS app
Hi Nathaniel, I spoke with you yesterday in the WWDC lab. Thanks for chatting with me! Is it possible to get a link to a doc that has some key metrics I'd find in a RealityKit trace so I know if that metric is exceeding limits and probably causing a problem? Right now, I just see numbers and have no idea if a metric is high or low :). This is specifically for a VisionOS app. Thanks, Bob
3
0
283
Jun ’25
Cannot get Instruments to profile my apps
Hi, I need help to get Instruments running to profile my application. I tried to profile my main app (Qt-5.15-Framework, c++, Intel-arch only) from Xcode. My app starts and Instruments runs time profiler or Leaks for about 15 seconds and the quits. No crash, no message nothing. This has been happening for a while on my Mac Studio M1 Max running macOS 14.7.6 and Xcode 15.4 IDE with a toolchain from Xcode 14.3 for the qmake (qt) project. However, this also happens if i set up a new vanilla Swift UI project from scratch wihtout any Qt stuff. In addition to the Mac Studio I also have Mac Book Pro M4 running macOS 15.5 and Xcode 16.4. On that machine I get the same results, no matter if I try Instruments on my qt project or a vanilla SwiftUI project. Also it does not make a difference if I change the toolchain with: sudo xcode-select -s /Applications/Xcode_143.app or sudo xcode-select -s /Applications/Xcode_164.app. Same results in either case. I also tried switching to Debug build in the editing the scheme for profiling, but got no better results. I also tried to lauch Instruments from Xcode using the Open Developer Tool menu entry, but got no better results. When I start Instruments first, run my program in Xcode and attach to it, I get the same results. Do you have any advice what to check for or to setup, maybe in signing or such? I am probably missing something basic. Thanks in advance
4
0
691
Jun ’25
Instruments Network: Background URLSession instance appears not to complete
As stated in the title. I am running the following code. Each time I perform an API call, I create a new instance of URLSession and use a background-configured session to allow background API calls. ` Code being executed: import Foundation // Model definitions struct RandomUserResponse: Codable { let results: [RandomUser] } struct RandomUser: Codable { let name: Name let email: String } struct Name: Codable { let first: String let last: String } // Fetcher class class RandomUserFetcher: NSObject, URLSessionDataDelegate { private var receivedData = Data() private var completion: ((RandomUser?) -&gt; Void)? private var session: URLSession! func fetchRandomUserInBackground(completion: @escaping (RandomUser?) -&gt; Void) { self.completion = completion let configuration = URLSessionConfiguration.background(withIdentifier: "com.example.randomuser.bg") session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil) let url = URL(string: "https://randomuser.me/api/" )! let task = session.dataTask(with: url) task.resume() } // Data received func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { receivedData.append(data) } // Completion func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { defer { self.session.finishTasksAndInvalidate() } guard error == nil else { print("Error: \(error!)") completion?(nil) return } do { let response = try JSONDecoder().decode(RandomUserResponse.self, from: receivedData) completion?(response.results.first) } catch { print("Decoding error: \(error)") completion?(nil) } } }` Called in viewDidLoad, etc.: let fetcher = RandomUserFetcher() fetcher.fetchRandomUserInBackground { user in if let user = user { print("Name: \(user.name.first) \(user.name.last), Email: \(user.email)") } else { print("Failed to fetch random user.") } } In Instruments' Network instrument, I focus on my app's process, use 'Command + 3', and switch to 'List: URLSessionTasks'. Even though didCompleteWithError is called and the API call fully completes, the Duration keeps increasing, and the Success column remains '-' (neither 'Yes' nor 'No'). For non-background URLSessions, the session shows up as 'unnamed session', but for background URLSessions, it appears as 'unnamed background session 1 (XXXXXX-XXXXXX-XXXXX)'. Does this mean the session is not actually being completed? I've checked Debug Memory Graph and confirmed there is no NSURLSession memory leak, but is it possible that the app is somehow still retaining session information internally? I also suspect that Instruments may not be able to fully track background URLSession tasks.
3
0
532
Jun ’25
CoreImage memory build up on real device but not on simulator
I'm trying to benchmark a Core Image filter chains memory footprint and notice a weird quirk in instruments. On a real device, even with a simple Core Image chain, the memory balloons each time I ran the filter. See attached screen shots. Running on iPhone 17 Pro: Running on simulator (M2 Macbook Pro) As you can see there's a huge build up of 4MB "VM: IOSurface" memory on the real device, but the simulator seems to clean it up correctly. Here's my basic code: func processImage() { guard let inputImage = ContentViewModel.loadImageFromBundle(name: "kitty.HEIC") else { print("Failed to load sample_image from bundle") return } var outputImage = inputImage outputImage = outputImage.applyingFilter("CIBloom", parameters: [ kCIInputRadiusKey: 20, kCIInputIntensityKey: 0.8 ]) DispatchQueue.global(qos: .userInitiated).async { let data = self.context.jpegRepresentation(of: outputImage, colorSpace: CGColorSpace(name: CGColorSpace.sRGB)!) if let data = data, let uiImage = UIImage(data: data) { DispatchQueue.main.async { self.displayImage = Image(uiImage: uiImage) } } } } Why is this happening? Seems like a bug to me or I need to release an object. At the very least makes it challenging to measure memory usage. Any help is greatly appreciated. Alex
Replies
1
Boosts
0
Views
728
Activity
Nov ’25
SwifUI Performance With Rapid UI Updates
The code below is a test to trigger UI updates every 30 seconds. I'm trying to keep most work off main and only push to main once I have the string (which is cached). Why is updating SwiftUI 30 times per second so expensive? This code causes 10% CPU on my M4 Mac, but comment out the following line: Text(model.timeString) and it's 0% CPU. The reason why I think I have too much work on main is because of this from instruments. But I'm no instruments expert. import SwiftUI import UniformTypeIdentifiers @main struct RapidUIUpdateTestApp: App { var body: some Scene { DocumentGroup(newDocument: RapidUIUpdateTestDocument()) { file in ContentView(document: file.$document) } } } struct ContentView: View { @Binding var document: RapidUIUpdateTestDocument @State private var model = PlayerModel() var body: some View { VStack(spacing: 16) { Text(model.timeString) // only this changes .font(.system(size: 44, weight: .semibold, design: .monospaced)) .transaction { $0.animation = nil } // no implicit animations HStack { Button(model.running ? "Pause" : "Play") { model.running ? model.pause() : model.start() } Button("Reset") { model.seek(0) } Stepper("FPS: \(Int(model.fps))", value: $model.fps, in: 10...120, step: 1) .onChange(of: model.fps) { _, _ in model.applyFPS() } } } .padding() .onAppear { model.start() } .onDisappear { model.stop() } } } @Observable final class PlayerModel { // Publish ONE value to minimize invalidations var timeString: String = "0.000 s" var fps: Double = 30 var running = false private var formatter: NumberFormatter = { let f = NumberFormatter() f.minimumFractionDigits = 3 f.maximumFractionDigits = 3 return f }() @ObservationIgnored private let q = DispatchQueue(label: "tc.timer", qos: .userInteractive) @ObservationIgnored private var timer: DispatchSourceTimer? @ObservationIgnored private var startHost: UInt64 = 0 @ObservationIgnored private var pausedAt: Double = 0 @ObservationIgnored private var lastFrame: Int = -1 // cache timebase once private static let secsPerTick: Double = { var info = mach_timebase_info_data_t() mach_timebase_info(&info) return Double(info.numer) / Double(info.denom) / 1_000_000_000.0 }() func start() { guard timer == nil else { running = true; return } let desiredUIFPS: Double = 30 // or 60, 24, etc. let periodNs = UInt64(1_000_000_000 / desiredUIFPS) running = true startHost = mach_absolute_time() let t = DispatchSource.makeTimerSource(queue: q) // ~30 fps, with leeway to let the kernel coalesce wakeups t.schedule( deadline: .now(), repeating: .nanoseconds(Int(periodNs)), // 33_333_333 ns ≈ 30 fps leeway: .milliseconds(30) // allow coalescing ) t.setEventHandler { [weak self] in self?.tick() } timer = t t.resume() } func pause() { guard running else { return } pausedAt = now() running = false } func stop() { timer?.cancel() timer = nil running = false pausedAt = 0 lastFrame = -1 } func seek(_ seconds: Double) { pausedAt = max(0, seconds) startHost = mach_absolute_time() lastFrame = -1 // force next UI update } func applyFPS() { lastFrame = -1 } // next tick will refresh string // MARK: - Tick on background queue private func tick() { let s = now() let str = formatter.string(from: s as NSNumber) ?? String(format: "%.3f", s) let display = "\(str) s" DispatchQueue.main.async { [weak self] in self?.timeString = display } } private func now() -> Double { guard running else { return pausedAt } let delta = mach_absolute_time() &- startHost return pausedAt + Double(delta) * Self.secsPerTick } } nonisolated struct RapidUIUpdateTestDocument: FileDocument { var text: String init(text: String = "Hello, world!") { self.text = text } static let readableContentTypes = [ UTType(importedAs: "com.example.plain-text") ] init(configuration: ReadConfiguration) throws { guard let data = configuration.file.regularFileContents, let string = String(data: data, encoding: .utf8) else { throw CocoaError(.fileReadCorruptFile) } text = string } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { let data = text.data(using: .utf8)! return .init(regularFileWithContents: data) } }
Replies
1
Boosts
0
Views
663
Activity
Nov ’25
iPhone 17, IOS 26 - No option to enable ‘Processor Trace’
According to the documentation for Processor Trace, it should be available on the iPhone 16 or later. Going off of the Optimize CPU performance with Instruments WWDC session, the toggle for it should be under Developer > Performance, but I don’t see this option anywhere on my iPhone 17. I can’t run a Processor Trace in Instruments without this feature turned on, because it claims my iPhone’s CPU is unsupported. Has anyone else managed to enable Processor Trace on the A19 chips?
Replies
5
Boosts
1
Views
1.3k
Activity
Oct ’25
Excessive red flags in SwiftUI Instruments on iOS 26
I'm running the new iOS 26 SwiftUI Instruments and seeing a lot of red/hitches, even with Apple's own Backyard Birds sample project. Is anyone else experiencing this? Not sure if it's a general iOS 26 issue or specific to my device (iPhone SE 2nd gen). Would appreciate hearing if others are seeing similar results.
Replies
1
Boosts
0
Views
1k
Activity
Oct ’25
RealityKit Debugger unavailable
Hi team, I'm looking for the RealityKit debugger in Xcode 26 beta 3. I'm running a RealityKit app on my iPad running iPadOS 26 b3, but the debugger option is not there in Xcode.
Replies
3
Boosts
1
Views
808
Activity
Oct ’25
How do I capture localhost traffic in instruments?
I'm currently exploring Instruments for profiling and tracing on macOS 15.6.1. I know there is the "network connections" instrument which records TCP/UDP information, however it seems to not include the "lo0" (loopback) interface. Is there a way to configure it so that localhost traffic is included in the recording? as the application I'm tracing uses that and I want that information to be included in traces. The documentation for network-interface-detection schema makes no mention of how it detects interfaces. Thanks in advance.
Replies
8
Boosts
0
Views
1.5k
Activity
Sep ’25
Regarding the issue of Xcode not displaying Apple Watch devices
My version is iOS 18.6.2 (22G100), watchOS 10.6.1 (21U580), macOS 15.3.1 (24D70), Xcode Version 16.4 (16F6). My iPhone can connect to Xcode and complete app installation testing. I have connected the iPhone to Xcode via USB, and both the iPhone and Apple Watch have been set to trust this device. The iPhone has Developer Mode enabled, but I cannot find Developer Mode in the Privacy &amp; Security settings on the Apple Watch. As shown in the image, the Devices section in Xcode's Developer Documentation displays my iPhone but not the Apple Watch. However, the Open Console for the displayed iPhone shows my Apple Watch—actually two of them, though I only have one Apple Watch (the other might be from a previous backup). The iPhone app installs and tests normally, but the Apple Watch app cannot select a target device and fails to start installation. How can I resolve this issue?
Replies
1
Boosts
0
Views
596
Activity
Sep ’25
Where is the instruments command line tool?
I was reading through this documentation about instruments command line tool https://help.apple.com/instruments/mac/current/#/devb14ffaa5 and how it can be launched from the command line. However, unlike what the documentation states, there's no such instruments command anywhere on my macos M1 (OS version 15.6). That command gives: $> instruments zsh: command not found: instruments I do have XCode installed which has the Instruments.App (GUI app) but not the command line utility: $> ls Xcode.app/Contents/Applications/ ... Instruments.app Is that linked documentation up-to-date (it does say "latest" in the URL)? Is there some other way to install this command line utility?
Replies
3
Boosts
0
Views
963
Activity
Aug ’25
Instruments Failure in Xcode 16.4
Updated Xcode from 16.2 to 16.4, running Time Profile in Instruments, it launches the trace, but does not install or load on connected device, breaks the functionality. I am unable to debug... ERROR: Connection with the remote side was unexpectedly closed : <dictionary: 0x1f3c8b6d0> { count = 1, transaction: 0, voucher = 0x0, contents = "XPCErrorDescription" => <string: 0x1f3c8b850> { length = 22, contents = "Connection interrupted" } } Domain: IXRemoteErrorDomain Code: 6 User Info: { DVTErrorCreationDateKey = "2025-08-09 00:47:53 +0000"; } -- Connection with the remote side was unexpectedly closed : <dictionary: 0x1f3c8b6d0> { count = 1, transaction: 0, voucher = 0x0, contents = "XPCErrorDescription" => <string: 0x1f3c8b850> { length = 22, contents = "Connection interrupted" } } Domain: IXRemoteErrorDomain Code: 6 IOS 18.5
Replies
1
Boosts
0
Views
1k
Activity
Aug ’25
Widget Memory Limit - Per Widget Kind/Size or Per Target?
I am building a widget that supports 2 different widget kinds, each supporting systemSmall, systemMedium, and systemLarge size families. My widget does download and display images so I expect memory usage to be on the higher end, but in debugging some memory issues, I notice that when I build my widget scheme to a physical device, things start off reasonable at ~12MB of memory usage. But as I change the widgets intent, add the other widget kind, or add different widget size families, this memory usage grows until it ultimately hits the 30MB cap. My question is, is the 30MB memory limit spread across all my supported widget kinds/sizes? Or does each individual widget get its own 30MB cap? i.e., if I have systemMedium Widget A and systemLarge Widget B, are they sharing that 30MB memory limit?
Replies
1
Boosts
0
Views
299
Activity
Aug ’25
Question about Metrics Analysis in Xcode 26
Hello, I have recently been using the new Power Profiler tool introduced in Xcode 26 to analyze the power consumption of my app. My app primarily operates in the background. During a profiling session of 5 hours and 30 minutes, I observed that the app was active in the background for 2 hours and 30 minutes, while it remained in a suspended state for the remaining 3 hours. While the Power Profiler allows me to identify spikes in CPU, networking, and other resource usage at specific points, it is difficult to determine whether these values are objectively considered high. For example, in my case, the total QoS Execution Time of CPU Impact recorded during the 5 hours and 30 minutes was 12.18 seconds. I am wondering whether this is considered a good metric. Could you please advise on the following points? 1. Is there a commonly accepted or recommended ratio between app active time and CPU time that developers should aim for? 2. Are there any guidelines or reference materials on how to interpret CPU usage and other resource metrics for apps that primarily run in the background? Any insights or advice would be greatly appreciated. Thank you.
Replies
1
Boosts
0
Views
468
Activity
Aug ’25
React native app crash on TestFlight
Good day everyone. I have a react native app which works on dev mode on my device - Iphone 13 pro version: 18.5, but when deployed to TestFlight and installed on same device it crashes when ever I click on any TextInput. I downloaded the crash file but finding it difficult to pinpoint the problem. I want to know what the problem is, if it's related to an installed package or code base or any other. Any help will be appreciated!!! Thanks. crashlog.crash
Replies
3
Boosts
0
Views
251
Activity
Jul ’25
Datadog Mobile Vitals equivalent in Instruments
Hello We use Datadog Mobile Vitals in our app and I'm trying to run some tools in Instruments for comparison. I'm not sure what tool should I use for some of those metrics: Slow Renders Description: With slow renders data, you can monitor which views are taking longer than 16ms or 60Hz to render. Instruments equivalent: Hangs including microhangs (?) CPU ticks per second Description: RUM tracks CPU ticks per second for each view and the CPU utilization over the course of a session. The recommended range is <40 for good and <80 for moderate. Instruments equivalent: CPU Profiler (?) Frozen Frames - Description: Frames that take longer than 700ms to render appear as stuck and unresponsive in your application. These are classified as frozen frames. Instruments equivalent: Hangs with > 500ms (?) Memory Utilization Description: The amount of physical memory used by your application in bytes for each view, over the course of a session. The recommended range is <200MB for good and <400MB for moderate. Instruments equivalent: Allocation (?)
Replies
0
Boosts
0
Views
458
Activity
Jul ’25
Request for PMU Counter Support on Context Switches in Instruments
Hi, My name is Hani Nemati, and I work at Microsoft, where we support several macOS applications such as Microsoft Edge and Teams. I’m also the primary contributor to Microsoft Performance Tools for Apple (https://github.com/microsoft/Microsoft-Performance-Tools-Apple), an open-source project aimed at improving trace analysis across platforms. We are exploring ways to enhance our performance tracing capabilities on macOS and are particularly interested in the ability to attach PMU (Performance Monitoring Unit) counters to context switch events during trace collection. For reference, this capability is supported on Linux via LTTng using the add-context option (https://lttng.org/man/1/lttng-add-context/v2.13), and on Windows through Windows Performance Recorder (WPR), which allows PMU counters to be added at the start and end of context switches, enabling delta computation. Would it be possible to introduce similar support in Instruments for macOS? I’d appreciate any guidance or suggestions you might have on this request. Thank you, Hani Nemati Email: hanemati@microsoft
Replies
2
Boosts
0
Views
698
Activity
Jul ’25
What is causing the Freeze in this SwiftUI View?
I made a small project that freezes after the following steps: Run the app Turn on VoiceOver Tap on "Header" once so it is read out loud Turn off VoiceOver Scroll up and down really quickly Using the Time Profiler, the items in the Main Thread followed by significant drops are: 19.11 s 85.1% 0 s closure #2 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) 13.05 s 58.1% 4.00 ms ViewGraph.updateOutputs(async:) 7.97 s 35.5% 83.00 ms AG::Graph::UpdateStack::update() 5.76 s 25.6% 19.00 ms LayoutScrollableTransform.updateValue() 1.73 s  7.7% 2.00 ms specialized NativeDictionary.setValue(:forKey:isUnique:) 579.00 ms  2.6% 58.00 ms 0x100a8c908 311.00 ms  1.4% 165.00 ms __thread_stack_pcs I see the memory usage increase by about 0.6 MB per second while frozen. And there are a few things that prevent the freeze: Changing LazyVStack for VStack Removing the VStack from the Section Removing the header: parameter from the Section Reducing the range of the ForEach Move the Text(verbatim: "Text at same level as ForEach containing Section") outside of the LazyVStack However, these are all things I need to keep for my actual app. So what is causing this hang? Am I using SwiftUI in any way it's not intended to be used? import SwiftUI struct ContentView: View { var body: some View { VStack { VStack(alignment: .leading) { Image(systemName: "pencil.circle.fill") Text("Title") Text("Label") } ScrollView { LazyVStack { Section { VStack { ForEach(0..<70) { _ in Text(verbatim: "A") } } } header: { Text(verbatim: "Header") } Text(verbatim: "Text at same level as ForEach containing Section") } } } } } AppDelegate: @main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let window = UIWindow(frame: UIScreen.main.bounds) window.rootViewController = UINavigationController(rootViewController: MainViewController()) window.makeKeyAndVisible() self.window = window return true } } MainViewController: import UIKit import SwiftUI final class MainViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let swiftUIView = ContentView() let hostingController = UIHostingController(rootView: swiftUIView) addChild(hostingController) hostingController.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(hostingController.view) NSLayoutConstraint.activate([ hostingController.view.topAnchor.constraint(equalTo: view.topAnchor), hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) hostingController.didMove(toParent: self) view.backgroundColor = .white } }
Replies
1
Boosts
0
Views
324
Activity
Jun ’25
Instruments Time Profiler Call Stacks & Percentages Differ Between Xcode 16.0 (16A242d) and 16.3 (16E140) – How Can I Get Consistent Metrics?
I’m seeing inconsistent call stacks and usage percentages in the Time Profiler between two Instruments builds: • Xcode 16.0’s Instruments Version 16.0 (16A242d) • Xcode 16.3’s Instruments Version 16.0 (16E140) When I open an old .trace file recorded with the 16A242d profiler in the newer 16E140 Instruments, the call trees and percentage breakdowns no longer match. It looks like the latest Instruments now exposes or collapses different frames (e.g. system libraries, inline code) by default. I rely on these call stacks as a baseline to track performance regressions and verify optimizations over time. Unfortunately, every Xcode/Instruments update changes what I see, making it impossible to compare profiles across versions. My questions: Is there a way in Instruments 16.0 (16E140) to restore the exact call-tree view and percentage calculations that 16A242d produced? Failing that, is there a recommended workflow or tool for capturing CPU profiles in a way that remains stable and comparable, regardless of Xcode or Instruments version? Any guidance on achieving consistent, version-independent performance measurements would be greatly appreciated!
Replies
2
Boosts
0
Views
485
Activity
Jun ’25
(iOS 26) - PowerProfiler trace file cannot be opened
I kept CoreLocation’s startUpdatingLocation running for a full day and used Performance trace - PowerProfiler to track the power usage during that time. The trace file was successfully generated on the iOS device, and I later transferred it to my MacBook. However, when I tried to open the .atrc file, I received the following warning: The document cannot be imported because of an error: File ‘/Users/jun/Downloads/PowerProfiler_25-06-16_181049_to_25-06-17_091037_001.atrc’ doesn’t contain any events. Why is this happening? Is there a known issue with PowerProfiler in iOS 26, or am I missing something in the tracing setup? Note: The .aar file and the extracted .atrc file are not attached here, as forum uploads do not support these formats.
Replies
1
Boosts
0
Views
456
Activity
Jun ’25
RealityKit Trace Metric Max/Range for VisionOS app
Hi Nathaniel, I spoke with you yesterday in the WWDC lab. Thanks for chatting with me! Is it possible to get a link to a doc that has some key metrics I'd find in a RealityKit trace so I know if that metric is exceeding limits and probably causing a problem? Right now, I just see numbers and have no idea if a metric is high or low :). This is specifically for a VisionOS app. Thanks, Bob
Replies
3
Boosts
0
Views
283
Activity
Jun ’25
Cannot get Instruments to profile my apps
Hi, I need help to get Instruments running to profile my application. I tried to profile my main app (Qt-5.15-Framework, c++, Intel-arch only) from Xcode. My app starts and Instruments runs time profiler or Leaks for about 15 seconds and the quits. No crash, no message nothing. This has been happening for a while on my Mac Studio M1 Max running macOS 14.7.6 and Xcode 15.4 IDE with a toolchain from Xcode 14.3 for the qmake (qt) project. However, this also happens if i set up a new vanilla Swift UI project from scratch wihtout any Qt stuff. In addition to the Mac Studio I also have Mac Book Pro M4 running macOS 15.5 and Xcode 16.4. On that machine I get the same results, no matter if I try Instruments on my qt project or a vanilla SwiftUI project. Also it does not make a difference if I change the toolchain with: sudo xcode-select -s /Applications/Xcode_143.app or sudo xcode-select -s /Applications/Xcode_164.app. Same results in either case. I also tried switching to Debug build in the editing the scheme for profiling, but got no better results. I also tried to lauch Instruments from Xcode using the Open Developer Tool menu entry, but got no better results. When I start Instruments first, run my program in Xcode and attach to it, I get the same results. Do you have any advice what to check for or to setup, maybe in signing or such? I am probably missing something basic. Thanks in advance
Replies
4
Boosts
0
Views
691
Activity
Jun ’25
Instruments Network: Background URLSession instance appears not to complete
As stated in the title. I am running the following code. Each time I perform an API call, I create a new instance of URLSession and use a background-configured session to allow background API calls. ` Code being executed: import Foundation // Model definitions struct RandomUserResponse: Codable { let results: [RandomUser] } struct RandomUser: Codable { let name: Name let email: String } struct Name: Codable { let first: String let last: String } // Fetcher class class RandomUserFetcher: NSObject, URLSessionDataDelegate { private var receivedData = Data() private var completion: ((RandomUser?) -&gt; Void)? private var session: URLSession! func fetchRandomUserInBackground(completion: @escaping (RandomUser?) -&gt; Void) { self.completion = completion let configuration = URLSessionConfiguration.background(withIdentifier: "com.example.randomuser.bg") session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil) let url = URL(string: "https://randomuser.me/api/" )! let task = session.dataTask(with: url) task.resume() } // Data received func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { receivedData.append(data) } // Completion func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { defer { self.session.finishTasksAndInvalidate() } guard error == nil else { print("Error: \(error!)") completion?(nil) return } do { let response = try JSONDecoder().decode(RandomUserResponse.self, from: receivedData) completion?(response.results.first) } catch { print("Decoding error: \(error)") completion?(nil) } } }` Called in viewDidLoad, etc.: let fetcher = RandomUserFetcher() fetcher.fetchRandomUserInBackground { user in if let user = user { print("Name: \(user.name.first) \(user.name.last), Email: \(user.email)") } else { print("Failed to fetch random user.") } } In Instruments' Network instrument, I focus on my app's process, use 'Command + 3', and switch to 'List: URLSessionTasks'. Even though didCompleteWithError is called and the API call fully completes, the Duration keeps increasing, and the Success column remains '-' (neither 'Yes' nor 'No'). For non-background URLSessions, the session shows up as 'unnamed session', but for background URLSessions, it appears as 'unnamed background session 1 (XXXXXX-XXXXXX-XXXXX)'. Does this mean the session is not actually being completed? I've checked Debug Memory Graph and confirmed there is no NSURLSession memory leak, but is it possible that the app is somehow still retaining session information internally? I also suspect that Instruments may not be able to fully track background URLSession tasks.
Replies
3
Boosts
0
Views
532
Activity
Jun ’25