Навигация
- 5.1 General provisions for infrastructure optimization
- 5.2 Setting up caching of static resources
- 5.3 Data compression (Gzip and Brotli)
- 5.4 Optimizing connection parameters
- 5.5 Microcaching
- 5.6 Infrastructure optimization results
5.1 General provisions for infrastructure optimization
The infrastructure level of optimization is aimed at improving the performance of a web application by configuring the server environment, load balancing, caching and scaling. Even with optimized code and database, using the capabilities of the Yii2 framework, an incorrectly configured infrastructure can become the main bottleneck of the system. This chapter covers key infrastructure optimization techniques applicable to web applications developed using the Yii2 framework.
There is a point of view regarding infrastructure methods for optimizing application performance, which is radically different from the classical one. For example, according to Martin Fowler, using newer equipment is often simply more profitable than forcing the program to “run” on outdated equipment. If your enterprise application is scalable, adding several servers is cheaper than purchasing the services of several programmers1. The basis of this position is the business case for performance optimization, which also often influences decisions regarding the definition of engineering solutions.
The web server occupies an important place in the system of infrastructure optimization methods. According to the official documentation, Nginx is one of the most widespread and productive HTTP servers in the world2. Nginx is widely used to serve static content, act as a reverse proxy, load balancer, and caching system. The main functionality of an HTTP server includes: processing incoming HTTP requests; transfer of static files; proxying requests to the backend application; connection management; ensuring safety and stability under load.

