Next.js App Router streaming works when self-hosted, but Nginx buffers proxied responses by default. The reliable fix is to disable buffering for streaming responses and verify that every hop preserves incremental delivery.
Configure the response path
Next.js documents setting X-Accel-Buffering: no through response headers. Nginx also supports proxy_buffering off at the proxied location. Keep an appropriate proxy read timeout and use a proxy protocol version compatible with the rest of the stack. Do not disable request buffering unless upload behavior requires it; it is a different setting.
Find hidden buffering
A CDN, ingress, load balancer, compression layer, or second reverse proxy can still collect the response. Compare a direct request to the private Next.js port with requests through each successive layer. This isolates the first hop that changes chunk timing.
Test observable behavior
Use a route with a fast shell and deliberately delayed content. Inspect time to first byte and chunk arrival with a client that does not hide buffering. A correct page after the full delay does not prove streaming works; the shell must arrive before the delayed section.