carlos / platform Public

edge: purge_header.go's cost paragraph no longer claims PurgeHost scans the cache

Stale after the byHost index landed: PurgeHost used to scan every entry
(the "32x at a full cache" figure), but now costs one map lookup for the
host's own entry set via byHost (see cache.go). Restated the caps'
justification on what still holds — both the capped-targets path and the
degrade path are bounded operations whose cost doesn't scale with what the
header declares — rather than a cost differential that no longer exists.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 542f97a397be1fce6eb9fe09783c83c45cf97e82 parent 13b3b05
1 file changed, +11 −11
  • internal/edge/purge_header.go +11 −11
diff --git a/internal/edge/purge_header.go b/internal/edge/purge_header.go
index 0112f6697..c9afa81a6 100644
--- a/internal/edge/purge_header.go
+++ b/internal/edge/purge_header.go
@@ -140,17 +140,17 @@ const PurgeHostHeader = "Carlos-Purge-Host"
// path: without them a single response could name a million targets and drive
// a million locked cache operations before the client gets its bytes.
//
-// Degrading is NOT the cheap path — it is the SIMPLE one, and it is more
-// expensive than honouring the declaration. Honouring 64 targets is 128 map
-// lookups (each target hits the GET and HEAD index groups); PurgeHost takes
-// the same global lock and scans EVERY entry in the cache, which at
-// DefaultCacheMaxEntries (4096) is an order of magnitude more work — roughly
-// 32x at a full cache, and worse the fuller the cache is. So an app gains
-// nothing by exceeding the bound except a bigger blast radius on its own
-// cache; the bound is a cliff in behaviour (targeted -> whole host), not an
-// invitation. What the caps genuinely buy is that the per-response cost has a
-// CEILING that does not scale with the header's length — one host scan
-// instead of unbounded lookups.
+// Degrading is NOT the cheap path — it is the SIMPLE one. Honouring 64
+// targets is a bounded operation: up to 128 map lookups (each target hits
+// the GET and HEAD index groups) plus parsing each target string. PurgeHost
+// is bounded too — it rides the byHost index (see cache.go), a single map
+// lookup for the whole host's entry set, not a scan of the cache. Neither
+// path's cost is the point of the caps; what they genuinely buy is that the
+// per-response cost has a CEILING that does not scale with how much the
+// header declares, whichever path is taken. So an app gains nothing by
+// exceeding the bound except a bigger blast radius on its own cache — the
+// coarser whole-host purge, not a more precise one; the bound is a cliff in
+// behaviour (targeted -> whole host), not an invitation.
//
// 64 targets is well above what a real write invalidates (a page, its
// paginated index, a couple of locale variants). 8 KiB bounds the joined