Questions about proxy buffers

Hello,

I have read the documentation of the HTTP Proxy Module regarding
buffers and would like to understand which is the exact (basic)
workflow regarding buffers only. Let me ask about some scenarios,
assuming everything fits in memory and ignoring caching workflows etc.

Let’s suppose proxy_buffer_size is 4k and proxy_buffers is 8 4k.

Say the proxied server sends a response of 2k. Then I guess the entire
response is buffered, as quickly as possible, and when the proxied
server is done, then nginx starts sending the buffer to the client. Is
that right?

The description of proxy_buffer_size says “This directive set the
buffer size, into which will be read the first part of the response,
obtained from the proxied server.” What is the first part of the
response? Does it mean the chunk that fits in the first buffer? In
this case exactly 4k? If that’s correct, what does the module do with
the “subsequent” parts? does proxy_buffer_size have anything to do
with them? Or are those for the remaining 7 buffers, 4k each?

Let’s say now the proxied server sends a response consisting of 16k.
Does the module fill 4 buffers, as quickly as possible, and when
everything is done it sends the 16k to the client? Or does it start
sending the first buffer while filling the second one?

Here “nginx does not attempt to read the entire answer from the
proxied server, the maximum size of data which nginx can accept from
the server is set by directive proxy_buffer_size.” should
proxy_buffer_size be proxy_buffers, or rather a combination of the
two?

What happens if the proxied server sends a response greater than the
total buffer sizes, say 50k? Does nginx frees buffers sending data,
and then buffers another chunk from the proxied server, iterate until
done?

What’s proxy_busy_buffers_size?

Thanks!!!

On 6/11/11, Xavier N. [email protected] wrote:

What happens if the proxied server sends a response greater than the
total buffer sizes, say 50k?

It depends whether or not you have proxy_buffering enabled.
With proxy_buffering nginx tries to receive an entire response as
quickly as possible. Even uses temporary file if response can’t fit
into proxy_buffers.

Does nginx frees buffers sending data,
and then buffers another chunk from the proxied server, iterate until
done?

And that’s how nginx does it with disabled proxy_buffering.

On Sat, Jun 11, 2011 at 4:08 AM, Maxim D. [email protected]
wrote:

Hi Maxim, that was an awesome reply, thank you very much.

Let’s say now the proxied server sends a response consisting of 16k.
Does the module fill 4 buffers, as quickly as possible, and when
everything is done it sends the 16k to the client? Or does it start
sending the first buffer while filling the second one?

It will start sending as long as it has nothing to read for a
while (i.e. read() from upstream will return EAGAIN).

That’s a rule of thumb even if we are filling the first data buffer?
(to distinguish from the first buffer whose primary content are
headers).

I have in mind chunked responses from the proxied server in that
question. Imagine we are producing a HTML response whose head is kinda
static content, but whose dynamic body is costly. If the app sends a
chunk with the head of the document, and after that some amount of
time passes after the bytes from the second chunk come (because they
are costly to produce), would in general nginx send that head to the
client?

Hello!

On Sat, Jun 11, 2011 at 01:50:59AM +0200, Xavier N. wrote:

I have read the documentation of the HTTP Proxy Module regarding
buffers and would like to understand which is the exact (basic)
workflow regarding buffers only. Let me ask about some scenarios,
assuming everything fits in memory and ignoring caching workflows etc.

Just a side note: you may want to read this relatively recent
thread:

http://nginx.org/pipermail/nginx/2011-April/026435.html

Let’s suppose proxy_buffer_size is 4k and proxy_buffers is 8 4k.

Say the proxied server sends a response of 2k. Then I guess the entire
response is buffered, as quickly as possible, and when the proxied
server is done, then nginx starts sending the buffer to the client. Is
that right?

Basically, yes. “Bascially” here assumes proxy_buffering on (the
default), and “response” being interpreted as “response body”, as
header is processed separately and may be sent without buffering
(this will be usually prevented by other options like
postpone_output though).

The description of proxy_buffer_size says “This directive set the
buffer size, into which will be read the first part of the response,
obtained from the proxied server.” What is the first part of the
response?

This is a buffer where response header will be read and parsed.
It may also happen to contain some parts of response body as long
as they were read from kernel along with header.

This buffer is also used in unbuffered mode, but this is
completely different story.

Does it mean the chunk that fits in the first buffer? In
this case exactly 4k?

No.

If that’s correct, what does the module do with
the “subsequent” parts? does proxy_buffer_size have anything to do
with them? Or are those for the remaining 7 buffers, 4k each?

Subsequent parts of the response are read to proxy_buffers.

Let’s say now the proxied server sends a response consisting of 16k.
Does the module fill 4 buffers, as quickly as possible, and when
everything is done it sends the 16k to the client? Or does it start
sending the first buffer while filling the second one?

It will start sending as long as it has nothing to read for a
while (i.e. read() from upstream will return EAGAIN).

Here “nginx does not attempt to read the entire answer from the
proxied server, the maximum size of data which nginx can accept from
the server is set by directive proxy_buffer_size.” should
proxy_buffer_size be proxy_buffers, or rather a combination of the
two?

There were a stray newline before the sentence in question, I just
removed it from wiki. It’s about work with buffering switched
off.

What happens if the proxied server sends a response greater than the
total buffer sizes, say 50k? Does nginx frees buffers sending data,
and then buffers another chunk from the proxied server, iterate until
done?

Yes. With some nuances though: as long as sending is not possible
(client is slow) nginx will spool data to disk in an attempt to
free backend as soon as possible. Disk buffering may be limited
(or even completely disabled) with proxy_max_temp_file_size
directive.

What’s proxy_busy_buffers_size?

This directive specifies how many data may be in “busy” buffers,
i.e. already passed to output filter chain but still not sent.
It limits amount of busy buffers and leaves some buffers available
for reading upstream response and buffering it to disk.

Maxim D.

Hello!

On Sun, Jun 12, 2011 at 08:28:24PM +0200, Xavier N. wrote:

while (i.e. read() from upstream will return EAGAIN).

That’s a rule of thumb even if we are filling the first data buffer?
(to distinguish from the first buffer whose primary content are
headers).

Buffers which aren’t fully filled aren’t sent with proxy_buffering
on.

I have in mind chunked responses from the proxied server in that
question. Imagine we are producing a HTML response whose head is kinda
static content, but whose dynamic body is costly. If the app sends a
chunk with the head of the document, and after that some amount of
time passes after the bytes from the second chunk come (because they
are costly to produce), would in general nginx send that head to the
client?

No.

Maxim D.