‹ All Air Kalon docs

Air Kalon

Performance

Measured throughput, coding overhead and decoder cost on real devices, how each number was measured, and what the numbers do and do not show.

Summary

MeasureResultConditions
RaptorQ frames needed, real devicesExactly K distinct symbols in every runDevice sessions 2 to 4 and all 64 replication runs
Best goodput, default size (version 27)30.5 KB/sMacBook Pro to iPhone 12 Pro Max, one run
Best goodput, version 4044.4 KB/siPad Air to iPhone 12 Pro Max, one run
Median goodput, version 27, Low Power Mode off22.6 to 25.3 KB/sThree device pairings, 6 runs each
Median goodput, version 40, Low Power Mode off28.2 to 36.5 KB/sThree device pairings, 4 to 6 runs each
Receiver decoder pass, best case23.8 ms median, 41.3 ms 95th percentileiPhone 12 Pro Max, version 27
Frames an uncoded sender would need instead3.4 to 5.5 × moreClosed-form estimate on measured loss

A kilobyte here is 1,024 bytes, as the app reports it. Goodput is the transmitted object's size divided by the time from the first locked frame to completion.

Coding overhead

Synthetic

Measured with examples/rqbench.rs on an M1 Max (committed as docs/benchmarks/2026-08-07-rqbench-m1max.txt).

PayloadSymbolKRaptorQ frames needed
512 KiB1,445 bytes3631.006 × K, with and without loss
10 MiB2,933 bytes3,5761.002 × K, with and without loss
4,097 bytes512 bytes91.000 × K

Decoding is not the bottleneck. RaptorQ decoded the 10 MiB case in 3.6 ms in total with no loss.

On real light

Every RaptorQ transfer recorded on physical devices completed at exactly K distinct symbols: 371 for K = 371 and 226 for K = 226 in session 2, 163 for K = 163 and 1,759 for K = 1,759 in session 3, 371 and 183 in session 4, and every one of the 64 replication runs. Duplicates, where a 30 fps camera reads a 24 fps display twice, cost decoder time but no coding overhead.

For history: an earlier LT-coded mode, since removed, needed 1.262 and 1.308 × K in the two device runs of session 1.

Throughput on devices

Session 4

MacBook Pro sending to an iPhone 12 Pro Max propped at a measured 30 cm, the same 521 KB image in each cell, one run per cell.

Version 27, Low Power Mode onVersion 27, Low Power Mode offVersion 40, Low Power Mode off
Goodput15.8 KB/s30.5 KB/s38.6 KB/s
Decode rate, run mean11.3 codes/s24.7 codes/s13.8 codes/s
Decoder pass after lock, median40.2 ms23.8 ms31.3 ms
Decoder pass after lock, 95th percentile102.1 ms41.3 ms72.4 ms
Captures never examined because the decoder was busy51 %16 %38 %
Time to lock4.46 s1.99 s0.94 s
Distinct symbols ÷ K1.0001.0001.000
Thermal stateNominalNominalNominal

At version 27 with Low Power Mode off, the sender showed 24 unique frames a second and the receiver decoded 24.7 a second. The ceiling at 24 fps and 1,440-byte symbols is 33.8 KB/s, and the measured 30.5 is 90 percent of it. The rest is the two seconds of lock time and the remaining busy drops.

Replication: 64 runs on three device pairings

Each sitting ran four cells, four to six runs each, every run SHA-256 verified. Payloads were 310 to 318 KB. Values are the median over runs.

CellMacBook Pro to iPhone 12 Pro MaxMacBook Pro to iPad Air (5th gen)iPad Air to iPhone 12 Pro Max
Version 2725.3 KB/s23.3 KB/s22.6 KB/s
Version 4036.5 KB/s28.2 KB/s31.1 KB/s
Version 27, Low Power Mode on20.4 KB/s15.3 KB/s20.0 KB/s
Version 40, Low Power Mode on31.1 KB/s28.3 KB/s31.8 KB/s

The contrasts that held in all three sittings:

ContrastSitting 1Sitting 2Sitting 3
Decoder pass, version 40 against 271.59 ×1.59 ×1.67 ×
Decoder pass, Low Power Mode on against off, version 271.59 ×1.34 ×1.47 ×
Decoder pass, Low Power Mode on against off, version 401.55 ×1.41 ×1.41 ×
Goodput, version 40 against 271.44 ×1.21 ×1.38 ×

