Summary
WordPress core's HTTP API (wp_remote_get() / wp_remote_post()) cannot stream responses. Every layer — from the Requests library transports through Requests::parse_response() to WP_HTTP_Requests_Response::to_array() — buffers the full response body as a string before returning.
This is a blocker for AI/LLM integration in WordPress, where Server-Sent Events (SSE) streaming from APIs like OpenAI, Anthropic, etc. is the standard pattern.
Full Analysis
See streaming-analysis.md for the complete call chain trace and layer-by-layer breakdown.
Key Findings
8 Buffering Bottlenecks Identified
| # |
Location |
Issue |
Severity |
| 1 |
Curl::stream_body() |
\$this->response_data .= \$data accumulates all chunks |
Low |
| 2 |
Fsockopen::request() |
\$body .= \$block accumulates all chunks |
Low |
| 3 |
Curl::process_response() |
Concatenates headers+body |
Medium |
| 4 |
Requests::parse_response() |
Expects complete body string |
High |
| 5 |
Requests::parse_response() |
decode_chunked() on complete body |
Medium |
| 6 |
Requests::parse_response() |
decompress() on complete body |
High (fsockopen) / Low (cURL) |
| 7 |
WP_HTTP_Requests_Response::to_array() |
'body' => string |
High |
| 8 |
WP_Http::request() return value |
Flat array with string body |
High |
The request.progress Hook Already Exists
Both cURL and fsockopen transports fire a request.progress hook per-chunk during data reception. cURL handles decompression in-flight, so chunks arrive decompressed. This is the closest thing to streaming that exists today — but the body is still accumulated regardless.
Most AI Plugins Bypass wp_remote_* Entirely
Because the API fundamentally cannot stream, plugins use raw curl_init() / curl_exec() with CURLOPT_WRITEFUNCTION. This works but loses WordPress proxy, SSL cert, cookie, and hook handling.
Proposed Approaches
| Approach |
Core Changes? |
Effort |
Usability |
request.progress hook workaround |
No |
Low |
Poor (still accumulates) |
| Bypass WP HTTP, raw cURL |
No |
Low |
Good (but loses WP features) |
Transport-level stream_callback option |
Requests lib only |
Medium |
Good |
| Full streaming API |
WP Core + Requests |
Medium-High |
Excellent |
Roadmap Context
This analysis supports enabling HTTP streaming in WordPress core for AI tool integration. The Requests library documentation in this repo provides the foundation for understanding the transport layer.
Summary
WordPress core's HTTP API (
wp_remote_get()/wp_remote_post()) cannot stream responses. Every layer — from the Requests library transports throughRequests::parse_response()toWP_HTTP_Requests_Response::to_array()— buffers the full response body as a string before returning.This is a blocker for AI/LLM integration in WordPress, where Server-Sent Events (SSE) streaming from APIs like OpenAI, Anthropic, etc. is the standard pattern.
Full Analysis
See
streaming-analysis.mdfor the complete call chain trace and layer-by-layer breakdown.Key Findings
8 Buffering Bottlenecks Identified
Curl::stream_body()\$this->response_data .= \$dataaccumulates all chunksFsockopen::request()\$body .= \$blockaccumulates all chunksCurl::process_response()Requests::parse_response()Requests::parse_response()decode_chunked()on complete bodyRequests::parse_response()decompress()on complete bodyWP_HTTP_Requests_Response::to_array()'body' => stringWP_Http::request()return valueThe request.progress Hook Already Exists
Both cURL and fsockopen transports fire a
request.progresshook per-chunk during data reception. cURL handles decompression in-flight, so chunks arrive decompressed. This is the closest thing to streaming that exists today — but the body is still accumulated regardless.Most AI Plugins Bypass wp_remote_* Entirely
Because the API fundamentally cannot stream, plugins use raw
curl_init()/curl_exec()withCURLOPT_WRITEFUNCTION. This works but loses WordPress proxy, SSL cert, cookie, and hook handling.Proposed Approaches
request.progresshook workaroundstream_callbackoptionRoadmap Context
This analysis supports enabling HTTP streaming in WordPress core for AI tool integration. The Requests library documentation in this repo provides the foundation for understanding the transport layer.