Figure 7 ¾ Share of sites on the Internet that run on a specific web server3
Nginx is part of the so-called LEMP stack and is widely used in developing PHP applications using the Yii2 framework. Nginx has proven itself in solving problems related to optimizing the performance of web applications due to its high speed, ease of configuration, asynchronous processing of static resources, caching capabilities at the web server level, and the ability to be used as a load balancer. The corresponding functionality allows you to flexibly configure and increase the performance of PHP web applications developed using the Yii2 framework.
Optimizing the performance of any type of server or application always depends on many variable factors such as, but not limited to, the environment, use case, requirements, and physical components involved. A frequently used optimization technique is based on finding bottlenecks, that is, testing until a bottleneck is found, identifying that bottleneck, adjusting to the constraints, and repeating the process until the desired performance is achieved4.
The literature identifies many ways to optimize Nginx performance, for example: 1) test automation using boot drivers; 2) browser cache management; 3) maintaining open connections with clients; 4) maintaining open connections with the outgoing channel; 5) buffering of responses; 6) buffering of access logs; 7) OS setup5.
The basis of the infrastructure part of the application will be the widely used LEMP stack (Linux, Nginx, MySQL, PHP). PHP code will be processed by the PHP-FPM process manager, which ensures effective load management and stable application operation.
5.2 Setting up caching of static resources
Static files (images, styles, scripts, fonts) rarely change, so it makes sense to cache them on the client side. Setting HTTP header directives allows the browser to reuse previously downloaded resources without contacting the server. Client-side caching improves application performance. The literature suggests the following Nginx configuration:
location ~* \.(css|js)$ {
expires 1y;
add_header Cache-Control "public";
}
This location block specifies that the client can cache the contents of CSS and JavaScript files. The expires directive tells the client that the cached resource will no longer be valid after one year. The add_header directive adds a Cache-Control HTTP response header with the value public, allowing any caching server to cache the resource. If private, only the 6 client can cache the value.
As a result, you can ensure: a reduction in the number of requests to the server; speeding up page reloading; reduction of network traffic; improving user experience. Cache performance depends on many factors, and disk speed is high on that list. Nginx configuration provides many ways to improve cache performance. One option is to configure the response headers so that the client actually caches the response and does not send the request to Nginx at all, but simply serves it from its own cache7.
5.3 Data compression (Gzip and Brotli)
Transferring uncompressed data increases page loading time. Compression allows you to significantly reduce the amount of transmitted information.
Gzip is the most common HTTP response compression algorithm. Setting example:
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
Brotli provides higher compression rates than Gzip and is supported by modern browsers.
brotli on;
brotli_types text/plain text/css application/javascript;
The use of compression is especially effective for text resources: HTML; CSS; JavaScript; JSON.
5.4 Optimizing connection parameters
Keep-alive allows you to use a single TCP connection for multiple HTTP requests, reducing connection establishment overhead. For example: keepalive_timeout 65;.
Correctly configuring the handling of a large number of simultaneous connections is also considered as a way to optimize the performance of web applications. You need to increase the number of requests allowed per connection from clients and increase the amount of time that inactive connections can remain open.
The literature recommends using the keepalive_requests and keepalive_timeout directives to change the number of requests that can be made within a single connection and the time that inactive connections can remain open:
http {
keepalive_requests 320;
keepalive_timeout 300s;
# ...
}
The keepalive_requests directive defaults to 100, and the keepalive_timeout directive defaults to 75 seconds. Typically, the default number of requests per connection will satisfy the client's needs, since modern browsers can open multiple connections to a single server for each fully qualified domain name (FQDN). The number of concurrent open connections to a domain is usually limited to less than 10, so in this regard there will be many requests on a single connection. One technique often used by content delivery networks in HTTP/1.1 is to create multiple domain names that point to the content server and alternate the domain names used in the code to allow the browser to open more connections. These connection optimizations can be useful if the frontend application is constantly polling the backend application for updates, since an open connection that allows more requests to be sent and remains open longer will limit the number of connections needed8.
By default, Nginx can: open a connection to the backend (upstream); send a request; close the connection. Creating a new TCP connection every time is: an extra handshake; delay; additional load on the CPU; more sockets. If there are a lot of requests, this significantly affects performance.
To improve performance, it is necessary to maintain open connections with upstream servers for reuse. The literature recommends using the keepalive directive in an upstream context to keep connections to upstream servers open for reuse9:
proxy_http_version 1.1;
proxy_set_header Connection "";
upstream backend {
server 10.0.0.0;
server 10.0.0.1;
keepalive 32;
}
The keepalive 32 directive indicates that each Nginx worker can keep up to 32 idle (free but open) connections to backend servers. When a new request arrives, Nginx does not open a new connection, but takes one of the already open idle connections. This speeds up the processing of requests.
The proxy_http_version 1.1 directive is specified because HTTP/1.0 does not fully support keep-alive connections. Using HTTP/1.1 allows multiple requests and responses to be sent within a single connection, which reduces overhead and improves performance.
The proxy_set_header Connection "" directive is used because by default Nginx can send the header: Connection: close. This header causes the backend to close the connection. This line removes this header to keep the connection open.
It is important to note that idle connections are not equal to all connections: 1) keepalive 32 is 32 free connections per worker; 2) there may be more active compounds; if the number of workers is 4, then there are a maximum of 128 idle connections. For this reason, the value must be reasonable so as not to clog the backend with open sockets. The specified optimization technique is that without keepalive, each request creates a new connection, keepalive connections are reused, less latency, less load, higher performance.
The keepalive directive in the upstream context activates a cache of connections that remain open for each Nginx worker process. The directive specifies the maximum number of idle connections that must remain open for each worker process. The proxy module directives used above the upstream block are required for the keepalive directive to work correctly for connections to upstream servers. The proxy_http_version directive tells the proxy module to use HTTP version 1.1, which allows multiple requests to be made sequentially on a single connection while it is open. The proxy_set_header directive tells the proxy module to remove the default close header, allowing the connection to remain open.
Connections to upstream servers should be kept open to reduce the time it takes to establish a connection, allowing the worker process to instead proceed directly to sending a request over an inactive connection. It is important to note that the number of open connections may exceed the number of connections specified in the keepalive directive, since open connections and inactive connections are not the same thing.
The number of keepalive connections should be small enough to allow other incoming connections to your upstream server to be processed. Configuring Nginx accordingly can save resources and improve performance10. The worker_processes and worker_connections parameters determine how many requests the server can process in parallel.
worker_processes auto;
events {
worker_connections 1024;
}
Correct settings allow you to make the most efficient use of processor and RAM resources.
5.5 Microcaching
Microcaching is the caching of dynamic pages for a very short time (for example, 1-10 seconds). Even such a small interval can significantly reduce the load when there are a large number of similar requests.
Example of setting proxy_cache:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=microcache:10m inactive=60m;
location / {
proxy_pass http://backend;
proxy_cache microcache;
proxy_cache_valid 200 5s;
}
The benefits mainly include dramatically reduced load on the backend, increased resilience during peak loads, and faster responsiveness for users.
5.6 Infrastructure optimization results
We will consider practical results of optimization at the server infrastructure level using the example of Gzip and Brotli compression. Figure 8 shows the “Network” tab of the browser developer panel of the source page (without applying any compression algorithms), which we will take as a basis when determining the compression efficiency of the algorithms in question.

