fankeke opened a new issue, #13188:
URL: https://github.com/apache/apisix/issues/13188

   ### Description
   
   Evaluating the reasonableness of APISIX’s performance overhead through load 
testing
   
   Hello, recently I ran load tests on APISIX and wanted to measure the 
performance overhead introduced by its Lua framework. Below is my load-testing 
approach.
   
   Configuration: single process, single worker enabled.
   
   Goal: mainly to evaluate the overhead in the access_by_lua_block phase.
   
   Load-test comparison:
   
   Comment out the access_by_lua_block phase. In the content phase, use the 
ngx.say API to return “hello”. Remove proxy_pass, and eliminate overhead from 
SSL and other phases such as header_filter, body_filter, log_filter, etc.
   Keep the access_by_lua_block phase. In the content phase, use the ngx.say 
API to return “hello”. Remove proxy_pass, and eliminate overhead from SSL and 
other phases such as header_filter, body_filter, log_filter, etc.
   Config file: as follows.
   ```
   
   master_process on;
               
   worker_processes 1;
               
   # main configuration snippet starts
               
   # main configuration snippet ends
   
   error_log logs/error.log warn; 
   pid logs/nginx.pid;
               
   worker_rlimit_nofile 20480;
               
   events {    
       accept_mutex off;
       worker_connections 10620;                   
   }           
               
   worker_rlimit_core  16G;
               
   worker_shutdown_timeout 240s;
               
   env APISIX_PROFILE;
   env PATH; # for searching external plugin runner's binary
   
   # reserved environment variables for configuration
   env APISIX_DEPLOYMENT_ETCD_HOST; 
   env GCP_SERVICE_ACCOUNT;
               
               
   thread_pool grpc-client-nginx-module threads=1;
               
   lua {
       lua_shared_dict prometheus-cache 10m;
       lua_shared_dict nacos 10m;
   }           
               
   http {
      ....; 
   
     server {
           http2 on;
           listen 0.0.0.0:9080 default_server reuseport;
           listen 0.0.0.0:9443 ssl default_server reuseport;
   
           server_name _;
   
           ssl_certificate      cert/ssl_PLACE_HOLDER.crt;
           ssl_certificate_key  cert/ssl_PLACE_HOLDER.key;
           ssl_session_cache    shared:SSL:20m;
           ssl_session_timeout 10m;
   
           ssl_protocols TLSv1.2 TLSv1.3;
           ssl_ciphers 
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
           ssl_prefer_server_ciphers on;
           ssl_session_tickets off;
   
           proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
   
           # opentelemetry_set_ngx_var starts
           set $opentelemetry_context_traceparent          '';
           set $opentelemetry_trace_id                     '';
           set $opentelemetry_span_id                      '';
           # opentelemetry_set_ngx_var ends
   
           # zipkin_set_ngx_var starts
           # zipkin_set_ngx_var ends
   
           # http server configuration snippet starts
   
           # http server configuration snippet ends
   
           access_log off;
   
           location = /apisix/nginx_status {
               allow 127.0.0.0/24;
               deny all;
               access_log off;
               stub_status;
           }
   
           #        ssl_client_hello_by_lua_block {
           #            apisix.ssl_client_hello_phase()
           #        }
           #
           #        ssl_certificate_by_lua_block {
           #            apisix.ssl_phase()
           #        }
   
           proxy_ssl_name $upstream_host;
           proxy_ssl_server_name on;
      location / {
               set $upstream_mirror_host        '';
               set $upstream_mirror_uri         '';
               set $upstream_upgrade            '';
               set $upstream_connection         '';
   
               set $upstream_scheme             'http';
               set $upstream_host               $http_host;
               set $upstream_uri                '';
               set $ctx_ref                     '';
   
   
               # http server location configuration snippet starts
   
               # http server location configuration snippet ends
   
   
               set $llm_content_risk_level         '';
               set $apisix_upstream_response_time  $upstream_response_time;
               set $request_type               'traditional_http';
               set $request_llm_model              '';
   
               set $llm_time_to_first_token        '0';
               set $llm_model                      '';
               set $llm_prompt_tokens              '0';
               set $llm_completion_tokens          '0';
   
   
               set $apisix_request_id $request_id;
               lua_error_log_request_id $apisix_request_id;
   
               #            access_by_lua_block {
               #                apisix.http_access_phase()
               #            }
   
               proxy_http_version 1.1;
               proxy_set_header   Host              $upstream_host;
               proxy_set_header   Upgrade           $upstream_upgrade;
               proxy_set_header   Connection        $upstream_connection;
               proxy_set_header   X-Real-IP         $remote_addr;
               proxy_pass_header  Date;
   
               ### the following x-forwarded-* headers is to send to upstream 
server
   
               set $var_x_forwarded_proto      $scheme;
               set $var_x_forwarded_host       $host;
               set $var_x_forwarded_port       $server_port;
   
               proxy_set_header   X-Forwarded-For      
$proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto    $var_x_forwarded_proto;
               proxy_set_header   X-Forwarded-Host     $var_x_forwarded_host;
               proxy_set_header   X-Forwarded-Port     $var_x_forwarded_port;
   
               ###  the following configuration is to cache response content 
from upstream server
   
               set $upstream_cache_zone            off;
               set $upstream_cache_key             '';
               set $upstream_cache_bypass          '';
               set $upstream_no_cache              '';
   
               proxy_cache                         $upstream_cache_zone;
               proxy_cache_valid                   any 10s;
               proxy_cache_min_uses                1;
               proxy_cache_methods                 GET HEAD POST;
               proxy_cache_lock_timeout            5s;
               proxy_cache_use_stale               off;
               proxy_cache_key                     $upstream_cache_key;
               proxy_no_cache                      $upstream_no_cache;
               proxy_cache_bypass                  $upstream_cache_bypass;
   
   
               content_by_lua_block {
                       ngx.say("benchmark")
               }
               #proxy_pass      $upstream_scheme://apisix_backend$upstream_uri;
   
               # mirror          /proxy_mirror;
   
               #            header_filter_by_lua_block {
               #                apisix.http_header_filter_phase()
               #            }
               #
               #            body_filter_by_lua_block {
               #                apisix.http_body_filter_phase()
               #            }
               #
               #            log_by_lua_block {
               #                apisix.http_log_phase()
               #            }
           }
    }
   
   ```
   
   
   Load-test results:
   
   With access_by_lua_block commented out:
   ```
   root@885e85bad68d:/usr/local/apisix/wrk# ./wrk   -t4 -c200 -d30s   -H "Host: 
test2.abc.com"  http://127.0.0.1:9080/get --latency
   Running 30s test @ http://127.0.0.1:9080/get
     4 threads and 200 connections
     Thread Stats   Avg      Stdev     Max   +/- Stdev
       Latency     5.17ms    6.78ms 298.00ms   99.35%
       Req/Sec    10.39k   846.65    22.23k    83.33%
     Latency Distribution
        50%    4.76ms
        75%    5.01ms
        90%    5.22ms
        99%    6.59ms
     1241296 requests in 30.01s, 222.55MB read
   Requests/sec:  41363.43
   Transfer/sec:      7.42MB
   
   ```
   
   
   With access_by_lua_block kept:
   
   ```
   root@885e85bad68d:/usr/local/apisix/wrk# ./wrk   -t4 -c200 -d30s   -H "Host: 
test2.abc.com"  http://127.0.0.1:9080/get --latency
   Running 30s test @ http://127.0.0.1:9080/get
     4 threads and 200 connections
     Thread Stats   Avg      Stdev     Max   +/- Stdev
       Latency    18.97ms   45.68ms 977.12ms   98.01%
       Req/Sec     3.66k   537.12     7.75k    78.33%
     Latency Distribution
        50%   12.77ms
        75%   14.30ms
        90%   18.52ms
        99%  265.48ms
     437710 requests in 30.08s, 78.48MB read
   Requests/sec:  14549.67
   Transfer/sec:      2.61MB
   
   ```
   
   Preliminary conclusion: QPS drops by about `65%.`
   
   I’d like to ask whether this level of performance overhead is considered 
reasonable, and whether it falls within the normal framework overhead behavior.
   
   ### Environment
   
   - APISIX version (run `apisix version`):
   ```
   - root@885e85bad68d:/usr/local/apisix/wrk# apisix version
   /usr/local/openresty//luajit/bin/luajit 
/usr/local/apisix/apisix/cli/apisix.lua version
   3.15.0
   ```
   - Operating system (run `uname -a`):
   ```
   Linux 885e85bad68d 4.18.0-553.80.1.el8_10.x86_64 #1 SMP Fri Oct 24 09:31:30 
UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
   ```
   - OpenResty / Nginx version (run `openresty -V` or `nginx -V`):
   ```
   root@885e85bad68d:/usr/local/apisix/wrk# openresty -v
   nginx version: openresty/1.27.1.2
   ```
   - etcd version, if relevant (run `curl 
http://127.0.0.1:9090/v1/server_info`):
   - APISIX Dashboard version, if relevant:
   - Plugin runner version, for issues related to plugin runners:
   - LuaRocks version, for installation issues (run `luarocks --version`):
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to