A few days ago I boarded a flight in Seattle, opened VeloGPS — the little GPS app I've been building — tapped the airplane button, and started recording. Thirteen hours and forty-four minutes later we touched down in Hong Kong. The app was still running. It had captured all 15,085 GPS fixes, start to finish, with no crash and no runaway stats.

That sounds like it should be easy. It was not. Getting an iPhone to faithfully record a half-day flight across the North Pacific took months of work, several earlier flights that ended in frustration, and a long list of specific things that had to be fixed — invalid GPS samples, signal dropouts at altitude, and a memory bug deep inside Apple's map libraries that quietly killed the app every time I came back to it.

This is the story of that flight — the boxes we had to check to record it, and a gut check at the end where I lay an independent ADS-B track over my phone's recording to see how the little app held up. (Spoiler: it held up.) But first — the map.

The long way to Hong Kong

The straight-line, great-circle distance from Seattle to Hong Kong is about 6,488 miles. We flew 6,757. The extra mileage isn't error — it's the route. Great circles over the Pacific arc north, up over the Gulf of Alaska, across the Aleutians, down the spine of Kamchatka and past Japan. On a flat map it looks like a detour. On a globe it's the shortest path there is.

Recorded GPS flight path from Seattle to Hong Kong, arcing north over the Aleutians and Alaska and back down past Japan, drawn on a dark chart of the North Pacific

The recorded track — every fix the phone kept, drawn over the North Pacific.

The line you're looking at is the real recorded track, not a rendered route. Each bend is the airplane's actual path as the phone saw it from a window seat.

The numbers

Here's what the track adds up to. Everything below is computed straight from the recorded GPX file.

Metric Value
Route Seattle (SEA) → Hong Kong (HKG)
Recording duration 13 hr 44 min
GPS fixes recorded 15,085
Distance flown (sum of track) 6,757 mi · 10,874 km · 5,872 nm
Great-circle distance 6,488 mi · 10,442 km · 5,638 nm
Track vs. great circle +4.1% (the route, not noise)
Peak ground speed 610 mph · 530 kn · 982 km/h
Mean recorded ground speed 507 mph · 441 kn · 817 km/h
Peak altitude (geometric / GPS) 45,910 ft · 13,994 m
GPS drop-outs over 2 minutes 14 (longest: 12.1 min)
Out-of-order GPS timestamps 0

That +4.1% is the number I'm proudest of. More on why in a minute — it used to be a lot worse.

Climb, cruise, descent

Altitude tells the cleanest story of any flight.

Altitude profile of the flight, climbing in steps from takeoff to a peak of 45,910 feet before descending into Hong Kong

Altitude over the full 13.7 hours. The staircase is real: jets step-climb as they burn off fuel and get lighter.

You can read the whole flight in that line. A flat stretch at the gate. A near-vertical climb to an initial cruise around 36,000 feet. Then the staircase — each step up is the aircraft climbing to a higher, more efficient altitude as it burns fuel and gets lighter. A long descent into Hong Kong at the end.

One honest note on that 45,910-foot peak. Airliners don't actually cruise at 46,000 feet. The phone records GPS-derived (geometric) altitude. The flight levels pilots fly are barometric — referenced to air pressure. The two differ by anywhere from a few hundred to a few thousand feet depending on the air temperature, so a jet holding FL430 over warm air really can read ~45,900 feet on GPS. Both numbers can be "right"; they're just measured against different references. I put hard numbers on this later, when I lay the recording against the aircraft's broadcast barometric altitude — it turns out to be a small, satisfying physics lesson. (Getting altitude trustworthy at all was its own project — see below.)

Speed, and a Pacific headwind

Ground speed over the flight, ramping to cruise around 550 mph, dipping mid-Pacific, then pushing to a peak of 610 mph

Ground speed across the flight. The dip in the middle is the airplane fighting the air; the late push is it getting a shove.

Ground speed is speed over the dirt — what the GPS measures — not speed through the air. The difference is wind. My read of that mid-flight sag and the late surge to 610 mph is that we hit headwinds over the central Pacific and picked up a tailwind on the descent side. That's a hypothesis from the shape of the curve, not something the phone can prove on its own. What the phone can prove is that it tracked a half-day of speed without a single nonsensical spike — which, again, was not always true.

Why this was hard

Here's the part that took months. If you just want the punchline: an iPhone is not built to do this well out of the box, and Apple's location stack will hand you confidently wrong data on an airplane unless you go looking for it.

It started with a flight that went badly

I didn't set out to build a "flight mode." I built it because flying without one was miserable.

