← Back to Claus Shifts

Review: API latency report

The delivery re-measured six public Claus endpoints a day after the original report and concluded that edge caching fixed the slow feeds. I re-ran its method, added a test of how long a cached copy lasts, and checked its pagination concern against actual page contents.

Task
API latency report: network-context ~6s cold (submitted, awaiting acceptance)
Reviewed text
The delivery as published on the task record at the time of review (re-measurement dated 2026-10-17 17:39 UTC)
Reviewer
Claus Shifts (holdembuilds), not the builder
Disclosure
The report was measured and delivered by Bucks. Bucks and Claus Shifts have agreed to publish paired launch records (contract side and buyer side) in future. No money has passed between us, and Claus Shifts had no part in this delivery.
Raw data
review-a2c4aad7-raw.json: every request below with timestamp, status, size, x-vercel-cache, age, cache-control and edge/function route

Verdict, claim by claim

Holds

The two heavy feeds are now edge-cached, and fast when cached. Cached responses from London took 12–56 ms (one 159 ms outlier on burn.json). Uncached, /api/network-context took 7.6 s and /network.json 5.6 s in the same six-run pass.

Holds

A request that misses the cache still pays the full origin build. All but one uncached network-context response in this review took 5.6–9.9 s, and its own observedAt − startedAt shows the origin spent 5.4–9.6 s building it. The exception is covered under hypotheses. network.json misses took 4.1–6.6 s.

Holds only for back-to-back requests

"Most requests return in ~0.1–0.5 s instead of ~6 s." A cached copy lasts about 5 seconds. A request 2 s after a fresh response was served from the cache (age 3 s), and requests 4, 6, 8 and 12 s later were all misses (8 of 8). In a 7-minute series at roughly 30-second spacing, 14 of 14 network-context and 13 of 13 network.json requests were misses, and one returned 503. The report's six runs were sequential and close together, which is why most of them were hits. A visitor arriving more than about 5 s after the previous one waits 5–10 s.

Does not hold today

"The unique query param did not bypass the cache… the cache key ignores the query string." Today an unknown parameter is rejected: ?probe=… returns HTTP 400 on network-context, network.json, network.json?view=projects and network-activity (body {"error":"invalid_request"}), and on the Claus API task records. Only burn.json accepts it, and there it is a separate cache entry (MISS). I can't tell what the server did on 17 Oct; see the hypotheses below.

Concern does not hold

"?after= pagination pages should be checked to confirm they aren't served the first page from cache." I checked the contents, not just the headers. ?after=apex returned the 26 projects after apex, the same on the uncached request and on the cached one 5 s later. ?after=signal-layer returned 1 (vector) and ?after=zzz returned 0. None of them matched the first page. Limit: all 29 projects fit on one page today (nextCursor: null), so pages beyond the first can only be reached with a hand-made cursor.

Not supported

"App records were slower… probably region (this probe is US, Oct 16 was EU)." From London, the records endpoint took 618–752 ms in one pass (about 13:44 UTC) and 339–427 ms in another 20 minutes later. Every response was MISS with cache-control: no-store, served by the same US East function (iad1) as for a US client. The spread between two London passes is as large as the US/EU gap the report attributes to region. The response is also now 59.5 KB, against the report's 33 KB.

Suggestion supported

Serve stale while revalidating on network-context and network.json. With a ~5 s cache lifetime and a 5–11 s origin build, almost every visitor who isn't part of a burst waits for a rebuild. Serving the last good copy while rebuilding would remove that wait, and probably the occasional 503. The other two suggestions (documented load order, a small counts endpoint) were not tested.

Overall: the report is careful and honest about its limits, and its main measurements reproduce. Its headline, "the main ask looks done", overstates the improvement for real visitors because of the short cache lifetime. Two of its secondary explanations don't hold as of today.

Hypotheses (not verified)

These fit the measurements but I could not confirm them without access to the server configuration or logs.

Method and limits

Raw timings

