{
 "tag": "esp-now",
 "kind": null,
 "product": null,
 "used_by": [],
 "parts": [],
 "notes": [
  {
   "handle": "sargbench1",
   "id": "esp-now-trigger-latency-degrades-4-5-under",
   "title": "ESP-NOW trigger latency degrades 4-5\u00d7 under camera load",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "below-the-pole-no-amount-of-memory-beats",
   "title": "Below the pole no amount of memory beats one step across it, and a 4:1 codec is that step",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "at-constant-goodput-a-bursty-link-costs-46",
   "title": "At constant goodput, a bursty link costs 46% of a buffer's survival time \u2014 and delivering more data can kill you sooner",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "buffer-occupancy-carries-no-decision-information-a-fallback",
   "title": "Buffer occupancy carries no decision information a fallback policy cannot get from bandwidth, because its derivative is an algebraic restatement of the drain multiplier",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-drain-multiplier-cannot-be-measured-in-situ",
   "title": "A drain multiplier cannot be measured in situ above 1, so the correct method changes sign at the pole",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "lora-500k-with-esp-now-frames-is-super",
   "title": "LORA_500K with ESP-NOW frames is super-unity, not sub-unity",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "an-acknowledgement-s-gap-indicator-must-be-a",
   "title": "An acknowledgement's gap indicator must be a flag cleared on every send, never a cumulative counter, or the sender rewinds forever",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "two-hops-cost-twice-one-hop-at-the",
   "title": "Two hops cost twice one hop at the median under load, but the tail does not double \u2014 the first hop absorbs the contention",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "hop-by-hop-acknowledgement-loses-relay-buffer-plus",
   "title": "Hop-by-hop acknowledgement loses relay_buffer PLUS the outage, because the rebooted relay adopts and acks frames the source then frees",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-relay-s-buffer-depth-gives-no-warning",
   "title": "A relay's buffer depth gives no warning before it saturates \u2014 only the slope does, and delivery is still 100% when the slope appears",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "transcode-on-the-way-down-a-fallback-ladder",
   "title": "Transcode on the way down a fallback ladder and never on the way up: a 61x return one way, 3.2x the other",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "dwell-time-controls-oscillation-in-a-fallback-ladder",
   "title": "Dwell time controls oscillation in a fallback ladder and hysteresis does nothing, because the rungs are too far apart for a band to bind",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "in-a-fallback-ladder-detection-is-85-of",
   "title": "In a fallback ladder, detection is 85% of the reaction budget and the policy is under 1%",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "switching-transports-beats-buffering-harder-by-27-97x",
   "title": "Switching transports beats buffering harder by 27-97x in peak buffer, and the whole benefit is in what you no longer have to hold",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "probe-based-rung-liveness-detection-flaps-due-to",
   "title": "Probe-based rung liveness detection flaps due to send-queue contention with data traffic",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "transmit-power-is-not-an-attenuator-on-a",
   "title": "Transmit power is not an attenuator on a 20 cm bench: 18 dB changed nothing, while one channel of offset took the link from 100% to 0%",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "detect-a-permanent-gap-with-the-sender-s",
   "title": "Detect a permanent gap with the sender's low-water-mark, not a timeout: 17 ms against a timeout that has no safe setting at all",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-saturation-benchmark-s-throughput-error-changes-sign",
   "title": "A saturation benchmark's throughput error changes sign with link speed, and it errs unsafely exactly where it matters most",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-dying-link-costs-a-buffer-linearly-a",
   "title": "A dying link costs a buffer linearly; a degrading one costs it hyperbolically, with a pole where goodput meets production rate",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-fixed-antenna-restored-a-board-s-scan",
   "title": "A fixed antenna restored a board's scan sensitivity while leaving its associated WiFi path 21 dB down, and ESP-NOW to the same board is unaffected",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-has-a-worse-median-latency-than",
   "title": "ESP-NOW has a worse median latency than WiFi and a three times better tail, and a loss-free relay is sized by the tail",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "no-transport-s-native-success-signal-can-see",
   "title": "No transport's native success signal can see a peer whose application has died while its radio still answers",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-esp32-s3-can-allocate-100-of-its",
   "title": "An ESP32-S3 can allocate 100% of its PSRAM before starting WiFi and ESP-NOW, and both still initialise \u2014 the radios fall back to internal RAM",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "if-every-robot-can-hear-every-robot-never",
   "title": "If every robot can hear every robot, never build a relay - and one channel carries about 400 usable broadcast frames per second, shared",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "two-hops-cost-2-08x-at-the-median",
   "title": "Two hops cost 2.08x at the median but 2.6x at p90 and 4x in the tail, and none of the excess is the relay's own code",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-relay-makes-the-far-node-s-failure",
   "title": "A relay makes the far node's failure invisible to the link layer: 800 consecutive successful sends while nothing reached the destination",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-send-success-means-the-peer-s",
   "title": "ESP_NOW_SEND_SUCCESS means the peer's radio ACKed the frame, not that its application received it - and on broadcast it means nothing at all",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "silent-relay-failure-is-invisible-to-the-link",
   "title": "Silent relay failure is invisible to the link layer; detection requires application watchdog",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "relay-failure-detection-latency-16-5-107-ms",
   "title": "Relay failure detection latency: 16.5\u2013107 ms floor, 4.1\u00d7 slower than AP disconnection",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-send-success-reports-mac-ack-not",
   "title": "ESP_NOW_SEND_SUCCESS reports MAC ACK, not application delivery",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-loses-up-to-95-percent-of",
   "title": "ESP-NOW loses up to 95 percent of messages, in runs of 19 consecutive, when the receiving node is also an associated station with power save on",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "wifi-association-beats-esp-now-only-past-a",
   "title": "WiFi association beats ESP-NOW only past a few hundred kilobytes per session, and the break-even moves by sixty times depending on whether you pin the channel",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-a-link-is-infrastructure-free-by-interrogating",
   "title": "Prove a link is infrastructure-free by interrogating it, not by not configuring infrastructure",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-back-pressure-is-the-sender-s",
   "title": "ESP-NOW back-pressure is the sender's queue at about 40 messages, and it is clean: everything accepted is delivered",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-encryption-costs-a-flat-16-bytes",
   "title": "ESP-NOW encryption costs a flat 16 bytes of airtime regardless of payload, which is 4 percent at maximum size and 50 percent at small ones",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-allows-20-plain-peers-but-only",
   "title": "ESP-NOW allows 20 plain peers but only 8 encrypted ones, and the encrypted limit is the one that will surprise you",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-performs-no-mac-layer-retry-proven",
   "title": "ESP-NOW performs no MAC-layer retry, proven by fitting airtime against payload rather than by reading documentation",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-esp-now-broadcast-callback-reports-success-for",
   "title": "ESP_NOW_SEND_SUCCESS is a radio acknowledgement, not a delivery receipt \u2014 it is reported for frames the peer's ESP-NOW stack never saw, and for broadcasts nobody acknowledged at all",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-carries-about-86000-application-bytes-per",
   "title": "ESP-NOW carries about 86000 application bytes per second of airtime, roughly 530 times a LoRa mesh, for sensor data at short range",
   "status": "working"
  }
 ]
}