RFC 1738 vs RFC 3986 query encoding in http_build_query
A narrow timing and output comparison of PHP’s two standard query-encoding modes.
The correctness boundary
Is there a meaningful local cost to selecting RFC 3986 encoding for a nested query structure?
The default mode encodes spaces with plus signs, while RFC 3986 uses percent encoding. Signature schemes and external APIs may require one exact representation.
A tiny timing difference cannot compensate for a mismatched protocol contract.
Performance should be close; compatibility requirements and space encoding semantics should drive the choice.
Measured evidence
What this run shows: RFC 3986 encoding was faster under the selected encoding mode, but a receiving protocol may already require the other representation. The slowest-to-fastest median spread was 2.78% on the measured host.
| Variant | Median | Middle 50% | Operations/s | Additional measure |
|---|---|---|---|---|
| RFC 3986 encodingFastest | 1.05 µs | 1.04 µs–1.11 µs | 956,223 | 240 output bytes |
| RFC 1738 default | 1.07 µs | 1.05 µs–1.09 µs | 930,374 | 238 output bytes |
What could go wrong with a timing-only choice?
This is a compatibility decision with a performance measurement attached, not a speed contest. The correct mode is the one expected by the receiving endpoint and any canonical-signature process.
When query strings are signed, test the exact byte representation and parameter ordering used in production.
Implementation checks
- Use RFC 3986 when an API or signature specification requires percent-encoded spaces.
- Do not hand-build nested query strings when the standard function expresses the required contract.
- Add fixture tests for exact output when interoperability is critical.
How this boundary was tested
- Both variants encode the same nested filter, pagination, search and include structure.
- Only the encoding mode changes; separators and source data remain fixed.
- The resulting byte length is published with the timing samples.
Open measured environment
- Measurement run
- 2026-07-22T15:23:56+00:00
- PHP
- 8.4.23 (cli)
- Operating system
- Linux 4.18.0-553.85.1.el8_10.x86_64
- Architecture
- x86_64
- Processor
- AMD EPYC-Rome Processor
- Reported host memory
- 15.02 GiB host total
- CLI OPcache
- 0
- PHP memory limit
- 1024M
- Loaded study extensions
- json, openssl, zlib, mbstring, pdo_sqlite
- Timing clock
- hrtime(true)
- Measured rounds
- 7
Scope and unresolved questions
- Only one nested query shape is tested.
- URL length limits and receiving-server behavior are outside scope.
Primary documentation
Use these documents to verify the required API, encoding or filesystem behavior. ASAMB supplies the local measurements, not the normative rule.
Inspect or rerun the evidence
The common runner and study-specific fixture are public so the result can be challenged on another PHP host.