Figure 8 ¾ Original page (without compression algorithms)
Figures 9 and 10 show a similar page using the Gzip and Brotli algorithms, respectively. In the presented figures, we are interested in the “Size” column, which contains the size of the downloaded files.

Figure 9 ¾ Compression using the Gzip algorithm
The following Nginx configuration was used for compression using the Gzip algorithm:
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_vary on;
gzip_proxied any;
gzip_disable "msie6";
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-javascript;

Figure 10 ¾ Compression using the Brotli algorithm
The following Nginx configuration was used for compression using the Brotli algorithm:
brotli on;
brotli_static on;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
brotli_comp_level 5;
Consolidated data demonstrating a comparison of the Gzip and Brotli compression algorithms are presented in Table 4.
Table 4 ¾ Comparison of Gzip and Brotli compression algorithms as a percentage of the original size
| **Name**
file | **Original size (KB)** | **Gzip (KB)** | **Gzip % compression** | **Brotli (KB)** | **Brotli % compression** |
| bootstrap.css | 281 | 35 | 87.5% | 30.8 | 89.0% |
| site.css | 1.8 | 0.9 | 50.0% | 0.8 | 55.6% |
| jquery.js | 286 | 85.8 | 70.0% | 80 | 72.0% |
| yii.js | 21.2 | 6.2 | 70.8% | 5.8 | 72.6% |
| bootstrap.bundle.js | 208 | 45.9 | 77.9% | 41.9 | 79.9% |
The compression percentage is calculated using formula (1).
|  | (1) |
where original size is the file size before applying the compression algorithm (in KB or MB);
size after compression – file size after applying the compression algorithm (in the same units).
Taking into account the above, it can be noted that the use of compression algorithms can significantly reduce the size of transferred files (up to 87-89%). Brotli compression algorithm is more efficient than Gzip. On average, Brotli compresses files 2-5% more efficiently than Gzip, depending on the specific file.
Fowler M. Templates for enterprise applications. Per. from English – M.: LLC “I.D. Williams", 2016. ↩
Nginx: documentation. – [Electronic resource]. – URL: https://nginx.org/ru/docs/ (date of access: 01/14/2026). ↩
Netcraft. The percentage of sites on the Internet that run on a particular web server. [Electronic resource]. – URL: https://www.netcraft.com/blog/january-2026-web-server-survey (access date: 03/10/2026). ↩
DeJonghe D. Nginx Cookbook: Advanced Recipes for High Performance Load Balancing. – 3rd ed. – Sebastopol: O’Reilly Media, 2024. ↩
DeJonghe D. Nginx Cookbook: Advanced Recipes for High Performance Load Balancing. – 3rd ed. – Sebastopol: O’Reilly Media, 2024. ↩
DeJonghe D. Nginx Cookbook: Advanced Recipes for High Performance Load Balancing. – 3rd ed. – Sebastopol: O’Reilly Media, 2024. ↩
DeJonghe D. Nginx Cookbook: Advanced Recipes for High Performance Load Balancing. – 3rd ed. – Sebastopol: O’Reilly Media, 2024. ↩
DeJonghe D. Nginx Cookbook: Advanced Recipes for High Performance Load Balancing. – 3rd ed. – Sebastopol: O’Reilly Media, 2024. ↩
DeJonghe D. Nginx Cookbook: Advanced Recipes for High Performance Load Balancing. – 3rd ed. – Sebastopol: O’Reilly Media, 2024. ↩
DeJonghe D. Nginx Cookbook: Advanced Recipes for High Performance Load Balancing. – 3rd ed. – Sebastopol: O’Reilly Media, 2024. ↩
Coding is used in almost all aspects of life and work now, be it directly or indirectly. It’s not just for companies in the tech sector. “An increasing number of businesses rely on computer code,
Coding is used in almost all aspects of life and work now, be it directly or indirectly. It’s not just for companies in the tech sector. “An increasing number of businesses rely on computer code,
Coding is used in almost all aspects of life and work now, be it directly or indirectly. It’s not just for companies in the tech sector. “An increasing number of businesses rely on computer code,