What Apple's Performance Team Said in the WWDC26 Lab
At WWDC26, Apple put five of its own Power & Performance engineers on camera for an hour of live developer Q&A and answered the questions developers actually file: why an idle SwiftUI screen still drains battery, how to fake an old device you do not own, what the biggest power mistake in shipping apps really is. The polished sessions tell you how a framework works. The Group Lab told you how Apple’s own teams use it. This post pulls the field guidance worth keeping.
A note on sourcing: Apple published this lab video without captions. I transcribed it locally with Whisper, so every lab quote below is a paraphrase from that transcription, not a verbatim Apple transcript. I attribute speakers by the names and roles given in the lab’s introductions, inferred from conversational context: Terry on performance, Yanni on MetricKit, Kaspar on Instruments, Kunal on CoreOS Power, and Marco on the render pipeline, with Cole moderating.1 Where the lab guidance touches something Apple documents formally, I cite the doc or the matching session and flag it.
The untethered power-trace workflow that anchors much of the lab’s advice starts around 11:42.
TL;DR
- The old Objective-C MetricKit surface is on its way out:
MXMetricManageris formally deprecated as of 27.0, and the new metric and diagnostic types ship exclusively on the new Swift API.23 - Xcode Organizer now offers Metric Goals, baselines drawn from your own history and from apps Apple judges similar to yours, covering launch, hang rate, disk writes, battery, storage, and hitches.4
- The power workflow the team recommends is the Power Profiler mode of Performance Trace: record an untethered
.aartrace on the device, share it to your Mac, and read the CPU, GPU, display, and networking power lanes in Instruments. The feature shipped with iOS 26, not iOS 27.5 - Apple Intelligence work runs mostly on the Neural Engine and Private Cloud Compute, so CPU-bound app work can often run alongside it without contention. Chunk background tasks so the system can pause and resume them.1
- The biggest power mistake the team sees is insufficient telemetry: developers optimize the wrong thing because they never measured the right one.1
Why a lab is worth transcribing
Apple’s recorded sessions are scripted, rehearsed, and edited. A Group Lab is none of those things. It is engineers reacting in real time to questions from working developers, and the answers carry the texture of field experience: the war stories, the “we see this all the time” pattern recognition, the small admissions about what is hard. That texture is exactly what a polished session sands off.
The catch is that Apple published the lab without captions. To quote it at all, I ran the video through local speech recognition, which means proper nouns and API spellings come out approximate. I have reconciled every technical claim against Apple’s documentation or the matching WWDC session before stating it as fact, and I keep the lab’s own words as clearly labeled paraphrase. Treat the engineers’ framing as authoritative on intent and priority, and treat the citations as the source of record on specifics.
The field-data story: MetricKit is being rebuilt
Yanni, who works on MetricKit, called it a very big year for the framework and described a ground-up rebuild around a new Swift-first API. The motivation he gave: the Swift API is built for Swift concurrency, and it was designed for new data granularity, where developers get not only the daily metric report but smaller breakdowns over shorter intervals. Crucially, he noted that new diagnostic and metric types ship only on the new API, which he framed as the real reason to migrate.1
Apple’s documentation backs the harder edge of that claim. MXMetricManager, the entry point developers have used since MetricKit shipped, is now formally deprecated: Apple’s reference page marks it deprecated at 27.0 and directs developers to use MetricManager instead.2 WWDC26 session 222 makes the exclusivity explicit, the new metric and diagnostic types live on the new Swift API and do not backfill to the old one.3 If you are still calling MXMetricManager, you are not merely on an older style; you are cut off from everything Apple adds going forward.
The lab also surfaced a recurring confusion about where field data comes from and how to read it. Kunal and Yanni drew the line clearly: Instruments gives you deep local profiling on one device at your desk, while Xcode Organizer and MetricKit give you aggregated field telemetry from real users on real devices. The two disagree often, and that disagreement is the point. Kunal described developers who chase a hang they can reproduce in Instruments while Organizer shows the actual top cause of hangs is something else entirely, something that never reproduces at a desk.1
The new lever on the Organizer side is Metric Goals. Kunal flagged them as the single feature he most wanted developers to try before leaving WWDC. Session 258 spells out what they are: recommended targets that Organizer derives “based on technical and functional similarities between your app and other apps,” combined with your own historical baselines, spanning launch time, hang rate, disk writes, battery, storage, and hitches.4 The lab framed the value in human terms. Cole described a developer holding up a video app and asking whether its high power draw is a problem or just the cost of playing video all day. Before Metric Goals, no one could answer. Now the Organizer compares you against similar apps and gives you a baseline to reason from.1
One more piece of field-data hygiene came up, and it is worth stating plainly because developers keep getting it wrong: do not roll your own launch timer. The lab recounted developers inspecting kernel APIs for process-creation time and using that as a launch goalpost. Yanni’s response was that MetricKit and Organizer deliberately do not measure launch that way; they measure the interval the user actually feels. Apple’s documentation confirms the definition: launch time is “the number of milliseconds between the user tapping your icon and when your first screen is drawn,” measured after the static splash screen.6 Your own timer cannot see the moment of the tap, because your process does not exist yet. Apple’s tooling can, and it adds no measurement overhead to your app.
The power workflow the team actually recommends
The most useful procedural advice in the lab was about how to catch power problems that never show up at your desk. Kaspar and Kunal kept returning to one workflow: the untethered trace.
The mechanics, in Kaspar’s framing, are that you disconnect from Instruments, record a trace on the device that can run for multiple hours, then share the file to your Mac and open it in Instruments to analyze it later. The benefit is real-world conditions: you move around, ride real cellular handoffs, let the device get warm, and capture what actually happens instead of what happens in a controlled desk session. Kunal pointed to it as the way to catch a specific bug class, background tasks scheduled when they should not be, which is invisible while you are tethered and watching.1
That workflow is the Power Profiler mode of Performance Trace, and it is worth being precise about its provenance: it is an iOS 26 feature from WWDC25, not new in iOS 27. Apple documents it under “Measuring your app’s power use with Power Profiler.” You enable it under Settings > Developer > Performance Trace, trigger it with a Control Center control, share the resulting .aar file to your Mac, and read power broken down by subsystem across CPU, GPU, display, and networking lanes in Instruments.5 The lab presented it as their recommended go-to, not as a 27 headline. (The genuinely new sibling this year is the lookback collection workflow and the metalperftrace macOS CLI, which I covered in the Metal machine learning post. They are different tools for different jobs; do not conflate them.)
Two more techniques from the power discussion are worth keeping:
- Low Power Mode as a poor-device proxy. Terry offered a trick for developers who own only new hardware but need to know how the app feels on old hardware: turn on Low Power Mode. It slows the CPUs to save battery, which surfaces issues you would otherwise see only on an older device. He added that it doubles as good general optimization practice, because many users run Low Power Mode by choice and your app should still feel good there.1
- Device Conditions for thermal and network simulation. The lab repeatedly mentioned a “condition inducer” for forcing the app into an elevated thermal state or a degraded network link. Apple’s official name for the feature is Device Conditions; the speaker himself was not sure where it lives in Xcode 27. It has historically lived in the Devices window and may be folded into the Device Hub. The lab speaker was careful about what it does and does not do: it artificially induces the throttling behavior of a hot device; it does not actually heat the hardware. So you can observe how your app behaves under thermal pressure, more hitches, more hangs, without baking your phone.1
And a flat rule that came up more than once: never profile on the Simulator. Kaspar noted that the Simulator runs on your Mac, so its performance tells you nothing about device performance regardless of which device you select. Use a physical device for profiling, and lean on MetricKit and Organizer field data to cover the device diversity you cannot buy.1
Performance triage: thermals, AI contention, and chunked work
When the questions turned to triage strategy, three pieces of guidance stood out.
The thermal playbook. A developer asked about an ARKit and Metal app used outdoors in direct sunlight, where the device runs hot constantly. Kunal’s answer started with the API: listen for ProcessInfo.thermalState and back off the experience when it climbs.1 The specific levers the panel offered: request lighter network resources so the device spends less time decoding and parsing, swap richer animations for simpler ones, and drop the frame rate or rendering resolution under pressure. Kunal noted the system already throttles animation and display frame rates in higher thermal states, so some relief is automatic and you layer your own on top. Marco’s closing line on it: pushing fewer pixels is less work, and there is “no getting around thermodynamics.” You control your app’s compute; you do not control physics, so optimize hard on the part you own.1
The Apple Intelligence contention model. A pointed question asked how iOS 27 prioritizes app background tasks when the system is busy with Apple Intelligence work. Terry’s answer was reassuring and specific: many Apple Intelligence features run on the Neural Engine or in Private Cloud Compute, so if your app is using the CPU while an AI workload uses the Neural Engine, the two can often run concurrently without contending for the same resource. The defensive move he recommended is structural, configure background tasks into small chunks so the system can pause and resume them, rather than one monolithic job that has to restart from zero every time it gets interrupted. Chunked work makes progress even when the scheduler is not running you as often as you would like.1
StateReporting cardinality. The new MetricKit StateReporting feature lets you slice metrics by application state, which is powerful and easy to misuse. The lab gave a clear rule on cardinality: do not report frequently changing exact values like the precise number of items in a list. Bucket them instead, small, medium, large, so you can later ask “in this size range, did performance regress?” without paying the cost of recording every distinct count. Yanni’s example: a 1,000-item list and a 1,001-item list make no meaningful difference, so recording the exact number is pure overhead. Define the boundaries that matter for your analysis and report the bucket.1
On launch specifically, the panel converged on a single mental model that ties the triage advice together: figure out the minimum data you need to draw the first frame, load only that, and defer everything else. Terry warned against the common failure of spinning off a pile of background work and then blocking the main thread until all of it finishes, which freezes the whole app during launch. To see whether that is your problem, Kaspar pointed to the System Trace template’s main-thread view, where a blocked main thread shows up directly. The panel also described System Trace surfacing thread priorities, preemption, and a context-switch histogram, though I have not been able to confirm those as documented Instruments 27 features, so take that as the lab’s description of the tool rather than a spec.
Tooling notes: the Foundation Models instrument and a beginner’s on-ramp
Two tooling items round out the lab.
For developers shipping Foundation Models features, Kaspar described the Instruments tool growing from last year’s basic token-count metrics into a full debugging instrument that captures prompts and responses and shows how many tokens are being cached.1 The precise picture across the WWDC26 sessions: the Foundation Models instrument captures prompt and response data from the device for the duration of the trace (session 243, which also notes that capture can include sensitive information, so it is off in production).7 The cached-token counts come through the usage API on model responses (session 241).8 Two different mechanisms, one for the trace timeline and one for the per-response accounting, worth keeping straight when you read your numbers.
For beginners, the panel was consistent about where to start. Marco recommended the Time Profiler with the flame graph view as a first pass, because a flame graph shows visually how much a call stack costs you instead of making you read numbers in an outline. Kaspar added the Top Functions mode as the next step, a flat list of the heaviest functions so you can spot offenders at a glance without walking a deeply nested call tree.1 And the panel’s most-repeated meta-advice: measure before you optimize. Kunal’s framing was that the most common pitfall is insufficient telemetry, which leads developers to optimize areas that yield no real wins. Terry’s corollary on launch and background work: a network request sent half as often is a free power win.1 Look at the whole picture before diving into any one subsystem.
Key Takeaways
For iOS developers shipping today:
- Migrate off MXMetricManager to the new MetricManager Swift API. The old surface is deprecated as of 27.0, and new metric and diagnostic types are exclusive to the new API.23
- Open Xcode Organizer and check your Metric Goals against the similar-app baselines for launch, hangs, battery, hitches, disk writes, and storage.4
- Stop measuring launch with your own timer; MetricKit and Organizer measure from the icon tap, which your process cannot see.6
For performance and power triage:
- Use the Power Profiler untethered trace (iOS 26, Settings > Developer > Performance Trace) to catch background-task and real-world power problems that never reproduce at your desk.5
- Profile on a physical device, never the Simulator, and use Low Power Mode as a stand-in for old hardware you do not own.1
- Listen for ProcessInfo.thermalState and back off frame rate, resolution, animation richness, and network weight under pressure.1
For teams building AI features:
- Chunk background work so the scheduler can pause and resume it; CPU work can often run alongside Neural Engine and Private Cloud Compute AI workloads without contention.1
- Bucket StateReporting values (small, medium, large); never report fast-changing exact counts.1
- For Foundation Models, read the Instruments tool for prompt and response capture (session 243) and pull cached-token counts from the response usage API (session 241).78
This lab pairs naturally with the deeper dives in the series: MetricKit and StateReporting in iOS 27 on slicing metrics by app state, Instruments 27 and app responsiveness on the new diffing and hang-detection workflows, and the performance blind spot on why field data and desk profiling disagree. The full series hub is the Apple Ecosystem Series.
References
-
Apple, WWDC 2026 Power and Performance Group Lab, session 8003. Apple published no official transcript or captions for this lab; quotes are paraphrased from a local Whisper transcription. Source for the panel’s framing on MetricKit’s rebuild motivation, Instruments-versus-Organizer field data, Metric Goals adoption advice, the untethered Power Profiler workflow, the Low Power Mode proxy trick, Device Conditions (“condition inducer”) behavior, the never-profile-on-Simulator rule, the thermal playbook, the Apple Intelligence contention model and chunked background work, StateReporting cardinality guidance, the Time Profiler / flame graph / Top Functions beginner on-ramp, and “insufficient telemetry is the biggest power mistake.” ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
Apple Developer Documentation,
MXMetricManager. Marked deprecated as of 27.0 with the guidance “Use MetricManager instead.” ↩↩↩ -
Apple, WWDC 2026 session 222, Meet the new MetricKit. Source for the Swift-first API and the exclusivity of new metric and diagnostic types to the new API. ↩↩↩
-
Apple, WWDC 2026 session 258, What’s new in Xcode 27. Source for Metric Goals derived from technical and functional similarity to other apps plus historical baselines, covering launch, hang rate, disk writes, battery, storage, and hitches. ↩↩↩
-
Apple Developer Documentation, Measuring your app’s power use with Power Profiler. Power Profiler mode of Performance Trace, an iOS 26 / WWDC25 feature: enable under Settings > Developer > Performance Trace, capture via a Control Center control, share the
.aarfile to a Mac, and analyze CPU, GPU, display, and networking power lanes in Instruments. ↩↩↩ -
Apple Developer Documentation, Reducing your app’s launch time. Launch is measured as the milliseconds between the user tapping the app icon and the first screen being drawn. ↩↩
-
Apple, WWDC 2026 session 243, Debug and profile agentic app experiences with Instruments. Source for the Foundation Models instrument capturing prompt and response data from the device, including potentially sensitive information. ↩↩
-
Apple, WWDC 2026 session 241, What’s new in the Foundation Models framework. Source for cached-token counts available through the
usageAPI on model responses. ↩↩