Skip to content
RPRichard PruittTech & Cyber
Navigation
repo://poppyup/docs/03-datapath-bottlenecks.md

docs/03-datapath-bottlenecks.md

30 KB · 266 lines · markdown · View source · Download from the repository page

PoppyUp — Data-Path & Bottleneck Analysis

Document: 03-datapath-bottlenecks.md · Baseline: v0.3, 2026-09-27 (owner review decisions D1–D13 applied; see ADR §15. v0.2: built-in cellular modem removed, ADR §14) · Derives from: 00-architecture-decisions.md (ADR §2, §3, §5). Requirements that cite these numbers: 01-requirements.md NFR-010…019.

0. The one-line answer

In standalone mode PoppyUp is never the bottleneck; the network is. The card side delivers 0.3–1.7 GB/s, the best network we can attach (5GBASE-T) takes ~0.5 GB/s, a typical venue drop takes 0.01–0.12 GB/s, and real-world cellular uplink — reached through the user's phone (Wi-Fi hotspot or USB tether on Port B) or a USB cellular adapter, since there is no built-in modem — takes 0.003–0.012 GB/s — two to three orders of magnitude below the card. In host mode the limiting factor is the USB path chosen by the host: ~3 GB/s over USB4 (Port C, Pro SKU only), ~0.9 GB/s over USB 3.2 Gen2, ~0.4 GB/s via the SoC gadget (Port A, all SKUs), ~0.04 GB/s on a USB 2.0 iPhone. Both host paths present the media read-only by default (D8). 5GBASE-T is the final Ethernet choice (D6, ADR §5).

All rates below are decimal (MB/s = 10⁶ B/s). "Raw" is the line rate; "payload" subtracts encoding and protocol overhead; "realistic" is what a well-implemented stack achieves in the field with real cards and real servers.


1.1 Card and source interfaces

Interface Raw line rate Encoding / protocol payload Real cards (vendor-measured seq. read) In PoppyUp (what limits it)
CFexpress Type B 4.0 (PCIe Gen4 ×2, NVMe) 2 × 16 GT/s = 32 Gb/s 128b/130b + TLP ≈ 3.5–3.7 GB/s 3.4–3.7 GB/s (Sony Tough G 4.0, ProGrade Cobalt 4.0, Lexar Diamond) ~1.65 GB/s — negotiates to Gen3 ×2 at the RK3588 root port (2 × 8 GT/s = 15.75 Gb/s payload ≈ 1.97 GB/s theoretical, 82–85 % delivered with NVMe QD ≥ 8). Card capability is 2× our root port; see §4.1 why this is acceptable.
CFexpress Type B 2.0 (Gen3 ×2) 16 Gb/s ≈ 1.97 GB/s 1.5–1.8 GB/s ~1.5–1.7 GB/s — card-limited
CFexpress Type A 4.0 (Gen4 ×1) 16 Gb/s ≈ 1.8 GB/s 1.6–1.8 GB/s (Sony CEA-G 4.0, Nextorage) ~850 MB/s — Gen3 ×1 behind ASM2812 (985 MB/s theoretical)
CFexpress Type A 2.0 (Gen3 ×1) 8 Gb/s ≈ 985 MB/s 700–900 MB/s 700–850 MB/s — card-limited
SD UHS-II FD156: 1.56 Gb/s per lane × 2 lanes (full duplex) → 156 MB/s each direction; HD312: both lanes one direction → 312 MB/s ≈ 300 MB/s (HD312 mode) 270–300 MB/s (Sony SF-G, ProGrade V90, Angelbird V90, Lexar 2000x) ~280–300 MB/s — GL9755 in HD312; card-limited; Gen3 ×1 lane not a factor
SD UHS-I (SDR104) 104 MB/s bus ≈ 100 MB/s 90–100 MB/s (170–200 MB/s only in proprietary DDR200 mode, not supported) ~90–100 MB/s — bus-limited
UHS-III 624 MB/s — No cards exist. Spec published 2017, zero commercial cards. Not supported; nothing lost
SD Express 7.x / 8.x Gen3 ×1 / Gen4 ×1 / Gen3 ×2 985 MB/s / 1.97 GB/s A handful of cards (SanDisk, Lexar, Samsung, ADATA); one or two cameras Not supported in host mode; cards fall back to UHS-I (~100 MB/s). Footprint-compatible GL9767 upgrade path if the market appears.
microSD UHS-I (SDR104) 104 MB/s ≈ 100 MB/s 90–100 MB/s ~90–100 MB/s — GL9750, bus-limited
CFast 2.0 (SATA III) 6 Gb/s 8b/10b → 600 MB/s, AHCI ≈ 550 MB/s 500–550 MB/s (SanDisk Extreme Pro, Angelbird AV Pro CF) ~480–550 MB/s — card-limited. ASM1064 sits on a Gen3 ×1 ASM2812 port (985 MB/s), so the lane is not a factor; ASM1064's AHCI DMA engine tops out near 550 MB/s on a single port.
External SSD on Port B (USB 3.2 Gen2, UAS) 10 Gb/s 128b/132b + UAS ≈ 1.1 GB/s Samsung T7/T9 950–1 050 MB/s; Blackmagic-class 900+ ~900 MB/s — ASM3142 on Gen3 ×2 (1.97 GB/s upstream, not limiting); SSD-limited
Internal NVMe (Pro, M.2 2280, Gen3 ×2) 16 Gb/s ≈ 1.97 GB/s Any modern Gen3/Gen4 SSD writes > 2 GB/s sustained for tens of GB, then SLC-cache exhaustion drops some to 0.8–1.5 GB/s ~1.6–1.7 GB/s link-limited, then SSD-cache-limited on multi-hundred-GB copies. Choose a TLC drive with large dynamic SLC or a "Pro" class drive (WD SN770/SN850X-class sustained ≥ 1.4 GB/s).

