Title: AsyncContextFrame may not be released when using HTTP parsers · Issue #61882 · nodejs/node · GitHub
Open Graph Title: AsyncContextFrame may not be released when using HTTP parsers · Issue #61882 · nodejs/node
X Title: AsyncContextFrame may not be released when using HTTP parsers · Issue #61882 · nodejs/node
Description: Version v25.6.1 Platform Darwin XXX 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:48:41 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6041 arm64 Subsystem http What steps will reproduce the bug? When an HTTP request is executed, da...
Open Graph Description: Version v25.6.1 Platform Darwin XXX 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:48:41 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6041 arm64 Subsystem http What steps will reproduce the b...
X Description: Version v25.6.1 Platform Darwin XXX 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:48:41 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6041 arm64 Subsystem http What steps will reproduce the b...
Opengraph URL: https://github.com/nodejs/node/issues/61882
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"AsyncContextFrame may not be released when using HTTP parsers","articleBody":"### Version\n\nv25.6.1\n\n### Platform\n\n```text\nDarwin XXX 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:48:41 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6041 arm64\n```\n\n### Subsystem\n\nhttp\n\n### What steps will reproduce the bug?\n\nWhen an HTTP request is executed, data in AsyncLocalStorage isn't freed. To reproduce it:\n\n```\nimport hooks from 'node:async_hooks';\nimport http from 'node:http';\nimport net from 'node:net';\nimport crypto from 'node:crypto';\n\n// http.setMaxIdleHTTPParsers(1);\n\nconst store = new hooks.AsyncLocalStorage();\n\nfunction sendRequest() {\n store.enterWith({body: crypto.randomBytes(512)});\n const proxyReq = http.request({\n agent: null,\n createConnection: net.createConnection,\n method: 'HEAD',\n hostname: '127.0.0.1',\n headers: {\n 'connection': 'close'\n },\n port: 9009,\n path: '/',\n });\n proxyReq.end();\n}\n\nfor (let i = 0; i \u003c 10; i++) {\n for (let j = 0; j \u003c 100; j++) {\n sendRequest();\n }\n}\n\nsetTimeout(() =\u003e {\n console.log('done');\n}, 1000 * 60 * 60);\n```\n\nWhen running this with `node --inspect`, one can see that there are 1000 `AsyncContextFrame` entries in memory, as well as the buffer stored in the `AsyncLocalStorage`. This happens with `AsyncContextFrame` enabled (Node 24+)\nI stumbled upon this when making an outbound request from an HTTP server handler `(req, res) =\u003e {...}` where I was using AsyncLocalStorage to keep some request context. I noticed that the memory was freed if I made the outbound requests using `fetch()` instead of `http.request`.\n\nAlso, if `http.setMaxIdleHTTPParsers(1);` is uncommented, so that HTTP parsers aren't reused, the memory is also freed.\n\n### How often does it reproduce? Is there a required condition?\n\nAlways\n\n### What is the expected behavior? Why is that the expected behavior?\n\nWhatever is stored in an `AsyncLocalStorage` should be freed when it goes out of scope.\n\n### What do you see instead?\n\n\u003cimg width=\"2123\" height=\"1113\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/970e8e75-8e8b-4d11-85cf-6633fa6a4543\" /\u003e\n\nIt can be seen here that there are 1000 instances of `AsyncContextFrame`\n\n### Additional information\n\nI downloaded Node's source and tinkered with the parser initialization in `_http_client.js` and with the AsyncWrap logic in `node_http_parser.cc`, but couldn't fix it. I see that `freeParser()` should free everything, but it seems something is being held. I'm not familiar with the relationship between `AsyncWrap` and V8-based new `AsyncLocalStorage` implementation.\nI understand that not reusing parsers has a memory impact. I also noticed PRs like https://github.com/nodejs/node/pull/57938 and https://github.com/nodejs/node/pull/59621 that might fix this thing.\n\nThis is an issue when using libraries like Datadog's `dd-trace`, which store tracing information in `AsyncLocalStorage`","author":{"url":"https://github.com/lukiano","@type":"Person","name":"lukiano"},"datePublished":"2026-02-19T04:19:16.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/61882/node/issues/61882"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:49a71c3c-d740-ab7c-40f4-a725cdc86db2 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | CF0A:265A7D:7509FE:9D931A:6A4C2FE7 |
| html-safe-nonce | 0748eec4ef004f24d1d8df9b85f4facf353d98190232ebcb3d87e4de745b9709 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDRjBBOjI2NUE3RDo3NTA5RkU6OUQ5MzFBOjZBNEMyRkU3IiwidmlzaXRvcl9pZCI6IjE4ODMxOTk2Mjc1NjczMTI4NzEiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 424efaa2e9ea0d6700aa67e782bb1508b9bff4a73e8db30e1b1e4ee34dcde877 |
| hovercard-subject-tag | issue:3960913637 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/61882/issue_layout |
| twitter:image | https://opengraph.githubassets.com/0e479299649b1843dd3442fce7f46dedfac0f5bd9b2eb09c55a8f41237a35b81/nodejs/node/issues/61882 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/0e479299649b1843dd3442fce7f46dedfac0f5bd9b2eb09c55a8f41237a35b81/nodejs/node/issues/61882 |
| og:image:alt | Version v25.6.1 Platform Darwin XXX 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:48:41 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6041 arm64 Subsystem http What steps will reproduce the b... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | lukiano |
| hostname | github.com |
| expected-hostname | github.com |
| None | 1b6b16d04026f131a36d57e3b01d0f4d26a51800edf48bf5ed0256e0ac905511 |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 9ee13484b32cf23e15fde191da4c9aa47d41201c |
| ui-target | canary-2 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width