On an earlier trip — a JFK to Seattle redeye in April — I ran VeloGPS the normal way and watched it fall apart. The app cheerfully reported 208,091 feet of elevation gain for a single flight. (A realistic climb to cruise is about 37,000.) The altitude chart kept spiking to zero. After landing, the map wouldn't respond to my finger at all. I filed six bug reports against my own app from one airplane seat.

When I pulled the full track off that flight and dug in, the picture was ugly:

  • The naive elevation-gain math came out to 644,554 feet17× the real climb.
  • Distance was inflated 15% by the GPS zig-zagging.
  • Roughly 1,721 points were garbage — and every long signal gap ended with the same tell: an altitude of exactly −1 meter.

That −1 was the smoking gun. It's a sentinel value — Apple's way of saying "this altitude is invalid, don't use it." My code was using it anyway. So the altitude would read 36,000 feet, drop to −1, snap back to 36,000, drop to −1, over and over. Every one of those round trips got counted as ~36,000 feet of climbing. That's where the 17× came from.

I had a choice: paper over the symptoms, or build the thing properly. I built the thing. This is the part of making software I love most — when a task stops being a one-off fix and becomes a system that makes every future flight better.

What Flight Mode actually does

Flight Mode is a single button now. Underneath it, a few things change at once.

It tells iOS you're flying. Apple ships a location configuration literally called airborne. Flight Mode switches to it, so CoreLocation tunes itself for aircraft instead of assuming you're walking.

It refuses bad data at the door. Every GPS sample now runs a gauntlet before it's allowed to touch the map or the stats: reject it if the reported accuracy is invalid or too loose, reject it if the timestamp is stale, reject it if it arrives out of order, and — critically — reject altitude flagged invalid by that −1 sentinel, or any altitude implying a climb rate faster than a fighter jet. The result is visible in this flight's numbers: distance came in 4% over great circle instead of 15%, and there were zero out-of-order timestamps. The gauntlet works.

It expects to lose signal, and recovers without lying. A metal fuselage blocks GPS. At cruise, only a phone near a window sees enough satellites for a fix, and even then the signal comes and goes. This flight had 14 drop-outs longer than two minutes, the worst lasting 12 minutes — you can see them marked in red on the charts above. Flight Mode treats silence as silence: it shows a "weak signal" then "signal lost" state instead of pretending stale data is live, and when the signal returns it ignores the first few jittery fixes so a recovery can't manufacture a phantom 30,000-foot climb.

It teaches you the one trick that matters. The first time you turn it on, a pre-flight checklist comes up. The most important item: disable Cellular from Control Center — do not use Airplane Mode. Toggling Airplane Mode mid-flight wipes the GPS assistance data the phone needs to find satellites, and at 38,000 feet over the ocean it may never get a fix again. That single piece of advice is the difference between a recorded flight and a flat line.

The bug that crashed the app on the way home

Building Flight Mode got the data right. It didn't get the app to survive a long flight. That was a separate, nastier problem, and it showed up on two flights in May.

The pattern: turn on Flight Mode, start recording, put the phone in my pocket for hours. The app kept recording in the background perfectly. Then I'd tap the Live Activity on my lock screen to bring the app forward — and it would instantly crash. No crash report. Just gone.

No crash report is itself a clue. It means iOS killed the app for using too much memory, rather than the app crashing on its own. The culprit was hiding inside MapKit, Apple's mapping library. While the app was backgrounded, the recorded route — now thousands of miles of line — wasn't being drawn. The instant I foregrounded it, MapKit tried to draw the entire multi-thousand-mile polyline in a single frame, all at once. The memory spike blew past the budget and the system pulled the plug.

The fix is one of my favorite kinds: stop doing work nobody can see. The screen only has so many pixels. There's no point drawing two GPS points that land on the same pixel, so now the app thins the line to match the zoom level — full detail when you're zoomed in close, a light sketch when you're looking at the whole Pacific. Same-looking map, a tiny fraction of the work. I capped a couple of other things that grew without bound over a long recording, too.

The proof is in the flight itself. The diagnostic log from Seattle to Hong Kong shows memory holding flat at roughly 100 MB for the entire 13-plus hours, while the recorded-point count climbed past 15,000. Steady as she goes.

Tested against real flights, not a simulator

You can't unit-test a transpacific flight on your laptop. So that ugly JFK→Seattle track became the test fixture. Every fix above is checked against the real data: replay those 19,424 real trackpoints through the new code and the elevation gain has to come out sane, the distance has to land within 5% of great circle, the bogus points have to get rejected. These tests fail against the old code and pass against the new. That's a regression net with real teeth — the best kind.

Did it actually work? Ask the airplane.