XQD is not in this table: it is unsupported (no driver, no licence, no USB-reader workaround — final, D10). An XQD card is physically insertable in the CFe B slot; firmware detects a non-NVMe PCIe device and rejects it with "XQD not supported" (01-requirements.md IF-006). That detection message is the only XQD behaviour in the product.

1.2 SoC-internal paths

Path Rate Notes
RK3588 pcie3x4 bifurcated → CFe B, Gen3 ×2 ~1.65 GB/s delivered Dedicated root port; no sharing. DMA into LPDDR4x (RK3588 LPDDR4x-4266 ×64 → ~34 GB/s theoretical, ~20 GB/s practical) — memory is not a factor.
RK3588 pcie3x2 → ASM2812, Gen3 ×2 upstream ~1.65 GB/s delivered, shared by CFe A, NVMe, Ethernet, SD, microSD, CFast, USB-SSD Worst-case concurrency below.
USB 3.2 Gen2 Port B (ASM3142, Gen3 ×2 switch port) → tethered phone / USB cellular adapter Link ≥ 40 MB/s iPhone USB tethering is USB 2.0-class in practice (~30–40 MB/s, even on Pro models); Android phones and USB adapters up to ~100 MB/s. Never the bottleneck — the phone's or adapter's cellular uplink (2.5–25 MB/s, §1.4) is.
Gen2 ×1 spare ×2 (pcie2x1l0, pcie2x1l2) ~400 MB/s payload each Test headers; pcie2x1l0 carried the v0.1 modem.
Gen2 ×1 → Wi-Fi 7 ~400 MB/s payload MT7925 2×2 160 MHz PHY peak 2.9 Gbps = 360 MB/s; realistic TCP ≤ 300 MB/s. Gen2 ×1 is marginally limiting only at ideal 6 GHz 160 MHz. Acceptable.
RK3588 USB3 OTG1 (dwc3, 5 Gbps) → Port A gadget 500 MB/s payload; f_tcm (UAS) ~400–420 MB/s, f_mass_storage (BOT) ~350–380 MB/s CPU-bound in the gadget stack at 5 Gbps; A76 core handles it.
Memory bandwidth ~20 GB/s practical Every byte crosses memory twice (DMA in, DMA/TX out) plus hashing passes; at 500 MB/s upload the memory system runs at < 10 %.

Worst-case ASM2812 upstream concurrency (Pro SKU): CFe A read (850 MB/s) + NVMe write during quick-copy of the CFe A card (850 MB/s) + Ethernet TX (500 MB/s) + SD read (300 MB/s) = 2.5 GB/s > 1.65 GB/s. In practice PCIe arbitration shares fairly and everything slows proportionally; the only user-visible effect is quick-copy from CFe A dropping to ~500 MB/s while a 5GbE upload runs. CFe B is unaffected because it has its own root port — which is precisely why it got the dedicated lanes. Quick-copy from CFe B to NVMe crosses both root ports (CFe B in via pcie3x4, NVMe out via pcie3x2) and runs at the full ~1.6 GB/s.

1.3 CPU budget (RK3588: 4 × Cortex-A76 @ 2.4 GHz + 4 × Cortex-A55 @ 1.8 GHz, ARMv8.2 Crypto Extensions)

