~0x64616E69656C
nxTLS · EXP 06 / Priority-Aware Early Flush (G0A) · 2026-10-21

The frame was ready.
The record wasn't.

What if nginx could emit a critical HTTP/2 DATA frame before filling the next TLS output buffer? G0A demonstrates that boundary: one short record, then normal bulk output. Phase 3E also forced actual BoringSSL WANT_WRITE during the selected prefix and recovered intact in four controlled cases, without changing G0A. The native socket prefix gate remains open.

G0A · mechanism and controlled retry demonstrated.
Stock comparison: 300/300 runs.
Selective TLS records: 4,381 / 4,241 B.
Deterministic prefix recovery: 4/4 PASS.
Phase 3E responses: 20/20 intact.
Native selected-prefix retry: INCONCLUSIVE.
nginx 1.31.7 · pinned BoringSSL · TLS 1.3 / HTTP/2 stage-only patch · no release decision
Research checkpoint · 21 October 2026. The original mechanism and native-suffix evidence follow HANDOFF_2026-10-19.md; the new selected-prefix results follow PHASE3E_2026-10-21.md and its retry-invariant audit. Raw traces, builds and reproducibility records remain separate local evidence. No production release or performance claim is implied.

One well-placed short record. Then normal bulk output.

Experiment 6 began as Priority-Aware Dynamic TLS Record Sizing: use HTTP/2 urgency to retain early delivery without the continuous TLS-record overhead of static 4 KiB fragmentation. The tested candidate, G0A, is more specific: a priority-aware bounded early flush in nginx's HTTP/2 send path. It does not change BoringSSL's fragment limit.

Configured stock matrix
300/300
Five cases, two workloads, thirty randomized repeats per cell
Selected short record
4,381 B
Simultaneous; 4,241 B in late. One traced sample each
Controlled prefix retry
4/4
Real BoringSSL WANT_WRITE from a test BIO; recovery PASS
Phase 3E integrity
20/20
Responses verified across four injected and four native transfers
one shared h2 connectionRFC 9218 effective urgency 0bounded 4096-byte DATAnginx output queueno BoringSSL policy changeisolated Debian Testing / Clang
The research result: G0A creates an early, client-decrypted TLS record at a selected urgent-frame boundary, then resumes 16 KiB bulk writes. Phase 3E demonstrated correct selected-prefix retry under four controlled BoringSSL WANT_WRITE conditions, with the original G0A patch unchanged. Native prefix retry, fresh-record coverage and an uninstrumented performance campaign remain separate gates. No production adoption follows.

Where priority meets buffering

Experiment 5 showed that nginx's RFC 9218 scheduling can favor urgent HTTP/2 frames, but cannot reorder bytes already passed downstream. Experiment 6 asked whether the output boundary itself could respond to that known urgency before later bulk data were copied into nginx's SSL output buffer.

Phase 2 tracing found that stock nginx could copy a complete, urgent roughly 4 KiB DATA frame into its SSL buffer and then copy roughly 12 KiB more before emitting the next 16 KiB TLS write. An HTTP/2 flush marker did not itself terminate the inner SSL copy loop. This offered an exact place to test, not a reason to alter the RFC 9218 scheduler.

Record sizing is a connection-level TLS concern, not an HTTP/2 per-stream setting. G0A uses information available in the HTTP/2 frame queue while it still exists. It does not dynamically call SSL_set_max_send_fragment(), move bytes past earlier output, or alter the upstream scheduling policy.

Before changing code: five stock and control cases

The Phase 1 campaign ran five configurations across simultaneous and late-critical-request workloads, thirty randomized repetitions per cell: 300 reported successful trials. The primary metric is when the client receives the first complete critical HTTP/2 DATA frame, not merely the first decrypted TLS bytes. The controlled profile used 20 ms RTT, 20 Mbit/s, and 0% configured loss.

CaseMechanismSimultaneous (median)Late request (median)TLS records (sim. / late)
BStock 16 KiB SSL buffer; default H2 chunks73.045 ms58.713 ms142 / 80
HStock 16 KiB buffer; 4 KiB H2 chunks73.100 ms58.654 ms143 / 80
DExperimental static 4 KiB BoringSSL fragments69.984 ms48.810 ms529 / 272
SStock 4 KiB SSL buffer; default H2 chunks66.905 ms48.826 ms529 / 273
SHStock 4 KiB SSL buffer and 4 KiB H2 chunks65.194 ms46.927 ms529 / 273

