docs(series4): CORRECTED -- cellular cost is NOT independent of payload

I had it as "~0.65 s per round trip, independent of payload size", and based
design advice on it ("minimise round trips, not bytes").  The first claim is
wrong and the second is too strong.

Every measurement behind it had a SMALL payload -- 59 B status, 266 B setup
records, 1024 B download chunks.  With the byte term small and similar across all
of them, per-command cost looked constant.  It was a narrow-range fit
extrapolated past its evidence.

Measured against a 14,176 B single response on UM12947 over an RX55:

  1,024 B   0.67 s      8,192 B   3.59 s
  2,048 B   1.22 s     14,176 B   6.25 s
  4,096 B   2.13 s

  t ~ 0.21 s + bytes / 2,350   -- fits within +/-11% over a 14x size range

The old 0.65 s figure was right FOR A 1 KB RESPONSE and is that model evaluated
at 1 KB.  Round trips still cost (0.21 s each; 24 of them for a setup walk is
still 16 s), but bytes cost more than round trips on anything over ~500 B, and
that reverses the advice: for STATUS work minimise commands, for DOWNLOADS the
floor is throughput and batching does not beat it.

So the 16 KB chunk size is a ~30% win, not 14x.  UM20147's 72,560-byte event is
~46 s at THOR's 1024 B and ~32 s at 16,384 B, because ~31 s of it is bytes on the
wire.  Still worth keeping -- 30% faster, and 14x fewer requests is 14x fewer
chances for a link to drop mid-download -- but the earlier "~3.2 s" projection
was wrong and is withdrawn.

Corrected in all four places it had propagated: the protocol reference, the
CHUNK_SIZE comment, the probe's verdict, and mm_client_check's banner.  The probe
now also prints a net time per measurement, since its raw timings include the
idle gap while the control reads to frame completion -- comparing them directly
was misleading.

Also confirmed in the same run: 16 KB-class responses survive a cellular PAD.
1,024 / 2,048 / 4,096 / 8,192 / 14,176 B all arrived in one frame, byte-identical,
over an RX55.  14,176 B is UM12947's largest event so the ceiling itself was not
reached, but a 14 KB response crossing the PAD intact is what needed proving.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
2026-10-02 15:09:38 -04:00
co-authored by Claude Opus 5
parent eefc846c8c
commit 338ce4fea7
4 changed files with 69 additions and 10 deletions
+16 -4
View File
@@ -173,8 +173,11 @@ def main() -> int:
body = b"".join(f.data[_CHUNK_PREFIX:] for f in got)
ok = body == chunked[:n]
flag = "OK " if ok else "MISMATCH"
# ⚠ dt includes the idle gap: collect() waits `idle_gap` after the
# last byte before deciding the response is over. Subtract it to
# compare against the control, which reads to frame completion.
print(f" {n:6} B {len(got)} frame(s) {len(body):6} B back "
f"{dt:5.2f} s {flag}"
f"{dt:5.2f} s ({max(dt - a.idle_gap, 0):4.2f} s net) {flag}"
+ ("" if ok or not body else
f" (first diff at {next((i for i in range(min(len(body), n)) if body[i] != chunked[i]), None)})"))
if ok and len(body) == n:
@@ -189,9 +192,18 @@ def main() -> int:
print(f" VERDICT: the device serves at least {best} B per request,")
print(f" verified byte-identical. For this {ref.size} B event that")
print(f" is {then} request(s) instead of {now}.")
if best > 1024:
print(f" Over cellular at ~0.65 s per round trip: "
f"~{now * 0.65:.0f} s -> ~{then * 0.65:.1f} s.")
if best > THOR_CHUNK_SIZE:
# ⚠ cost is ~0.21 s per request PLUS ~2,350 B/s over a modem --
# a download is throughput-bound, so do not promise a saving
# proportional to the drop in request count.
fixed, rate = 0.212, 2348.0
t_now = now * fixed + ref.size / rate
t_then = then * fixed + ref.size / rate
print(f" Modelled over cellular (0.21 s/request + "
f"{rate:.0f} B/s): {t_now:.1f} s -> {t_then:.1f} s, "
f"a {100 * (1 - t_then / t_now):.0f}% saving.")
print(" Throughput-bound, not round-trip bound — most of that is")
print(" bytes on the wire and batching does not touch it.")
if best >= ref.size:
print(" The WHOLE EVENT fits in one request.")