Operation Per-A76-core throughput (measured class, OpenSSL 3 / xxHash reference) Cores needed at 500 MB/s
AES-128-GCM (TLS 1.3 record encryption) ~1.8–2.2 GB/s 0.25
ChaCha20-Poly1305 (fallback cipher) ~1.0–1.3 GB/s 0.45
SHA-256 (S3 x-amz-checksum-sha256, SigV4 payload hash) ~1.0–1.5 GB/s 0.4
MD5 (S3 ETag verification, Drive md5Checksum) ~0.65–0.75 GB/s 0.7
xxHash64 (local manifest) > 5 GB/s (memory-bound) 0.1
exFAT + block layer + NVMe I/O + TCP stack overhead — ~0.4
Total, S3 with SHA-256 + xxHash64 ~1.5 A76 cores (NFR-018 budget: ≤ 2)
Total, S3 with MD5 ETag + SHA-256 + xxHash64 ~2.2 cores — acceptable (2.5 A76 + A55s remain)

SFTP is the CPU-bound endpoint. A single OpenSSH connection is single-threaded on both ends: with aes128-gcm@openssh.com on an A76 it tops out around 250–400 MB/s, and many SFTP servers (small VPS, NAS) are slower than the client. Firmware must open 4–8 parallel SFTP connections (per-file or chunked with sftp extension copy-data/offset writes) to fill a 5GbE link. This is a firmware design constraint, not a hardware one.

Conclusion: the A76 cluster has ~2× headroom at 500 MB/s. It would not have had headroom at 10GbE (1.1 GB/s → ~3.5 cores for S3 with SHA-256) — one of the reasons 5GBASE-T is final (D6, §4.4).

Link Raw TCP/IP payload (1500 MTU, TLS record overhead) Realistic sustained S3 multipart upload from PoppyUp Limiter
5GBASE-T 5 Gb/s ~590 MB/s 480–520 MB/s with 8–16 concurrent 16–64 MB parts TCP window/ramp on each part, TLS, per-connection server pacing
2.5GBASE-T 2.5 Gb/s ~295 MB/s 270–290 MB/s link
1000BASE-T 1 Gb/s ~118 MB/s 105–115 MB/s link
100BASE-TX 100 Mb/s ~11.8 MB/s 11 MB/s link
Wi-Fi 7, 2×2, 6 GHz, 160 MHz, 3 m LOS to Wi-Fi 7 AP 2.9 Gb/s PHY ~1.9–2.4 Gb/s MAC → 240–300 MB/s 200–280 MB/s airtime efficiency, Gen2 ×1 lane at the very top
Wi-Fi 7/6E, 2×2, 5/6 GHz, 80 MHz, typical venue AP at 10 m 1.2 Gb/s PHY 600–900 Mb/s 75–110 MB/s contention, rate adaptation
Wi-Fi 6/5, 2.4 GHz, 20 MHz, congested venue 287 Mb/s PHY 30–100 Mb/s 3–8 MB/s congestion; effectively unusable for media
Cellular via the user's phone (USB tether on Port B or Wi-Fi hotspot) or a USB cellular adapter — the rows below are what that phone/adapter delivers; PoppyUp has no modem of its own:
5G NR sub-6 SA/NSA, good C-band cell (US, urban, close to site) — 100–200 Mb/s UL 12–25 MB/s cell UL scheduling, phone power headroom
5G NR sub-6, typical (US/EU urban & suburban) — 20–80 Mb/s UL 2.5–10 MB/s operator UL allocation (UL is typically ⅓–⅕ of DL), TDD UL/DL ratio (n77/n78 is ~25–30 % UL slots), UE transmit power (23 dBm)
LTE, typical (phones fall back automatically) — 10–30 Mb/s UL 1.5–4 MB/s as above
LTE, rural / edge of cell — 2–15 Mb/s UL 0.25–2 MB/s path loss, single-layer UL
Phone Wi-Fi hotspot instead of USB tether (same cell) Wi-Fi 5/6 hotspot, 80 MHz — 85–95 % of the rows above hotspot Wi-Fi hop adds ~5–15 % overhead; phones thermally throttle after ~20–30 min of sustained TX (radio + hotspot). USB tether avoids the Wi-Fi hop and charges the phone from Port B.

Latency effects. 5G RTT of 30–60 ms (LTE 50–100 ms), plus a few ms for the USB tether or ~5–10 ms for a hotspot hop, matters for TCP ramp on every new part. Firmware must keep 4–8 parts in flight even at 10 MB/s so that a single connection stall (handover, cell reselection, phone screen-lock hiccup) does not idle the phone's radio. Chunk size on metered/tethered links should drop to 8–16 MB so that a lost connection re-sends little (FR-004).

