Repository navigation
worker use 100% cpu #41
Copy link
Copy link
Open
Description
Hello! I'm using fork nginx (angie) and trying to enable zstd-module into my project.
And it works great on ubuntu22.04 and 24.04, but one of my server still use ubuntu20.04 and I met trouble...
After few requests angie started to use 100% for worker that accept request... and than another worker and another and another. And after around 100-200 request all 4 workers utilizing all of my vcpu.
Here is start of problem debug log and after that many-many thousands last of two strings. Worker processed like that cannot finishing with HUP signal. Only restart...
2024/11/27 14:03:06 [debug] 56414#56414: *138 http cleanup add: 0000559F3E406028
2024/11/27 14:03:06 [debug] 56414#56414: *138 init keepalive peer
2024/11/27 14:03:06 [debug] 56414#56414: *138 get keepalive peer
2024/11/27 14:03:06 [debug] 56414#56414: *138 get rr peer, try: 1
2024/11/27 14:03:06 [debug] 56414#56414: *138 get keepalive peer: using connection 00007FC7D8ED66D8
2024/11/27 14:03:06 [debug] 56414#56414: *138 event timer del: 22: 7256125
2024/11/27 14:03:06 [debug] 56414#56414: *138 http upstream connect: -4
2024/11/27 14:03:06 [debug] 56414#56414: *138 http upstream send request
2024/11/27 14:03:06 [debug] 56414#56414: *138 http upstream send request body
2024/11/27 14:03:06 [debug] 56414#56414: *138 chain writer buf fl:1 s:889
2024/11/27 14:03:06 [debug] 56414#56414: *138 chain writer in: 0000559F3E406078
2024/11/27 14:03:06 [debug] 56414#56414: *138 writev: 889 of 889
2024/11/27 14:03:06 [debug] 56414#56414: *138 chain writer out: 0000000000000000
2024/11/27 14:03:06 [debug] 56414#56414: *138 event timer add: 22: 3600000:10796191
2024/11/27 14:03:06 [debug] 56414#56414: *138 http finalize request: -4, "/lux-kube-v3-ui-vue-components-2107-styles?delimiter=%2F&max-keys=1000&prefix=2.2.143-wv3inbox-14214-4749345f.0%2F" a:1, c:2
2024/11/27 14:03:06 [debug] 56414#56414: *138 http request count:2 blk:0
2024/11/27 14:03:06 [debug] 56414#56414: *138 http run request: "/lux-kube-v3-ui-vue-components-2107-styles?delimiter=%2F&max-keys=1000&prefix=2.2.143-wv3inbox-14214-4749345f.0%2F"
2024/11/27 14:03:06 [debug] 56414#56414: *138 http upstream check client, write event:1, "/lux-kube-v3-ui-vue-components-2107-styles"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http upstream request: "/lux-kube-web-push-4687-static/firebase-messaging-sw.js?"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http upstream process header
2024/11/27 14:03:06 [debug] 56414#56414: *143 malloc: 0000559F3E407150:131072
2024/11/27 14:03:06 [debug] 56414#56414: *143 recv: eof:0, avail:-1
2024/11/27 14:03:06 [debug] 56414#56414: *143 recv: fd:30 395 of 131072
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy status 200 "200 OK"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "Content-Length: 2722"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "Accept-Ranges: bytes"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "Last-Modified: Wed, 27 Nov 2024 07:07:56 GMT"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "x-rgw-object-type: Normal"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "ETag: "1e8ff66b01c006f78fa76ea36c13e891""
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "x-amz-meta-mtime: 1732691275.597285236"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "x-amz-request-id: tx000005dca0145fb0c9708-006746fc6a-2a2ff8f-default"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "Content-Type: text/javascript; charset=utf-8"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "Date: Wed, 27 Nov 2024 11:03:06 GMT"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header: "Connection: Keep-Alive"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy header done
2024/11/27 14:03:06 [debug] 56414#56414: *143 HTTP/1.1 200 OK
Server: Angie
Date: Wed, 27 Nov 2024 11:03:06 GMT
Content-Type: text/javascript; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Wed, 27 Nov 2024 07:07:56 GMT
ETag: W/"1e8ff66b01c006f78fa76ea36c13e891"
x-amz-meta-mtime: 1732691275.597285236
Content-Encoding: zstd
2024/11/27 14:03:06 [debug] 56414#56414: *143 write new buf t:1 f:0 0000559F3E2779B0, pos 0000559F3E2779B0, size: 346 file: 0, size: 0
2024/11/27 14:03:06 [debug] 56414#56414: *143 http write filter: l:0 f:0 s:346
2024/11/27 14:03:06 [debug] 56414#56414: *143 http proxy filter init s:200 h:0 c:0 l:2722
2024/11/27 14:03:06 [debug] 56414#56414: *143 tcp_nodelay
2024/11/27 14:03:06 [debug] 56414#56414: *143 http output filter "/lux-kube-web-push-4687-static/firebase-messaging-sw.js?"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http copy filter: "/lux-kube-web-push-4687-static/firebase-messaging-sw.js?"
2024/11/27 14:03:06 [debug] 56414#56414: *143 http postpone filter "/lux-kube-web-push-4687-static/firebase-messaging-sw.js?" 00007FFD3E94C670
2024/11/27 14:03:06 [debug] 56414#56414: *143 http zstd filter
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd alloc: 0000559F3E277BE0, size: 1144
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd in: 0000559F3E278058
2024/11/27 14:03:06 [debug] 56414#56414: *143 malloc: 0000559F3E427160:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:0
2024/11/27 14:03:06 [debug] 56414#56414: *143 malloc: 00007FC7D7D1A010:6012417
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd alloc: 00007FC7D7D1A010, size: 6012417
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:1
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:0
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:1
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:0
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:1
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:0
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:1
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:0
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:1
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:0
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress out: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096
2024/11/27 14:03:06 [debug] 56414#56414: *143 zstd compress in: src:0000000000000000 pos:0 size: 0, dst:0000559F3E427160 pos:0 size:4096 flush:1 redo:1
Metadata
Metadata
Assignees
Labels
No labels
Activity
tokers commentedon Dec 17, 2024
@dolgovas It would be nice to have a minimum reproducible case. BTW, could you capture a flame graph when Nginx workers occupy nearly 100% CPU time.
dolgovas commentedon Dec 18, 2024
I'll try to make it ASAP
dolgovas commentedon Dec 18, 2024
made via this instruction.

