← All notes
Device Testing7 min

A cold start is not a session

Most performance checks we run are cold starts: launch the app, exercise the happy path, glance at Instruments, ship. That catches crashes and obvious main-thread work. It does not catch what happens when Endeo has been capturing pen strokes for ninety minutes on a warm iPad in someone's lap, or when RuleCaddie has been open on a sunlit fairway with the screen bright and the radio hunting. Those failures are thermal and energy failures, and they only show up if you treat session length as part of the test.

The benchmark ends before the damage starts

Thermal throttling is a time-domain problem. The SoC runs hard, heat accumulates, iOS drops clock frequency, frames slip, and touch latency climbs. A five-minute profile on a desk rarely reaches Fair, let alone Serious. The path that felt smooth in QA starts hitching after the user has already committed to the session — which is exactly when they notice.

Battery is the same shape. A cold-start energy impact number tells you the first screen was cheap. It does not tell you whether continuous Pencil sampling, periodic OCR, location, or a chatty sync loop will pull ten percent an hour once the device is off the cable and the radio is awake. Users experience the cliff mid-round or mid-meeting, not at launch.

So the unit of truth is a session, not a launch. If the product promise is "take notes for a lecture" or "keep the rules app open for eighteen holes," the test has to last long enough for heat and energy to matter on a mid-tier device that is not plugged in.

Watch thermalState the way you watch FPS

ProcessInfo.thermalState is not a debug curiosity. It is the OS telling you the device is already negotiating survival. Nominal means stay the course. Fair means stop discretionary work — background OCR passes, speculative prefetch, fancy animations you do not need. Serious means cut heavy CPU and GPU paths. Critical means drop peripherals like the camera before the system does it for you more harshly.

We treat transitions into Fair and Serious as product events, not log lines. On Endeo-shaped surfaces that means pausing non-essential recognition work and keeping stroke capture responsive. On RuleCaddie-shaped surfaces that means preferring the on-device rules database over a network round-trip that heats the radio for a second of maybe-better wording.

Xcode's Device Conditions let you force thermal states in the lab so you can see the degraded path without waiting for a sunny afternoon. That is useful for wiring the response. It is not a substitute for a long run on hardware, because forced Serious while the chassis is still cool does not reproduce the same cascade of memory pressure, battery chemistry, and frame pacing you get when the device actually cooked itself there.

How we run a session test

Pick the device tier your users actually hold — not the newest iPad on the bench. Leave it unplugged. Brightness up. Start from a warm battery around forty to sixty percent so you are not measuring a full-charge honeymoon. Exercise the real loop for a fixed wall-clock budget: for note capture, continuous writing with intermittent OCR; for a field app, a mix of foreground use, brief backgrounding, and the sync that happens when signal returns.

Log thermalState on an interval. Pair Instruments' Energy and Time Profiler templates so you can correlate CPU spikes with thermal climbs instead of staring at a single FPS chart from minute two. Watch memory for the slow climb that never returns to baseline — that leak only appears when the session outlasts the short benchmark.

Define fail criteria before you start. Examples we have used: entering Serious under ordinary note-taking inside the first hour; losing more than a fixed percent of battery per hour with the screen on and radios in a realistic state; frame time that stays broken after the thermal state drops back. Without those thresholds, the long run becomes a vibe check, and vibe checks do not gate releases.

Degrade on purpose before the OS degrades you

The apps that survive long sessions are the ones that shed work early. Drop preview quality before strokes feel late. Defer secondary model passes. Coalesce sync. Prefer local answers when the radio would only add heat. None of that is visible in a cold-start demo, which is why demos keep shipping the expensive path as the only path.

Be honest in the UI when you shed work. Silent quality loss teaches users the product is flaky. A short, specific signal — recognition paused until the device cools, sync deferred — is better than a mysteriously sticky canvas.

Simulator numbers do not participate in this conversation. The simulator borrows the Mac's cooling and power budget. It will not thermal-throttle like a sealed phone in a pocket, and it will not drain a battery it does not have. Functional tests belong there. Session performance does not.

What we treat as done

A build is session-ready when a representative mid-tier device can run the primary loop for the promised duration without crossing your thermal and battery thresholds, the app responds to Fair/Serious by cutting the right work, and a forced Device Condition pass proves the degraded path is wired — not merely hoped for.

Cold-start Instruments still matter for launch regressions. They are just not the finish line. The finish line is the hour mark on a warm device that has been doing the job the marketing screenshot implies.

Have something to build?

Tell us what you're working on and we'll tell you honestly whether we're the right fit.

Work with us