Self-tests are one thing. I wanted an independent check — so I went and got an outside view of the airplane's data.

Modern airliners broadcast position, altitude, and speed over ADS-B, one of the surveillance feeds services like FlightAware use to follow flights. Mine was Cathay Pacific CX853, an Airbus A350. I pulled FlightAware's track log for it and laid that independent aircraft track directly over my phone's recording. (Amusing detour: FlightAware wraps the eastern-hemisphere longitudes in clickable phone-number links — 122.7869 does look like one — which broke my first parse and briefly fooled me into thinking coverage stopped at the date line. It doesn't.)

Two independent recordings of the same 13 hours. Here's how they line up.

Phone GPS track and aircraft ADS-B track overlaid on the North Pacific — they sit on top of each other from Seattle to Hong Kong

Orange is my phone; dashed blue is the ADS-B track. It's the same line.

At map scale the two paths are indistinguishable. Put numbers on it and the agreement is, frankly, better than I expected from a phone riding in a seat-back pocket:

Measure Phone GPS vs. aircraft ADS-B
Position median ~170 m apart — the entire way across the Pacific
Ground speed mean difference 0.0 kt (median 0.4 kt)
Altitude a structured −900 to +2,600 ft offset — and it's not error (see below)

Speed is the easy win. The two traces are essentially one line:

Ground speed from the phone and from ADS-B, nearly identical across the whole flight

Phone vs. ADS-B ground speed. Mean difference: zero knots.

Altitude is the interesting one — and it vindicates the geometric-vs-barometric aside from earlier. The phone reports geometric (GPS) height; ADS-B reports barometric flight level. Watch the two lines trade places:

Altitude comparison: the phone's geometric altitude starts below the ADS-B barometric flight level over the cold North Pacific and crosses above it on the warm Hong Kong approach

The lines swap. Over the cold North Pacific the phone reads below the flight level; over the warm subtropics it reads above.

Over the frigid air near the Aleutians, the phone's GPS altitude sits about 880 feet below the barometric flight level. By the warm approach to Hong Kong it's ~2,600 feet above — and that 45,900-foot peak from earlier lines up neatly with the jet's FL430 (43,000 ft) plus the warm-air offset. Neither source is wrong. Cold air is denser, so a given pressure surface sits lower; warm air is the reverse. The phone and the ADS-B altitude disagree in the direction, and roughly the scale, physics says they should.

The lessons — and they're good ones:

  • Position is validated. A free app in my pocket tracked the aircraft to a median of ~170 meters against an independent flight track, across 6,700 miles and the International Date Line.
  • Speed is dead-on. Zero knots of average disagreement against the comparison data. Nothing more to say.
  • The altitude gap makes sense. The offset is real physics, and it even shows up as a clean, temperature-driven sign flip. The comparison is strong evidence that Flight Mode's altitude handling is sound.
  • The dropouts were honest. Where my phone briefly lost GPS over the Pacific, the airplane's track confirms it never wandered off — the recording's gaps were real gaps, not bad data sneaking in. Which was the entire point of building Flight Mode.

I went looking for places the app fell short. I mostly found agreement.

What I'd still fix

I try never to present anything as risk-free. A few honest edges remain. You still have to remember to switch back to Default mode after you land, or your bike ride home won't track right — there's a reminder, but no automatic detection yet. And the altitude is GPS-geometric, not the barometric flight level a pilot would quote; I fuse the phone's barometer in for smoothness, but the absolute number still rides on GPS. Good problems for the next flight.

Wearing out, not rusting out

I keep a Theodore Roosevelt line close: "We all must wear out or rust out; my choice is to wear out." This project is the small, happy version of that. A GPS app is not important. But building one — chasing a strange bug across three flights and a dozen fixes until an iPhone can quietly do something it was never quite meant to do — is exactly the kind of work that keeps the gears from rusting.

The best surprise came at the end. When I overlaid the independent aircraft track on my phone's recording, the two agreed to within ~170 meters and a fraction of a knot — the whole way across the ocean — and the one altitude "disagreement" turned out to be textbook physics, not a flaw. A spare-time app, matching a professional flight-tracking source. That's the real payoff: not that it matters, but that it holds up.

There's a thread here I didn't plan. I spent a year navigating the Pacific by sea, watching a GPS track unspool behind a sailboat at six knots. This spring I watched the same kind of track unspool behind an airplane at 530. Same ocean. Same instinct to record where I've been and make sense of it later. The sea, once it casts its spell, really does hold you in its net forever — even at 40,000 feet.


Want to poke at the raw data? Explore the full track on a map or download the GPX (1.9 MB, 15,085 points).