I'm configuring the nginx access_log to output in JSON format to use with other tools.

The data I want includes info about the compression. I have gzip on, but the only thing I'm getting for the gzip_ratio is -.

To confirm, the embedded var is $gzip_ratio.


Here's the definition of my log_format:

log_format  main_json '{"time": "$time_iso8601", '
                  '"remote_addr": "$remote_addr", '
                  '"body_bytes_sent": "$body_bytes_sent", '
                  '"gzip_ratio": "$gzip_ratio", '
                  '"status": "$status", '
                  '"request": "$request_time", '
                  '"request_method": "$request_method", '
                  '"http_referrer": "$http_referer", '
                  '"http_user_agent": "$http_user_agent", '
                  '"http_x_forwarded_for": "$http_x_forwarded_for", '
                  '"request_time": "$request_time", '
                  '"upstream_response_time": "$upstream_response_time"}';

Here are the gzip settings in nginx.conf:

gzip  on;
gzip_proxied any;
gzip_types text/plain text/xml text/css application/x-javascript text/javascript application/xml+rss text/json application/json;

And here is the output in the access_log:

    "http_user_agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2293.0 Safari/537.36",

So, it appears that things are not being compressed. However, I've run cURL to test for compression, and here are the results:

[~]$ curl https://[URL] --silent --write-out "size_download=%{size_download}\n" --output /dev/null
[~]$  curl https://[URL] --silent -H "Accept-Encoding: gzip,deflate" --write-out "size_download=%{size_download}\n" --output /dev/null

So, from actually measuring the size of the response, it seems it is being compressed. However, the logs are still missing the gzip_ratio. The body_bytes_sent in each request's log matches up to the bytes reported by cURL (slight variation w/ compressed response).

{"time": "2015-02-03T14:57:11+00:00", "remote_addr": "[IP]", "body_bytes_sent": "3297", "gzip_ratio": "-", "status": "200", "request": "0.477", "request_method": "GET", "http_referrer": "-", "http_user_agent": "curl/7.37.0", "http_x_forwarded_for": "-", "request_time": "0.477", "upstream_response_time": "0.477"}
{"time": "2015-02-03T14:57:20+00:00", "remote_addr": "[IP]", "body_bytes_sent": "871", "gzip_ratio": "-", "status": "200", "request": "0.676", "request_method": "GET", "http_referrer": "-", "http_user_agent": "curl/7.37.0", "http_x_forwarded_for": "-", "request_time": "0.676", "upstream_response_time": "0.676"}

Anyone know how I can get the actual gzip_ratio?


Either you are using a buggy version of nginx or your test method had some flaws. I have just confirmed that $gzip_ratio in a log_format definition works perfectly fine in nginx 1.9.1.

I have seen $gzip_ratio to only equal - when no compression was performed. In all other cases it held a numeric value.

  • That's the same link I referenced in my question, our settings are nearly identical, less text/json, and I put faith in curl. All of that was included in the question. – gotmikhail Jun 8 '15 at 12:20
  • Sorry, I actually let some days pass between reading your question and writing my answer. I will removed these parts that you have already referred to. I also know that my answer ("you must have done something wrong") might not be the most helpful one, but I figured this is better than leaving this un-answered forever. I think the crucial insight here is that this is not an nginx bug which would need to be reported. – Jan-Philip Gehrcke Jun 8 '15 at 12:23
  • I noticed the detail I left out was the second log, which had a larger value in body_bytes_sent. So, looks like it was compressing, but there at least was a bug with the $gzip_ratio field. I actually haven't checked this in quite a while, I found another solution, but will review the nginx version and report back. – gotmikhail Jun 8 '15 at 12:30

Encountered the same recently.

$gzip_ratio is only available if nginx does the compression itself. It will NOT be available if it actually is the upstream server that does the compression in a reverse-proxy/load-balancer scenario; that would match all your symptoms (response is actually compressed when tested with cURL).

A way to log that scenario is to include $sent_http_content_encoding and/or $upstream_http_content_encoding in your logs; it will contain "gzip".

Also worth checking for gzip_min_length and gzip_types config options to make sure responses actually qualify for gzipping.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.