SH had the lowest observed median critical-DATA times among these tested configurations, but paid approximately 3.4–3.7 times B's TLS application-record count. Against D, SH was earlier in all 30 simultaneous paired comparisons; its late-request paired median also favored SH, but not in every pair. Total fixture completion increased versus B. These results motivate selective output — not a claim that SH is generally optimal.

Evidence boundary: Reported aggregate JSON passed consistency review. The consolidated ZIP does not include the raw per-run samples, packet traces or binaries, so this website update does not independently reproduce the 300 trials or assert CPU savings.

G0A: one eligible frame, one bounded cut

The experimental patch is confined to ngx_http_v2_send_output_queue() in nginx 1.31.7 and guarded at compile time by NXTLS_EXP_G0A. It selects the first eligible unblocked, complete, small (up to 4096-byte payload) urgency-0 DATA frame, temporarily divides the output chain at that frame, submits the prefix, and then handles the untouched suffix through the normal ordered path. The resulting output is still subject to nginx SSL state and write readiness.

Two separate instrumented Gate-0 observations produced the intended short successful SSL_write() and matching client-side decrypted record. Subsequent bulk submissions returned to normal 16 KiB writes:

WorkloadSelected TLS write / recordB: complete critical DATAG: complete critical DATAB → G TLS records
Simultaneous4,381 B73.069 ms68.195 ms142 → 144
Late request4,241 B58.548 ms53.812 ms80 → 81

These timings are from one trace-enabled diagnostic sample per cell. They demonstrate that a selected output boundary and earlier complete-frame decryption can coincide in the tested cases; they are not a statistically supported G0A speedup. Background DATA preceding the critical frame did not change in these two comparisons. The client did not receive an already committed later frame out of order.

Native socket backpressure: prefix first, suffix blocked

Earlier tests established forced partial-chain recovery and real TLS/socket backpressure on the selected G0A connection. At the native boundary the short prefix succeeded, and the following suffix returned SSL_ERROR_WANT_WRITE. This was useful evidence but did not exercise a blocked prefix. Phase 3E separately forced that condition under a controlled test transport.

GateRecorded resultInterpretation
G0A Gate-0 and controls20/20 initial; 42/42 control trials; further 10/10 delayed repeatsFrame selection and inactive/control paths ran without client-reported integrity failures; diagnostic samples, not a performance campaign.
Synthetic prefix/suffix partial chains8/8 transfersOne-shot 512-byte send_chain() limits and explicit posted continuation recovered correctly; no native SSL_ERROR_WANT_WRITE was injected.
Earlier native prefix-targeted campaign4/4 B/G transfers complete; 0/2 prefix blocksBoth prefix calls succeeded normally. Native selected-prefix retry was not exercised; strict checker result: INCONCLUSIVE, not FAIL.
Observed native suffix behaviorReal SSL_ERROR_WANT_WRITE in 2/2 selected G suffixesNative backpressure was observed with successful client completion. This supports suffix progress, but is not a dedicated suffix-targeted gate or blocked-prefix proof.
Native attempt: two different outcomes within the same selected G0A boundary
selected prefix
Normal completion; no forced blockage.

Both native calls completed without WANT_WRITE; selected-prefix native-socket recovery remains unobserved.

0/2 blocked → gate open
immediately following suffix
Native WANT_WRITE observed.

Both G suffix calls logged SSL_get_error: 3, and the clients received complete correct responses.

2/2 events → intact completion

Interpretation: native socket pressure occurred at the adjacent suffix boundary, not during the prefix. The transfers were correct, but the strict native-prefix checker remains INCONCLUSIVE. Socket pressure alone does not guarantee where a synchronous write blocks. The controlled prefix-retry evidence below answers a different, narrower question.

Phase 3E: the selected prefix blocked — and recovered

