It is quite common in AWS to locate nginx Web servers running on EC2 instances behind ELB. There’re some tips to enhance nginx performance.


Worker Process

Number of process(es) for worker(s). This value should be equal to the number of cores of CPU. Setting auto will automatically set it that way. You don’t have to change this number even if you change the instance type of ELB.


worker_processes  auto;


Syntax:	worker_processes number | auto;
Default:	worker_processes 1;
Context:	main

See ngx_core_module: worker_processes

Connection settigns


This is a parameter that defines timeout for keep-alive connections. Nginx will close connections after this time.

For ngixn behind ELB, this value must be higher than ELB’s Idle timeout. Otherwise it end up with increasing in ELB 408 errors.


Syntax:	keepalive_timeout timeout [header_timeout];
Default:	keepalive_timeout 75s;
Context:	http, server, location

See ngx_http_core_module: keepalive_timeout


keepalive_timeout  75;

Assuming that ELB’s Idle timeout is default 60 seconds.

Get Client IP address instead of ELB’s

By default just putting nginx under ELB will make a client IP address, which is used (like for logging), ELB’s one not real client one. Adding those lines below, you can get a real client IP address. This is based on ELB’s X-Forwarded-For header.

Assume that your VPC CIDR Block is


set_real_ip_from; # VPC CIDR
real_ip_header     X-Forwarded-For


Syntax:	**set_real_ip_from** address | CIDR | unix:;
Default:	—
Context:	http, server, location

See ngx_http_realip_module

Terminate SSL/TLS at ELB

You can terminate https at ELB, and process the request to Web servers with http, for performance ehnahcement, easier maintenance of SSL/TLS Certificates files.

SSL Termination at ELB
- https -> [ ELB :443 ] - http -> [nginx :80]
SSL Termination at Nginx
- https -> [ ELB :443 ] - https -> [nginx :443]

Redirect http to https

Sometimes you need to redirect all the http requests to https, or visa versa. By terminating SSL at ELB, Web server only need to listen http 80 port. Still you can detect protocol based on ELB’s header $http_x_forwarded_proto.

Config (Example)

server {
  listen 80;

  if ($http_x_forwarded_proto != "https") {
    return 301 https://$host$request_uri;


Tell backend server for reverse proxy the protocol

One more thing, you can tell backend application the protocol.


proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;


Syntax:	proxy_set_header field value;
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context:	http, server, location

See ngx_http_proxy_module: proxy_set_header


Change DNS Server

Sometimes need to change name server for looking up DNS, it rarely happens though.




Syntax:	resolver address ... [valid=time] [ipv6=on|off];
Default:	—
Context:	http, server, location

See ngx_http_core_module: resolver


Most of the configuration for nginx benihd ELB is not diffrent from the one facing the Internet directly. Configuring a little bit for ELB will ehnance performance and availability of nginx.