Why cellular uplink is so far below the headline number. The ~1 Gbps 5G uplink figure quoted for phones and modems assumes 100 MHz of n77/n78, 2 UL layers, 256-QAM, full UL slot allocation, and near-cell-centre SINR. Operators deploy TDD frames that give the uplink ~25–30 % of slots; UL MIMO 2-layer is rarely scheduled; UE power (23 dBm, Power Class 3) limits MCS beyond a few hundred metres; and the aggregate UL of the sector is shared. Speedtest medians for 5G uplink in the US in 2025–26 sit in the 15–35 Mbps range; 90th-percentile users see 80–150 Mbps. This is why a built-in modem was dropped in v0.2 (ADR §14): it would have delivered the same uplink as the phone already in the user's pocket, at ~$146 of BOM and a carrier-certification programme. The honest promise is "uploads over the cellular you already carry, with the phone charging while it works" — not a speed figure.

1.5 Endpoint and Internet-side limits

Endpoint Per-connection practical rate Aggregate limits Implication
Amazon S3 / R2 / B2 / Wasabi / MinIO 50–100 MB/s per TCP connection (TLS, server pacing) 3 500 PUT/s per prefix (S3); effectively unlimited aggregate Use multipart with 8–16 concurrent parts, 16–64 MB parts (5 GB max part, 10 000 parts max → ≥ 100 MB parts for objects > 1 TB)
Google Drive (resumable upload API) 20–60 MB/s per file session 750 GB/day per user upload quota; per-user request quotas Upload several files concurrently; a 1 TB card cannot finish in one day on a standard Google account — surface the quota to the user
Dropbox (upload sessions) 20–60 MB/s per session; 150 MB append chunks Rate limits per app; team storage Concurrent sessions; use upload_session/append_v2 batching
SFTP 30–150 MB/s per connection depending on server CPU and cipher Server CPU / disk 4–8 connections; prefer aes128-gcm or chacha20-poly1305
Venue Internet uplink (the real ceiling behind Ethernet/Wi-Fi) — Studio/post-house 1–10 Gb/s; office 100 Mb/s–1 Gb/s; hotel 20–100 Mb/s; location shoot with Starlink 10–40 Mb/s UL In most locations the venue uplink, not PoppyUp, is the limiter. 5GBASE-T exists for the studio/post-house case.

2. Per-mode bottleneck table

Chain notation: source → … → sink. Bold = the single limiting element.