hackoffme commentedon Dec 25, 2024
I have encountered the same issue described in this thread. After integrating the zstd-nginx-module into my Nginx server, the worker processes consume 100% CPU following the first request, leading to server unresponsiveness.
nginx/1.26.2
zstd-nginx-module 0.1.1
cat /usr/share/nginx/modules/zstd_* load_module "/usr/lib64/nginx/modules/ngx_http_zstd_filter_module.so"; load_module "/usr/lib64/nginx/modules/ngx_http_zstd_static_module.so";kamermans commentedon Jan 10, 2025
I'm also seeing this in an Ubuntu 22.04 container running Nginx:
I repackage the official
debsource fromnginx.orgwith thezstdandbrotliadded.I'm using the official Ubuntu
libzstd1package:Here's a graph of the CPU usage from the instance start time to 30 minutes later when it started failing health checks. During this time period, this instance was getting about 140 client requests per second, although most of them would not have used ztsd, probably 5-10% of those requests were using zstd.

dolgovas commentedon Jan 15, 2025
@tokers may be you need any additional info?
bouk commentedon Jan 22, 2025
Seems related: #23
madrzejewski commentedon Jun 23, 2025
Hello,
Same issue here with Openresty 1.27.1.2, after a few days I always have a few Nginx processes stuck at 100% CPU usage.
When I run GDB on one of the process to get a backstrace, I have this :
fix: Apply PR #23 + PR #49 fixes for CPU 100% infinite loop bug
gtoxlili commentedon Aug 7, 2026
Still reproduces on nginx 1.29.8 / zstd-nginx-module 0.1.1 / libzstd 1.5.7.
filter/ngx_http_zstd_filter_module.cis byte-identical between the0.1.1tag and current master, so nothing has changed here since this was filed.One worker sat at 100% CPU for 12 days before we noticed (utime 12d, stime 134s, zero syscalls). I sampled RIP 30 times via ptrace: 21 samples landed in
libzstd.soinside a ~600 byte window, 9 in the module's filter code. The upstream socket was still in CLOSE-WAIT withRecv-Qexactly equal to the responseContent-Length, so the response body had never been read — the loop starts before any body byte arrives. That matches thesize: 0on both buffers in @dolgovas's debug log.The loop is an oscillation between
COMPRESSandFLUSHwhen the filter is entered with a zero-length buffer that hasflushset (line numbers are master):add_datapicks up the empty flush buf, setsctx->flush = 1(L518-519), computesbuffer_in.size = 0, returnsNGX_AGAIN(L531). After that it can never take anything else offctx->in: L500-503 short-circuits onctx->flushbefore reaching thectx->in == NULL → NGX_DECLINEDexit at L511.Each pass of the inner
for ( ;; )at L309 then does:COMPRESS—ZSTD_compressStream()within.size == 0returns > 0, so L443-448 sets action toFLUSHandredo = 1.out_bufis empty, so L462 returnsNGX_AGAIN.FLUSH—ZSTD_flushStream()returns 0 (nothing buffered),redo = 0at L441.rc > 0is false, andctx->lastis 0 becauselast_bufnever arrived, so L450 cannot switch toEND. L458-459 restores action toCOMPRESS.out_bufstill empty,NGX_AGAINagain.Neither
buffer_in.posnorbuffer_out.posever moves, so L439-440 are no-ops. This is exactly the alternatingredo:0/redo:1withpos:0 size:0in the log above.ctx->flushis the flag that would break the cycle, but it is only cleared at L480, which sits below thengx_buf_size(ctx->out_buf) == 0 → return NGX_AGAINat L462. A flush that produces no output never reaches it.On our side the trigger was
proxy_buffering offset atserverlevel on a vhost that also served a small proxied HTML page (200,text/html,Content-Length: 2281, clientAccept-Encoding: gzip, deflate, br, zstd). Scoping the directive down to the upload-only location removed the exposure. That page took ~150 requests over two months and only one of them wedged a worker, so some timing has to line up.One consequence worth flagging, since @dolgovas hit it too ("cannot finishing with HUP signal"): a worker in this state never returns to the event loop, so it also never handles SIGQUIT.
nginx -s reloadleaves it running as an orphan from the previous cycle, indefinitely — ours survived a reload and burned a core for another 7 days before anyone looked.worker_shutdown_timeoutbounds that. Settingzstd offwhile keepingzstd_static onavoids the code path entirely, since the static module does not compress at runtime.eilandert commentedon Aug 7, 2026
@gtoxlili would you be so kind to test a fork with an outstanding PR into this repo?
https://github.com/myguard-labs/nginx-zstd-module
I fixed this problem and more