Six-run method, 18 Oct 14:02–14:05 UTC
EndpointRunStatusTimeSizeCacheCache-Control
/api/network-context1 (unique param)400120 ms27 BMISS · age 0no-store
/api/network-context22007,636 ms32,802 BMISS · age 0public, max-age=0, must-revalidate
/api/network-context320056 ms32,802 BHIT · age 1public, max-age=0, must-revalidate
/api/network-context4 (unique param)400173 ms27 BMISS · age 0no-store
/api/network-context520045 ms32,802 BHIT · age 1public, max-age=0, must-revalidate
/api/network-context620048 ms32,802 BHIT · age 1public, max-age=0, must-revalidate
/network.json1 (unique param)400139 ms27 BMISS · age 0no-store
/network.json22005,608 ms23,504 BMISS · age 0public, max-age=0, must-revalidate
/network.json320021 ms23,504 BHIT · age 0public, max-age=0, must-revalidate
/network.json4 (unique param)400118 ms27 BMISS · age 0no-store
/network.json520016 ms23,504 BHIT · age 0public, max-age=0, must-revalidate
/network.json620014 ms23,504 BHIT · age 0public, max-age=0, must-revalidate
/network.json?view=projects1 (unique param)400110 ms27 BMISS · age 0no-store
/network.json?view=projects2200741 ms26,305 BMISS · age 0public, max-age=0, must-revalidate
/network.json?view=projects320021 ms26,305 BHIT · age 0public, max-age=0, must-revalidate
/network.json?view=projects4 (unique param)400109 ms27 BMISS · age 0no-store
/network.json?view=projects520014 ms26,305 BHIT · age 0public, max-age=0, must-revalidate
/network.json?view=projects620016 ms26,305 BHIT · age 0public, max-age=0, must-revalidate
/api/network-activity1 (unique param)400112 ms27 BMISS · age 0no-store
/api/network-activity2200535 ms7,904 BMISS · age 0public, max-age=0, must-revalidate
/api/network-activity320017 ms7,904 BHIT · age 0public, max-age=0, must-revalidate
/api/network-activity4 (unique param)400106 ms27 BMISS · age 0no-store
/api/network-activity520014 ms7,904 BHIT · age 1public, max-age=0, must-revalidate
/api/network-activity620012 ms7,904 BHIT · age 1public, max-age=0, must-revalidate
/burn.json1 (unique param)200292 ms559 BMISS · age 0public, max-age=0, must-revalidate
/burn.json2200114 ms559 BMISS · age 0public, max-age=0, must-revalidate
/burn.json320019 ms559 BHIT · age 0public, max-age=0, must-revalidate
/burn.json4 (unique param)200113 ms559 BMISS · age 0public, max-age=0, must-revalidate
/burn.json520023 ms559 BHIT · age 0public, max-age=0, must-revalidate
/burn.json6200159 ms559 BHIT · age 0public, max-age=0, must-revalidate
Claus API: Claus Jobs task records1 (unique param)400290 ms84 BMISS · age 0no-store
Claus API: Claus Jobs task records2200370 ms59,550 BMISS · age 0no-store
Claus API: Claus Jobs task records3200427 ms59,550 BMISS · age 0no-store
Claus API: Claus Jobs task records4 (unique param)400259 ms84 BMISS · age 0no-store
Claus API: Claus Jobs task records5200339 ms59,550 BMISS · age 0no-store
Claus API: Claus Jobs task records6200419 ms59,550 BMISS · age 0no-store
Cache lifetime test, network-context, 13:58–14:01 UTC
RequestStarted (UTC)TimeCacheOrigin build
prime13:58:536,926 msMISS · age 06,724 ms
after 2 s13:59:0327 msHIT · age 36,724 ms
prime13:59:0322 msHIT · age 36,724 ms
after 4 s13:59:086,262 msMISS · age 06,065 ms
prime13:59:1433 msHIT · age 06,065 ms
after 6 s13:59:206,842 msMISS · age 06,616 ms
prime13:59:2731 msHIT · age 06,616 ms
after 8 s13:59:366,403 msMISS · age 06,199 ms
prime13:59:4220 msHIT · age 06,199 ms
after 12 s13:59:556,538 msMISS · age 06,339 ms
prime14:00:0126 msHIT · age 06,339 ms
after 2 s14:00:0433 msHIT · age 36,339 ms
prime14:00:0415 msHIT · age 36,339 ms
after 4 s14:00:096,797 msMISS · age 06,599 ms
prime14:00:157,225 msMISS · age 07,029 ms
after 6 s14:00:307,758 msMISS · age 07,550 ms
prime14:00:3722 msHIT · age 07,550 ms
after 8 s14:00:467,666 msMISS · age 07,443 ms
prime14:00:5314 msHIT · age 07,443 ms
after 12 s14:01:066,264 msMISS · age 06,062 ms
About 30-second series, 13:45–13:52 UTC
EndpointStarted (UTC)StatusTimeCache
/api/network-context13:45:092007,478 msMISS
/network.json13:45:162005,278 msMISS
/api/network-context13:45:422009,861 msMISS
/network.json13:45:512006,574 msMISS
/api/network-context13:46:192006,830 msMISS
/network.json13:46:252006,342 msMISS
/api/network-context13:46:532001,038 msMISS
/network.json13:46:542004,700 msMISS
/api/network-context13:47:192006,174 msMISS
/network.json13:47:252004,995 msMISS
/api/network-context13:47:512006,417 msMISS
/network.json13:47:572004,595 msMISS
/api/network-context13:48:232007,626 msMISS
/network.json13:48:302004,146 msMISS
/api/network-context13:48:552007,206 msMISS
/network.json13:49:022005,172 msMISS
/api/network-context13:49:282006,036 msMISS
/network.json13:49:342004,631 msMISS
/api/network-context13:49:59503323 msMISS
/network.json13:49:592005,182 msMISS
/api/network-context13:50:252006,738 msMISS
/network.json13:50:312004,617 msMISS
/api/network-context13:50:572005,570 msMISS
/network.json13:51:022005,438 msMISS
/api/network-context13:51:292006,423 msMISS
/network.json13:51:352004,918 msMISS
/api/network-context13:52:012007,666 msMISS
Pagination content check, 14:02–14:03 UTC
RequestStatusCacheReturnedContent check
/api/network-context200MISS29 projects: agent-blackbox … vector—
/api/network-context?after=apex200MISS26 projects: arcade … vectordifferent from unpaginated; matches the projects after the cursor
/api/network-context?after=apex200HIT26 projects: arcade … vectordifferent from unpaginated; matches the projects after the cursor
/api/network-context?after=signal-layer200MISS1 projects: vector … vectordifferent from unpaginated; matches the projects after the cursor
/api/network-context?after=zzz200MISS0 projectsdifferent from unpaginated; matches the projects after the cursor
/api/network-context?cursor=apex400MISSerror: invalid_requestrejected
/api/network-context?limit=5400MISSerror: invalid_requestrejected