Mode Chain Rates along chain Limiter Delivered
Standalone — Ethernet 5GbE, CFe B, S3 CFe B card (3.5 GB/s) → Gen3 ×2 (1.65) → DDR → CPU hash+TLS (≥ 1.2 GB/s avail.) → RTL8126 (0.59) → 5GBASE-T / venue uplink 3 500 / 1 650 / 1 200 / 590 / 500 Network 480–520 MB/s
Standalone — Ethernet 1GbE venue as above → 1000BASE-T … / 118 Network 105–115 MB/s
Standalone — tethered phone on Port B, CFe B, S3 CFe B (1.65 GB/s) → CPU → ASM3142 → USB (iPhone ~40 MB/s, Android/adapter ~100) → phone / USB adapter → its NR/LTE uplink 1 650 / … / 40–100 / 2.5–25 Phone's cellular uplink 2.5–25 MB/s
Standalone — Wi-Fi STA to phone hotspot CFe B → CPU → MT7925 → hotspot Wi-Fi (~30–60 MB/s) → phone → its NR/LTE uplink 1 650 / … / 30–60 / 2–22 Phone's cellular uplink (−5–15 % hotspot overhead) 2–22 MB/s
Standalone — Wi-Fi 7, ideal CFe B → CPU → Gen2 ×1 (400) → MT7925 → 6 GHz 160 MHz air → AP → venue uplink 1 650 / 400 / 200–280 Air interface (then venue uplink) 200–280 MB/s
Standalone — Wi-Fi, typical venue … → 80 MHz shared channel 75–110 Air interface / contention 75–110 MB/s
Standalone — SD UHS-II, any link ≥ 2.5GbE SD card (300) → GL9755 → Gen3 ×1 (985) → … → 2.5GbE (295) 300 / 985 / 295 Card ≈ 2.5GbE tie; on 5GbE the card 270–295 MB/s
Standalone — CFast, 5GbE CFast card (500–550) → ASM1064 (550) → Gen3 ×1 (985) → … → 5GbE (590→500) 550 / 550 / 985 / 500 Card ≈ 5GbE tie 480–500 MB/s
Standalone — microSD microSD card (95) 95 Card ~90–100 MB/s
Host — Path 1 (Pro, RO default), USB4 Mac/PC/iPad Pro CFe B card (3.4–3.7 GB/s) → PI3DBS16412 → Gen4 ×2 (3.9 GB/s) → ASM2464PD → USB4 40 Gb/s PCIe tunnel (~3.2–3.4 GB/s) → host NVMe driver 3 500 / 3 900 / 3 300 Card ≈ USB4 tunnel tie 2.8–3.2 GB/s
Host — Path 1 (Pro, RO default), USB 3.2 Gen2 host (iPhone 15/16/17 Pro, TB3-less PC) CFe B (3.5 GB/s) → ASM2464PD in UAS fallback (10 Gb/s) → host UAS 3 500 / 1 000 USB 3.2 Gen2 900–1 000 MB/s
Host — Path 2 (all SKUs, RO default), SoC gadget, any card, USB 3.x host card (≤ 1.65 GB/s) → SoC → dwc3 5 Gb/s UAS gadget → host ≤ 1 650 / 400 SoC USB 3.0 (5 Gbps) gadget 380–420 MB/s
Host — Path 2, USB 2.0 iPhone (non-Pro) card → SoC → dwc3 → USB 2.0 (480 Mb/s) … / 40 iPhone's USB 2.0 port 35–40 MB/s
Host — Path 1 into a USB 2.0 iPhone ASM2464PD falls back to USB 2.0 BOT 40 iPhone's USB 2.0 port 35–40 MB/s (identical to Path 2; Path 1 adds nothing for non-Pro iPhones)
SSD ingest — Port B → S3 over 5GbE SSD (950) → ASM3142 10 Gb/s (1 000) → Gen3 ×2 shared (1 650) → CPU → 5GbE (590→500) 950 / 1 000 / 1 650 / 500 Network 480–520 MB/s
Quick copy — CFe B → NVMe (Pro) CFe B (1.65 read via pcie3x4) → DDR → NVMe write via pcie3x2 (1.65) → SSD sustained (≥ 1.4) 1 650 / 1 650 / 1 400+ Gen3 ×2 NVMe link / SSD sustained write 1.4–1.6 GB/s
Quick copy — CFe A → NVMe (Pro) CFe A (850) → shared pcie3x2 both directions (850 in + 850 out = 1.7 of 1.65) → NVMe 850 / 1 650 shared Shared switch upstream ~750–800 MB/s
Buffer-to-NVMe then upload (network down → up) NVMe read (1.65) → … → network Network as network

3. Worked examples — time to move a card

Assumes sustained realistic rates from §1–2; no per-file overhead (adds 1–5 % for thousands of small stills; negligible for video).

Path Rate 256 GB 1 TB Notes
Card → PoppyUp internal read (CFe B, Gen3 ×2) 1 650 MB/s 2.6 min 10 min Floor for anything downstream
Quick copy CFe B → NVMe (Pro) 1 500 MB/s 2.8 min 11 min Card back in the shooter's hand
Host Path 1, USB4 Mac (Pro) 3 000 MB/s 1.4 min 5.6 min Card-limited; the Mac powers the device over Port C (PD sink, Pro — D7), so session length is not battery-limited
Host Path 1, iPhone Pro (USB 3.2 Gen2) (Pro) 950 MB/s 4.5 min 18 min Device on its own battery (iPhone is not a power source)
Host Path 2, SoC gadget (any card, Mac/PC/iPhone Pro) 400 MB/s 11 min 42 min
Host, iPhone non-Pro (USB 2.0) 38 MB/s 1.9 h 7.3 h Phone-limited; unavoidable
Upload, 5GBASE-T to S3 (studio) 500 MB/s 8.5 min 33 min Battery: ~0.55 h of 4.4 h used per TB
Upload, 2.5GBASE-T 280 MB/s 15 min 60 min
Upload, 1000BASE-T 110 MB/s 39 min 2.5 h Most common wired case
Upload, Wi-Fi 7 ideal 250 MB/s 17 min 67 min
Upload, typical venue Wi-Fi 90 MB/s 47 min 3.1 h
Upload, 100 Mb/s venue uplink 11 MB/s 6.5 h 25 h Venue-limited regardless of link type
Upload, phone/adapter on 5G, good C-band cell (USB tether or hotspot) 18 MB/s 4.0 h 15.4 h 1 TB exceeds one battery (8.3 h hotspot / 4.1 h tether charging the phone at 1.5 A) → needs PD; the phone needs power too
Upload, phone/adapter on 5G, typical 6 MB/s 11.9 h 46 h Two–six battery charges or external power for device and phone
Upload, phone on LTE, rural 1 MB/s 71 h 12 days Selects-only workflow; no hardware (ours or a built-in modem) can fix this

