{"id":1,"date":"2023-01-22T14:10:47","date_gmt":"2023-01-22T14:10:47","guid":{"rendered":"http:\/\/ramansaini.in\/blog\/?p=1"},"modified":"2023-10-17T14:13:12","modified_gmt":"2023-10-17T14:13:12","slug":"how-to-set-up-nginx-for-optimized-traffic-load","status":"publish","type":"post","link":"https:\/\/ramansaini.in\/blog\/how-to-set-up-nginx-for-optimized-traffic-load\/","title":{"rendered":"How to set up Nginx for optimized traffic load?"},"content":{"rendered":"\n<p>Nginx is a web server much better than Apache for handling the user load and request management. We just need to create a shortcut for the configuration file in <code>\/etc\/nginx\/sites-enabled\/<\/code> . So first we need to understand the structure of Nginx.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Structure of Nginx<\/h3>\n\n\n\n<p>The structure of Nginx contains many things like server block, Including configurations, setting up server names, document root, and reverse proxies.<\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/ramansaini.in\/blog\/understanding-the-structure-of-nginx\/(opens in a new tab)\" target=\"_blank\">Read more about the Nginx structure in detail.<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Performance Optimizations<\/h3>\n\n\n\n<p>For Nginx performance optimizations, we need to look at these parameter configurations:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Workers<\/li>\n\n\n\n<li>Network activity<\/li>\n\n\n\n<li>Buffers<\/li>\n\n\n\n<li>Timeout<\/li>\n\n\n\n<li>Disk I\/O activity<\/li>\n\n\n\n<li>Compression<\/li>\n\n\n\n<li>Caching<\/li>\n<\/ul>\n\n\n\n<p>We&#8217;ll go through each of them one by one understanding the need of changing their value and what should be the value according to the requirement.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Workers<\/h3>\n\n\n\n<p>Worker processes are managed through the event block in <code>nginx.conf<\/code> file. For Editing the nginx.conf file you&#8217;ll need to run <code>nano \/etc\/nginx\/nginx.conf<\/code> in the terminal and then add this code in the event block:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>events { \n    worker_processes    auto;\n    worker_connections  1024;\n    worker_rlimit_nofile 20960;\n    multi_accept        on;  \n    mutex_accept        on; \n    mutex_accept_delay  500ms; \n    use                 epoll; \n    epoll_events        512;  \n}<\/code><\/pre>\n\n\n\n<p>Here <code>worker_processes<\/code> defines the number of workers that can run on the server. Putting the value as auto lets Nginx determine the number of workers by itself by calculating the disk, server load, and network system.<\/p>\n\n\n\n<p><code>worker_connections<\/code> defines the number of simultaneous connections which can be handled by one worker node in Nginx. The default value for worker_connections is 512 and this can be set to a maximum of 1024.<\/p>\n\n\n\n<p><code>worker_rlimit_nofile<\/code> is related to <code>worker_connections<\/code>. This is set to a large number in order to handle a large number of simultaneous connections.<\/p>\n\n\n\n<p><code>multi_accept<\/code> allows a single worker to accept many connections in a queue, which is a sequence of data waiting for process.<\/p>\n\n\n\n<p><code>mutex_accept<\/code> allows workers to accept connections one by one. This is turned off by default, but we need to turn it on because we have turned on the configuration for many connections.<\/p>\n\n\n\n<p><code>mutex_accept_delay<\/code> tells worker how long should it wait before accepting a new connection.<\/p>\n\n\n\n<p><code>use<\/code> determines the method of processing the incoming connection. We have set this as <code>epoll<\/code> because we&#8217;re working in ubuntu.<\/p>\n\n\n\n<p><code>epoll_events<\/code> determines the number events nginx needs to transfer to kernel.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Network activity<\/h3>\n\n\n\n<p>In this section, we will talk about <code>tcp_nodelay<\/code> and <code>tcp_nopush<\/code>. These two directives are used to help prevent small packets from waiting, for a specified period, which is about 200ms. <\/p>\n\n\n\n<p>Code needed in HTTP section:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http {   \n\n  tcp_nopush  on; \n  tcp_nodelay on;\n\n  }<\/code><\/pre>\n\n\n\n<p><code>tcp_nodelay<\/code> is off by default, but this is enabled to allow all the packets to be sent at once.<\/p>\n\n\n\n<p><code>tcp_nopush<\/code> is enabled to make sure the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Nagle%27s_algorithm\" target=\"_blank\" rel=\"noopener\">John Nagle\u2019s buffering algorithm<\/a> is in use. Enabling this makes sure to add packages to each other and send them all together.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Buffers<\/h3>\n\n\n\n<p>A buffer is a temporary space, where the data is kept for some time before processing it. For enabling and configuring buffer, directives are added into server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server { \n\n   client_body_buffer_size 16k;\n   client_max_body_size 2m; \n   client_body_in_single_buffer on;  \n   client_body_temp_pathtemp_files 1 2;\n   client_header_buffer_size  1m; \n   large_client_header_buffers 4 8k;\n\n }<\/code><\/pre>\n\n\n\n<p><code>client_body_buffer_size<\/code> is used to set the buffer size of the request body. Value for this directive should be 8k if you&#8217;re using 32 bit system, and 16k if you&#8217;re using 64 bit system.<\/p>\n\n\n\n<p><code>client_max_body_size<\/code> is used to set the upload file size limit. By default it is 1m, you&#8217;ll need to set this up accordingly.<\/p>\n\n\n\n<p><code>client_body_in_single_buffer<\/code> is used to make sure complete request body is stored in the buffer, as sometimes all the request body is not stored in buffer, but some of it is stored in a file system.<\/p>\n\n\n\n<p><code>client_header_buffer_size<\/code> is used to allocate a buffer for request header.<\/p>\n\n\n\n<p><code>large_client_header_buffers<\/code> is used to setup the maximum and size of the buffer for reading the large headers in the request.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Timeout<\/h3>\n\n\n\n<p>Timeout directives can be really useful in stopping the long running processes from wasting the resource time. For timeout we can add in HTTP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http {  \n\n keepalive_timeout  30s; \n keepalive_requests 30;\n send_timeout      30s;\n\n}<\/code><\/pre>\n\n\n\n<p><code>keepalive_timeout<\/code> sets the timeout to keep the connection alive. default value for this is 75s.<\/p>\n\n\n\n<p><code>keepalive_requests<\/code> specifies the number of requests which are needed to be kept alive for a specific period of time.<\/p>\n\n\n\n<p><code>send_timeout<\/code> is set to specify the timeout for data transmission to the client.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Disk I\/O activity<\/h3>\n\n\n\n<p>Using disk I\/O directives we&#8217;ll configure the asynchronous activity to improve data transfer and effective caching. When talking about Disk I\/O, we&#8217;re mainly talking about read &amp; write operations between hard disk and RAM. We can add the following code in the configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>location \/pdf\/  {\n   sendfile on; \n   aio      on; \n  }  \n\nlocation \/audio\/ {  \n    directio    4m\n    directio_alignment 512  \n}<\/code><\/pre>\n\n\n\n<p><code>sendfile<\/code> is used to serve small files. It&#8217;s value should be on, in case we want to use operating system resources.<\/p>\n\n\n\n<p><code>aio<\/code> is used to handle asynchronous operations. When turned on, it enables multi-threading for both read and write operations.<\/p>\n\n\n\n<p><code>directio<\/code> allows sending read and write to be sent directly to the application, which improves the effectiveness of caching.<\/p>\n\n\n\n<p><code>directio_alignment<\/code> is related to directio. It sets the block size value for data transfer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Compression<\/h3>\n\n\n\n<p>Another way of ensuring the performance of web server is by compressing the amount and size of data being transferred over the network. For compression, you can use this code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http {  \n\n  gzip on;\n  gzip_comp_level  2;\n  gzip_min_length  1000; \n  gzip_types  text\/xml text\/css; \n  gzip_http_version 1.1; \n  gzip_vary  on;  \n  gzip_disable \"MSIE &#91;4-6] \\.\"; \n\n}<\/code><\/pre>\n\n\n\n<p><code>gzip<\/code> let&#8217;s nginx know to enable the compression. By default it is turned off.<\/p>\n\n\n\n<p><code>gzip_comp_level<\/code> helps in setting up the compression level. If the value is set too high, in that case, CPU resources will be wasted. Value should be put 2 or 3.<\/p>\n\n\n\n<p><code>gzip_min_length<\/code> is to set the minimum length of the response for compression.<\/p>\n\n\n\n<p><code>gzip_types<\/code> helps to determine the type of responses you want to compress. text\/html is added by default. Others are needed to be added.<\/p>\n\n\n\n<p><code>gzip_http_version<\/code> is the minimum value of the HTTP version needed to be compressed.<\/p>\n\n\n\n<p><code>gzip_vary<\/code> helps in adding the header <code>Vary:Accept Encoding<\/code> in the response.<\/p>\n\n\n\n<p><code>gzip_disable<\/code> some clients or browsers do not support gzip compression, like IE6. This directive helps in disabling the compression by using the <code>User-Agent<\/code> from headers.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Caching<\/h3>\n\n\n\n<p>Caching is going to help reduce loading the same resource multiple times for the same data. To enable caching we can add:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http {  \n\nopen_file_cache max=1,000 inactive=30s; \nopen_file_cache_valid 30s; \nopen_file_cache_min_uses 4; \nopen_file_cache_errors on; \n\n }<\/code><\/pre>\n\n\n\n<p><code>open_file_cache<\/code> is used to enable the caching in nginx. It helps in storing the meta-data of the files and directories.<\/p>\n\n\n\n<p><code>open_file_cache_valid<\/code> is used to set a period of time to revalidate the information about the files and directories.<\/p>\n\n\n\n<p><code>open_file_cache_min_uses<\/code> is used to clear the cache of the files and directories after some specified period of inactivity.<\/p>\n\n\n\n<p><code>open_file_cache_errors<\/code> is used to show the errors to users who does not have permission for some request or accessing files. This directive will cache the errors.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Bonus<\/h3>\n\n\n\n<p>In nginx or any other web server, when setting up a project or serving an app, we should always disable the directory indexing which will help us in securing the file data from attackers and gives error when the files are not executable.<\/p>\n\n\n\n<p>For achieving this you can use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>location \/ {  \n auto_index  off;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Nginx is a web server much better than Apache for handling the user load and request management. We just need to create a shortcut for the configuration file in \/etc\/nginx\/sites-enabled\/ . So first we need to understand the structure of Nginx. Structure of Nginx The structure of Nginx contains many things like server block, Including&hellip;&nbsp;<a href=\"https:\/\/ramansaini.in\/blog\/how-to-set-up-nginx-for-optimized-traffic-load\/\" class=\"\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">How to set up Nginx for optimized traffic load?<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":206,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_themeisle_gutenberg_block_has_review":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[7,5],"tags":[10,9,11],"class_list":["post-1","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-devops","category-technology","tag-devops","tag-nginx","tag-performance"],"jetpack_featured_media_url":"https:\/\/ramansaini.in\/blog\/wp-content\/uploads\/2023\/01\/Nginx-1-1.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/comments?post=1"}],"version-history":[{"count":16,"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":285,"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/posts\/1\/revisions\/285"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/media\/206"}],"wp:attachment":[{"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/media?parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/categories?post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ramansaini.in\/blog\/wp-json\/wp\/v2\/tags?post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}