The test-only write-BIO gate induced actual BoringSSL SSL_ERROR_WANT_WRITE while nginx was submitting G0A's selected prefix. Nothing forged an SSL_write() result, and the original G0A patch remained byte-identical. Each controlled case restored the split chain, retained the required TLS retry input, resumed through nginx's write handler and delivered complete, ordered HTTP/2 responses.

Phase 3E conditionObserved outcomeMeaning
Before · simultaneous / late2/2 PASS; zero additional ciphertext bytes accepted after armingSelected-prefix write blocked, then resumed correctly. A 16,384-byte TLS input was already pending before arming.
Partial · simultaneous / late2/2 PASS; 1,024 ciphertext bytes newly accepted before blockingActual partial ciphertext progress followed by a real BoringSSL retry and intact completion.
Native socket · B/G simultaneous / late4/4 transfers intact; 0/2 selected G prefixes blockedOrdinary and suffix retries recovered; the native selected-prefix gate remains INCONCLUSIVE.

The four controlled transfers preserved the input pointer, length, full SHA-256 and committed bytes required by the active BoringSSL retry mode. Chain links and frame ownership recovered without duplication or reordering. Together with four native B/G controls, Phase 3E verified 20/20 responses; the E6 and shared H2 suites passed 55/55 tests.

What this does not claim: The injected prefix already had a pending 16 KiB TLS write when armed; the zero-forward case means zero additional bytes, not zero lifetime ciphertext acceptance for a new record. The timer and writable-event rearm are disclosed synthetic transport behavior, not proof of a native socket prefix retry. A fresh-record, zero-acceptance test and a true native-prefix hit remain separate gates.

What the prototype has shown — and what remains

  • Demonstrated in the staged workloads: short, client-confirmed urgent-frame TLS emission and normal bulk output; intact partial-chain recovery; real native suffix backpressure; and four controlled selected-prefix BoringSSL retries with preserved chain ownership, TLS input and response integrity.
  • Still to validate for integration: native selected-prefix retry and ordinary event-driven resumption; a fresh-record zero-acceptance retry; repeated blocks, cancellation/teardown with a pending retry, broader interleavings, sustained fairness and sanitizer checks. Phase 3E's synthetic readiness rearm does not close the native gate.
  • Performance research still to perform: randomized, uninstrumented G0A versus B/S/SH under controlled conditions, including throughput/CPU and total completion as well as critical-frame timing. The diagnostic timing deltas are not general performance claims.
  • Implementation scope: one disposable, compile-time-guarded nginx patch. Canonical upstream source inputs are untouched. No production nginx/BoringSSL patch, deployment or architecture adoption.
  • Policy: nxTLS decision D-015 remains accepted and unchanged. The rejected historical adaptive 1024/8192/16384 TLS policy is not revived.

Don't make every TLS record smaller. Make the right record available sooner.

Research checkpoint: mechanism plus bounded retry evidence. The stage-only G0A prototype demonstrates selective early TLS emission and now passes four deliberately blocked selected-prefix retries in an isolated test transport. The original G0A patch did not change. Native blocked-prefix recovery and statistically grounded performance comparisons remain open. D-015 and production nginx are unchanged.

Reproduction & evidence boundaries

Primary local sources: experiments/priority-aware-dynamic-tls-record-sizing/README.md, HANDOFF_2026-10-19.md, PHASE3E_2026-10-21.md and PHASE3E_RETRY_INVARIANTS_2026-10-21.md. Historical phase reports record the stock comparison, selected boundary, partial chains and native suffix tests; Phase 3E provides exact commands, binary hashes, diagnostic states and test limitations.

The original stage-only patches/nginx-1.31.7-g0a-early-flush.patch was unchanged. Phase 3E adds instrumentation and BIO fault injection only to disposable, isolated builds; the native diagnostic build excludes the injector. The experimental H2 harness, checkers and local evidence directories are not production components. This page does not link to private source repositories.

Fixed inputs: nginx 1.31.7, BoringSSL 594a44291086dcc7cef06cabec4c0b47afd674c0, Debian Testing amd64 / Clang 21.1.8, HTTP/2 over TLS 1.3/TCP. Raw captures, trial JSON, binaries and logs are held in the experiment's local results directories and are not reproduced here.

RFC 9218 — HTTP prioritization ↗

← EXP 06 summary