Reading the table. The ratio between the internal read rate and the typical 5G uplink of the user's phone is 1 650 / 6 ≈ 275×; against rural LTE, ~1 650×. This is the central UX fact of the product, and it is unchanged by removing the built-in modem — the uplink was always the phone-class cellular uplink, whoever owns the radio. Over a tethered or hotspot phone, PoppyUp is a background uploader that runs for hours on a cart or a desk (charging the phone from Port B as it goes; a bag is for transport only — ADR §1, D2), and the firmware must let the user prioritise files (selects, proxies, low-res first) rather than blindly walking the directory. Over studio Ethernet it is a foreground tool that finishes a card in minutes.


4. Design conclusions

4.1 Why Gen3 on the card side is not a real compromise in standalone mode

CFexpress 4.0 Type B cards run at Gen4 ×2 (3.5–3.7 GB/s). Our RK3588 root port is Gen3 ×2 (~1.65 GB/s delivered). That is a 2× haircut on paper. It is irrelevant for the primary function because:

  1. The fastest network we ship (5GBASE-T) drains at ~500 MB/s — 3.3× below our Gen3 ×2 read rate. The card link would have to be slower than ~600 MB/s before it became the bottleneck on any network path.
  2. The only internal consumer that could use > 1 GB/s is the optional NVMe quick copy, and it is itself limited by a Gen3 ×2 NVMe link and by SSD sustained-write behaviour to ~1.4–1.6 GB/s.
  3. Going Gen4 would require a Gen4-capable root (no RK3588; i.MX 95 and QCS6490 are Gen3 too) or a Gen4 switch (Microchip Switchtec PFX/PM40028 class, 5–8 W, $60+), for zero standalone benefit.

Where Gen4 does matter — a human waiting at a Mac for a card to offload — we bypass the SoC entirely (Path 1) and give the host the card's native Gen4 ×2 link through the ASM2464PD. That is exactly the silicon inside every current USB4 CFexpress 4.0 reader, so we inherit their performance and their compatibility history.

4.2 Why USB4 pass-through matters only for host mode — and why it is worth a port on the Pro SKU

Path 1 delivers 2.8–3.2 GB/s to USB4 hosts and 0.9–1.0 GB/s to iPhone Pro. Path 2 (SoC gadget) delivers 0.4 GB/s to both. For a 1 TB card that is 6 min vs 42 min on a Mac and 18 min vs 42 min on an iPhone Pro. Professional users benchmark readers; an $80 USB4 reader beating the device's reader mode by 7× would define the product's reputation in reviews even though reader mode is secondary. The cost is one IP67 USB-C receptacle, the ASM2464PD ($12–15), a Gen4 ×2 mux ($3), a PD sink controller and VBUS priority mux (~$3–4, verify), and 10-layer low-loss routing on ~60 mm of trace. Restricting Path 1 to the CFe B slot (the top-priority media) keeps the PCIe topology simple (one mux, no second switch) and avoids the USB 3.2-fallback limitation of the bridge (it can present exactly one NVMe device).