What this shows:

  • Version 40 is faster, but not twice as fast. It carries about twice the payload per code, and the decoder takes about 1.6 times as long to read it.
  • Low Power Mode slows decoding on every device measured. The size of the effect differs between devices.
  • Thermal state was not the cause. No run recorded a thermal transition.
  • No loss of decoding success at version 40 was detected in the replication, although a single earlier run had suggested one.

Acknowledgement

In the one recorded field run with auto-stop on, an iPad sending to an iPhone, the acknowledgement arrived in one round trip. The sender streamed 200.5 seconds for a receive that took 186.5, a tail of 1.075 ×. Without auto-stop, session 2's senders streamed 1.5 to 2.4 times longer than the receiver needed.

The grid

From a Mac sender, two codes per frame delivered 14.6 KB/s against 6.8 KB/s for a single code in an earlier session. That comparison crosses sessions, so it is reported but not relied on. From an iPhone sender the grid failed to transfer at all, which is why phones never render it.

Synthetic gauntlet

A seeded degradation harness (kit/Sources/AirKalonGauntlet) renders frames, degrades them under control and decodes them with Vision on an M1 Pro. It describes that machine, not a phone.

CellResult
Gaussian blur50 % decode floor at 0.407 modules (version 27) and 0.406 modules (version 40)
Two frames blended in one capture50 % decode threshold at a 0.397 mix
PrefilterThreshold 2.08; no changed frame ever classed as a repeat at any level tested
Coding comparison, 262,144 bytes at 2,953-byte framesRaptorQ 90 captures for K = 90, against 132 for an earlier LT-coded mode, since removed
Detection cost11.5 ms floor at 1080p, 7.8 ms for each additional code

Without a fountain code

The baseline every fixed-rate design reduces to is a sender that cycles the K blocks in order and a receiver that must catch every one. Using each session 4 run's measured share of shown frames that were read, such a sender would have had to show 3.4 to 5.5 times as many frames as the rateless sender needed. The penalty grows as the channel gets worse.

Sender cost

QR encoding

A stream's first frame scores all eight QR masks; every later frame reuses the chosen one. Measured with examples/rqbench.rs on the development Mac, as recorded in the repository README:

VersionFirst frame, all eight masksLater frames, mask pinned
273.01 ms0.16 ms
406.31 ms0.31 ms

Pacing

The credit pacer was measured camera-free with PacerBenchTests on a mocked 60 Hz display link, against a strict-interval pacer that never catches up (docs/benchmarks/2026-08-14-sender-pacing-bench.md). At the measured version 40 production cost of 0.73 ms per frame, median:

ConditionCredit pacerStrict interval
Steady production24.03 fps20.00 fps
Jittery display-link ticks23.33 fps16.27 fps
Spiky production and jittery ticks21.57 fps16.23 fps

This measures the sender's emission rate only, not what a camera receives.

Resource use on the Mac

Measured on an M1 Max with 1 Hz sampling (docs/benchmarks/2026-08-08-efficiency.md). The sending rows were measured while an earlier LT-coded mode, since removed, was the default, and at that time the acknowledgement watcher ran on every send; it is now off unless you switch on auto-stop.

StateAverage CPU
Idle, any tab0.00 to 0.05 %
Sending at 24 fps, single code61.1 %
Sending at 12 fps37.5 %
Receiving, searching for a code32.5 %

The Mac app bundle measured 2.5 MB in the same pass.

How the numbers were measured

  • Every device figure comes from the apps' own session reports, pasted verbatim into docs/benchmarks and collected in kit/Benchmarks.
  • From session 4 onward the receiver times each decoder pass directly, split into before and after the optics lock, and records thermal state, Low Power Mode, capture format, locked exposure and the module size it sees.
  • Comparisons are made only within one sitting. Absolute values are never compared across sessions, and a per-pass time is never inferred by dividing elapsed time by the number of passes. Two earlier conclusions were withdrawn under these rules.
  • Replication intervals are percentile bootstraps over run values, with exact Mann-Whitney tests. The unit of analysis is the run, not the decoder pass.

What has not been measured

  • No Android device and no device outside one vendor.
  • No sustained-load or thermal soak run.
  • Nine of the twelve cells in the session 4 protocol, including 720p capture and the alternative decoder paths.
  • The 2× grid together with RaptorQ on a device.
  • Handheld transfers under controlled conditions. The replication sittings held distance by hand.