@@ -238,27 +238,45 @@ usual culprit behind an inexplicably slow list), 18ms in **3** business hooks,
238238and 7ms serializing the response. ` db ` and ` hooks ` are aggregates — one member
239239carrying the summed duration and the event count, not one member per query.
240240
241- This is ** off by default** : the header discloses internal phase durations,
242- which is helpful for profiling but also lets a caller fingerprint the backend.
243- Treat it as a perf-tuning toggle you flip in staging (or briefly in production
244- behind an allowlist), not a default-on header.
241+ The header discloses internal phase durations, which is helpful for profiling
242+ but also lets a caller fingerprint the backend, so disclosure is ** gated** .
243+ There are two ways to turn it on:
245244
246- Enable it on the Hono server plugin:
245+ ** Global** — every response carries the header. Flip this in staging, or
246+ briefly on a production environment under active investigation:
247247
248248``` ts
249249new HonoServerPlugin ({ serverTiming: true });
250250```
251251
252252…or, for the default ` os serve ` server (which constructs the plugin for you),
253- via the environment:
253+ via the environment (` OS_PERF_TIMING=1 ` and the older ` OS_SERVER_TIMING=true `
254+ are equivalent):
254255
255256``` bash
256- OS_SERVER_TIMING=true os serve
257+ OS_PERF_TIMING=1 os serve
257258```
258259
259- When enabled, every response carries ` total ` (the whole request, measured by
260- an outer middleware) plus the sub-phases the request path records out of the
261- box:
260+ ** Per-request** — available by default (unless hard-disabled below), with ** no
261+ redeploy** : the caller sends the request header
262+
263+ ```
264+ X-OS-Debug-Timing: 1
265+ ```
266+
267+ and the ` Server-Timing ` header comes back ** only** when the request resolves an
268+ ** admin/service identity** (a platform/tenant admin, a service token, or an
269+ internal system call). An ordinary user who sends the header gets nothing back —
270+ they can never pull timings, so this is safe to leave available on a live
271+ environment. This is the path to reach for when diagnosing "why is * this* request
272+ slow?" against a running environment.
273+
274+ To hard-disable both paths (no middleware registered at all), set
275+ ` serverTiming: false ` explicitly.
276+
277+ When timing is emitted, every response carries ` total ` (the whole request,
278+ measured by an outer middleware) plus the sub-phases the request path records
279+ out of the box:
262280
263281| Member | Recorded by | Meaning |
264282| :---| :---| :---|
@@ -316,5 +334,7 @@ countServerTiming('db', queryMs, 'queries'); // → db;dur=<sum>;desc="<n> queri
316334- [ ] Log records include ` requestId ` field; cross-checked one against the
317335 response ` X-Request-Id ` header.
318336- [ ] Alerts wired: error rate, p95 latency per route.
319- - [ ] (Optional) ` Server-Timing ` verified in DevTools when ` serverTiming ` /
320- ` OS_SERVER_TIMING=true ` is enabled, and confirmed ** absent** by default.
337+ - [ ] (Optional) ` Server-Timing ` verified in DevTools with global mode
338+ (` serverTiming: true ` / ` OS_PERF_TIMING=1 ` ) on, confirmed ** absent** for a
339+ normal request, and confirmed the per-request ` X-OS-Debug-Timing: 1 ` header
340+ returns timing ** only** to an admin/service caller.
0 commit comments