Where the host's bottleneck actually is (D7). When the user offloads through a host app — the iPhone or Mac app pulling files from PoppyUp and pushing them to the cloud — the host's own internet link (hotel Wi-Fi, the phone's cellular uplink, §1.4–1.5) is the bottleneck, not the USB hop: Port A's ~380 MB/s (Path 2) already outruns any host uplink by 10–100×, so app-driven cloud upload needs nothing more than Port A. Port C's value is confined to fast local copies to the host's own SSD (the 6-min-per-TB case above). That is why Port C is Pro SKU only (depopulated on Base, same PCB), why Base is fully validated and shippable without it, and why its schedule is decoupled from the Base launch (ADR §10, §12). Both paths present the card read-only by default (D8); on Port C, enforcement is layered — NVMe namespace write protection where the card supports it, bridge write-protect in UAS fallback, otherwise an explicit per-session consent prompt (02-system-architecture.md §4.10). Read-only enforcement has no effect on the read rates in this document.

Power in a Port C session (D7). On the Pro SKU Port C is also a PD sink: a Mac attached on Port C (typically 15 W) powers the device through a priority mux into the charger (Port A has priority), so a USB4 reader session is not limited by the ADR §6.2 runtime row (6.4 h on battery) — it runs indefinitely. An iPhone on either port is never a power source; those sessions run on PoppyUp's battery.

The alternative of putting Path 1 and Path 2 on a single connector was rejected: it needs a 20 GBd-per-lane (USB4 Gen3) 2:1 SuperSpeed mux ahead of both bridges plus PD-controller coordination to select the path before link training — parts are scarce, signal-integrity margin at 40 Gbps shrinks, and the failure modes are subtle. Two labelled ports are the robust answer for a v1 (ADR §13.1).

4.3 Where the headroom is, for years

Element Today's need Capacity in this design Headroom
Card read (CFe B) 500 MB/s (5GbE) 1 650 MB/s 3.3×
Host reader (Path 1, Pro) card-limited ~3.3 GB/s tunnel tracks card generations through CFexpress 4.0; CFexpress "5.0"/Gen5 would exceed it
Ethernet 100 Mb/s–1 Gb/s venues 5 Gb/s 5–50× over typical venue uplinks
Wi-Fi Wi-Fi 6 venues (75–110 MB/s) Wi-Fi 7 2×2 (200–280) 2–3×
Cellular (via phone / USB adapter on Port B) phone-class 5G NR / LTE uplink n/a — the user's phone and USB adapters upgrade with the market (Rel-17 UL MIMO, 5G-Advanced) at no change to PoppyUp; USB 3.2 Gen2 on Port B outruns any of them tracks the phone market, no board change
CPU 1.5 A76 cores at 500 MB/s 4 A76 + 4 A55 ~2× at 5GbE (10GbE, which would have consumed the whole A76 cluster, was rejected — D6)
NVMe 1.4–1.6 GB/s Gen3 ×2 matches CFe B internal read
Modularity — 2 M.2 sockets (Key-E Wi-Fi, M-key NVMe), reader daughterboard, 2× spare Gen2 ×1 + spare USB3 on test headers new slot mixes / radios / a daughterboard without main-board re-spin (a built-in modem is not a population option — ADR §13 item 12)

4.4 Ethernet: 5GBASE-T is final (D6)

The Ethernet interface is the Realtek RTL8126 5GBASE-T MAC/PHY on one Gen3 ×1 switch lane — final (D6, ADR §5); no 10GBASE-T footprint option or watch item is carried. Why: a 10GBASE-T PHY dissipates +2–4 W over the RTL8126's 1.9 W inside a sealed passive enclosure whose whole shutter-closed ceiling is ~10 W at 25 °C (ADR §2), S3 with SHA-256 at 1.1 GB/s would consume the entire A76 cluster (§1.3), and real-world venue uplinks (§1.5) rarely exceed 1 Gb/s — 5GBASE-T is already 5–50× headroom over them. The card side (CFe B at 1.65 GB/s) is unaffected either way.

4.5 Consequences for firmware (Phase 2), recorded here so hardware does not block them

  • Multipart/multi-connection everywhere (S3 8–16 parts, SFTP 4–8 connections, Drive/Dropbox several files) — the hardware provides the CPU for it.
  • Adaptive chunk size per link (64 MB Ethernet, 16 MB Wi-Fi, 8 MB metered/tethered — phone hotspot, USB tether, USB cellular adapter) — FR-004.
  • Priority-aware upload order on slow links (user-defined selects, smallest-first, proxies-first).
  • Per-part hashing pipelined with reads (double-buffered DMA) so the card read and the network TX overlap; no store-and-forward.
  • Metered/tethered links: keep 4–8 parts in flight; count bytes per link in the job engine (there are no modem counters to read) and cross-check against endpoint-reported bytes (FR-025). Surface the phone's trust/unlock prompt and the SSD-vs-tether exclusivity on Port B (FR-026, FR-030).

5. Data-path diagram with rates

flowchart LR
  subgraph CARDS["Top-edge media (read-only)"]
    CFB["CFexpress B 4.0<br/>card 3.5 GB/s"]
    CFA["CFexpress A 4.0<br/>card 1.8 GB/s"]
    SD["SD UHS-II<br/>card 0.30 GB/s"]
    USD["microSD UHS-I<br/>card 0.10 GB/s"]
    CFAST["CFast 2.0<br/>card 0.55 GB/s"]
  end
  SSD["External SSD<br/>Port B, 0.95 GB/s"]

  MUX{{"PI3DBS16412<br/>Gen4 x2 mux"}}
  CFB -->|"Gen4 x2"| MUX
  MUX -->|"A: Gen3 x2<br/>1.65 GB/s"| RP1["RK3588 pcie3x4<br/>root port"]
  MUX -->|"B: Gen4 x2<br/>3.9 GB/s"| BR["ASM2464PD<br/>USB4 bridge"]
  BR -->|"USB4 tunnel<br/>2.8-3.2 GB/s"| MAC["USB4 host (Mac/PC/iPad)<br/>Pro only, RO default<br/>Mac powers device (PD sink)"]
  BR -.->|"USB 3.2 Gen2 UAS<br/>0.9-1.0 GB/s"| IPP["iPhone Pro"]

  SW["ASM2812 switch<br/>upstream Gen3 x2<br/>1.65 GB/s shared"]
  CFA -->|"Gen3 x1 0.85"| SW
  SD -->|"GL9755"| SW
  USD -->|"GL9750"| SW
  CFAST -->|"ASM1064 SATA<br/>0.38-0.55"| SW
  SSD -->|"ASM3142 10G"| SW
  NVME["NVMe (Pro)<br/>Gen3 x2 1.6 GB/s"] <--> SW
  SW --> RP2["RK3588 pcie3x2<br/>root port"]

  RP1 --> CPU["RK3588 4xA76<br/>hash + TLS<br/>&gt;1.2 GB/s available"]
  RP2 --> CPU

  CPU -->|"Gen3 x1"| ETH["RTL8126 5GbE<br/>0.48-0.52 GB/s"]
  CPU -->|"Gen2 x1"| WIFI["MT7925 Wi-Fi 7<br/>0.075-0.28 GB/s"]
  SW -->|"ASM3142 10G<br/>USB 0.04-0.10 GB/s"| TETH["Port B tether<br/>phone or USB cellular adapter<br/>(user's device)"]
  CPU -->|"dwc3 5 Gbps gadget"| PA["Port A host, RO default<br/>0.40 GB/s (USB3)<br/>0.04 GB/s (USB2)"]

  ETH --> NET["Venue uplink<br/>0.01-1.2 GB/s"]
  WIFI --> NET
  WIFI -.->|"phone hotspot<br/>0.03-0.06 GB/s"| CELL
  TETH --> CELL["Phone / adapter<br/>cellular uplink<br/>0.0025-0.025 GB/s"]
  NET --> EP["Endpoint<br/>S3 / SFTP / Drive / Dropbox"]
  CELL --> EP

  style CELL fill:#ffe0e0,stroke:#c00
  style NET fill:#fff3d0,stroke:#c80

Red = the real-world bottleneck: the tethered or hotspot phone's (or USB adapter's) cellular uplink, 2.5–25 MB/s — not PoppyUp hardware. Amber = the usual bottleneck on wired/Wi-Fi paths (venue uplink). Everything inside PoppyUp runs at 0.4–3.2 GB/s; the USB tether link itself (0.04–0.10 GB/s) is still 2–40× above the cellular uplink it carries.


6. Measurements to take at PoC (closes the assumptions above)

# Measurement Pass
M1 CFe B 4.0 cards from 3 vendors negotiate Gen3 ×2 on RK3588 root; fio seq read QD8 1 MB ≥ 1.6 GB/s (NFR-014)
M2 Same cards via ASM2464PD → M-series Mac (Pro path); record NWPC support (Identify Controller byte 531) per card for the Port C read-only mechanism ≥ 2.8 GB/s; → iPhone 15 Pro ≥ 900 MB/s (NFR-015); NWPC table complete for the IF-001 card list (FR-045-A)
M3 Hot re-route via PI3DBS16412 with REFCLK mux, 1 000 cycles 0 link-training failures, 0 FS errors (FR-043)
M4 S3 (MinIO on LAN) over RTL8126 5GbE with TLS + SHA-256, 100 GB ≥ 480 MB/s, ≤ 2 A76 cores (NFR-010, NFR-018)
M5 dwc3 f_tcm UAS gadget → Mac and iPhone 15 Pro ≥ 380 MB/s (NFR-016); Files app browses exFAT
M6 ASM2812 concurrency: CFe A read + NVMe write + Ethernet TX Fair sharing; CFe B path unaffected
M7 Tethered uplink: iPhone (ipheth) and Android (NCM/RNDIS) on Port B, plus Wi-Fi STA to the same phone's hotspot, iperf3 UL at 5 sites vs the phone's own speed test; 100 attach/detach cycles; phone charge current at 0.5/1.5/3 A ≥ 90 % of phone (NFR-013); enumerate ≤ 10 s, 0 stuck states (FR-026); ILIM ±10 % (FR-030)
M8 MT7925 STA+AP concurrent throughput ≥ 60 % of STA-only (FR-028)
M9 GL9755 HD312 with V90 cards; GL9750 SDR104; ASM1064 with CFast ≥ 480 MB/s, note trained link width/speed per NFR-014