{"id":13992257,"url":"https://github.com/node-modules/agentkeepalive","last_synced_at":"2025-06-14T03:07:45.028Z","repository":{"id":4397977,"uuid":"5535125","full_name":"node-modules/agentkeepalive","owner":"node-modules","description":"Support keepalive http agent.","archived":false,"fork":false,"pushed_at":"2024-05-08T15:43:33.000Z","size":340,"stargazers_count":580,"open_issues_count":19,"forks_count":57,"subscribers_count":31,"default_branch":"master","last_synced_at":"2024-10-29T20:37:49.435Z","etag":null,"topics":["keep-alive"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/node-modules.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-08-24T02:31:51.000Z","updated_at":"2024-10-29T07:08:42.000Z","dependencies_parsed_at":"2024-05-08T17:23:48.784Z","dependency_job_id":null,"html_url":"https://github.com/node-modules/agentkeepalive","commit_stats":{"total_commits":147,"total_committers":28,"mean_commits":5.25,"dds":"0.38095238095238093","last_synced_commit":"6db01a0c45ca4e0d9dac12147329fb3539f8728f"},"previous_names":["tbedp/agentkeepalive"],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fagentkeepalive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fagentkeepalive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fagentkeepalive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fagentkeepalive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/node-modules","download_url":"https://codeload.github.com/node-modules/agentkeepalive/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227124350,"owners_count":17734317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["keep-alive"],"created_at":"2024-08-09T14:01:54.234Z","updated_at":"2025-06-14T03:07:45.021Z","avatar_url":"https://github.com/node-modules.png","language":"JavaScript","readme":"# agentkeepalive\n\n[![NPM version][npm-image]][npm-url]\n[![Known Vulnerabilities][snyk-image]][snyk-url]\n[![Node.js CI](https://github.com/node-modules/agentkeepalive/actions/workflows/nodejs.yml/badge.svg)](https://github.com/node-modules/agentkeepalive/actions/workflows/nodejs.yml)\n[![npm download][download-image]][download-url]\n\n[npm-image]: https://img.shields.io/npm/v/agentkeepalive.svg?style=flat\n[npm-url]: https://npmjs.org/package/agentkeepalive\n[snyk-image]: https://snyk.io/test/npm/agentkeepalive/badge.svg?style=flat-square\n[snyk-url]: https://snyk.io/test/npm/agentkeepalive\n[download-image]: https://img.shields.io/npm/dm/agentkeepalive.svg?style=flat-square\n[download-url]: https://npmjs.org/package/agentkeepalive\n\nThe enhancement features `keep alive` `http.Agent`. Support `http` and `https`.\n\n## What's different from original `http.Agent`?\n\n- `keepAlive=true` by default\n- Disable Nagle's algorithm: `socket.setNoDelay(true)`\n- Add free socket timeout: avoid long time inactivity socket leak in the free-sockets queue.\n- Add active socket timeout: avoid long time inactivity socket leak in the active-sockets queue.\n- TTL for active socket.\n\n## Node.js version required\n\nSupport Node.js \u003e= `8.0.0`\n\n## Install\n\n```bash\n$ npm install agentkeepalive --save\n```\n\n## new Agent([options])\n\n* `options` {Object} Set of configurable options to set on the agent.\n  Can have the following fields:\n  * `keepAlive` {Boolean} Keep sockets around in a pool to be used by\n    other requests in the future. Default = `true`.\n  * `keepAliveMsecs` {Number} When using the keepAlive option, specifies the initial delay\n    for TCP Keep-Alive packets. Ignored when the keepAlive option is false or undefined. Defaults to 1000.\n    Default = `1000`.  Only relevant if `keepAlive` is set to `true`.\n  * `freeSocketTimeout`: {Number} Sets the free socket to timeout\n    after `freeSocketTimeout` milliseconds of inactivity on the free socket.\n    The default [server-side timeout](https://nodejs.org/api/http.html#serverkeepalivetimeout) is 5000 milliseconds, to [avoid ECONNRESET exceptions](https://medium.com/ssense-tech/reduce-networking-errors-in-nodejs-23b4eb9f2d83), we set the default value to `4000` milliseconds.\n    Only relevant if `keepAlive` is set to `true`.\n  * `timeout`: {Number} Sets the working socket to timeout\n    after `timeout` milliseconds of inactivity on the working socket.\n    Default is `freeSocketTimeout * 2` so long as that value is greater than or equal to 8 seconds, otherwise the default is 8 seconds.\n  * `maxSockets` {Number} Maximum number of sockets to allow per\n    host. Default = `Infinity`.\n  * `maxFreeSockets` {Number} Maximum number of sockets (per host) to leave open\n    in a free state. Only relevant if `keepAlive` is set to `true`.\n    Default = `256`.\n  * `socketActiveTTL` {Number} Sets the socket active time to live, even if it's in use.\n    If not set, the behaviour keeps the same (the socket will be released only when free)\n    Default = `null`.\n\n## Usage\n\n```js\nconst http = require('http');\nconst HttpAgent = require('agentkeepalive').HttpAgent;\n\nconst keepaliveAgent = new HttpAgent({\n  maxSockets: 100,\n  maxFreeSockets: 10,\n  timeout: 60000, // active socket keepalive for 60 seconds\n  freeSocketTimeout: 30000, // free socket keepalive for 30 seconds\n});\n\nconst options = {\n  host: 'cnodejs.org',\n  port: 80,\n  path: '/',\n  method: 'GET',\n  agent: keepaliveAgent,\n};\n\nconst req = http.request(options, res =\u003e {\n  console.log('STATUS: ' + res.statusCode);\n  console.log('HEADERS: ' + JSON.stringify(res.headers));\n  res.setEncoding('utf8');\n  res.on('data', function (chunk) {\n    console.log('BODY: ' + chunk);\n  });\n});\nreq.on('error', e =\u003e {\n  console.log('problem with request: ' + e.message);\n});\nreq.end();\n\nsetTimeout(() =\u003e {\n  if (keepaliveAgent.statusChanged) {\n    console.log('[%s] agent status changed: %j', Date(), keepaliveAgent.getCurrentStatus());\n  }\n}, 2000);\n\n```\n\n### `getter agent.statusChanged`\n\ncounters have change or not after last checkpoint.\n\n### `agent.getCurrentStatus()`\n\n`agent.getCurrentStatus()` will return a object to show the status of this agent:\n\n```js\n{\n  createSocketCount: 10,\n  closeSocketCount: 5,\n  timeoutSocketCount: 0,\n  requestCount: 5,\n  freeSockets: { 'localhost:57479:': 3 },\n  sockets: { 'localhost:57479:': 5 },\n  requests: {}\n}\n```\n\n### Support `https`\n\n```js\nconst https = require('https');\nconst HttpsAgent = require('agentkeepalive').HttpsAgent;\n\nconst keepaliveAgent = new HttpsAgent();\n// https://www.google.com/search?q=nodejs\u0026sugexp=chrome,mod=12\u0026sourceid=chrome\u0026ie=UTF-8\nconst options = {\n  host: 'www.google.com',\n  port: 443,\n  path: '/search?q=nodejs\u0026sugexp=chrome,mod=12\u0026sourceid=chrome\u0026ie=UTF-8',\n  method: 'GET',\n  agent: keepaliveAgent,\n};\n\nconst req = https.request(options, res =\u003e {\n  console.log('STATUS: ' + res.statusCode);\n  console.log('HEADERS: ' + JSON.stringify(res.headers));\n  res.setEncoding('utf8');\n  res.on('data', chunk =\u003e {\n    console.log('BODY: ' + chunk);\n  });\n});\n\nreq.on('error', e =\u003e {\n  console.log('problem with request: ' + e.message);\n});\nreq.end();\n\nsetTimeout(() =\u003e {\n  console.log('agent status: %j', keepaliveAgent.getCurrentStatus());\n}, 2000);\n```\n\n### Support `req.reusedSocket`\n\nThis agent implements the `req.reusedSocket` to determine whether a request is send through a reused socket.\n\nWhen server closes connection at unfortunate time ([keep-alive race](https://code-examples.net/en/q/28a8069)), the http client will throw a `ECONNRESET` error. Under this circumstance, `req.reusedSocket` is useful when we want to retry the request automatically.\n\n```js\nconst http = require('http');\nconst HttpAgent = require('agentkeepalive').HttpAgent;\nconst agent = new HttpAgent();\n\nconst req = http\n  .get('http://localhost:3000', { agent }, (res) =\u003e {\n    // ...\n  })\n  .on('error', (err) =\u003e {\n    if (req.reusedSocket \u0026\u0026 err.code === 'ECONNRESET') {\n      // retry the request or anything else...\n    }\n  })\n```\n\nThis behavior is consistent with Node.js core. But through `agentkeepalive`, you can use this feature in older Node.js version.\n\n## [Benchmark](https://github.com/node-modules/agentkeepalive/tree/master/benchmark)\n\nrun the benchmark:\n\n```bash\ncd benchmark\nsh start.sh\n```\n\nIntel(R) Core(TM)2 Duo CPU     P8600  @ 2.40GHz\n\nnode@v0.8.9\n\n50 maxSockets, 60 concurrent, 1000 requests per concurrent, 5ms delay\n\nKeep alive agent (30 seconds):\n\n```js\nTransactions:          60000 hits\nAvailability:         100.00 %\nElapsed time:          29.70 secs\nData transferred:        14.88 MB\nResponse time:            0.03 secs\nTransaction rate:      2020.20 trans/sec\nThroughput:           0.50 MB/sec\nConcurrency:           59.84\nSuccessful transactions:       60000\nFailed transactions:             0\nLongest transaction:          0.15\nShortest transaction:         0.01\n```\n\nNormal agent:\n\n```js\nTransactions:          60000 hits\nAvailability:         100.00 %\nElapsed time:          46.53 secs\nData transferred:        14.88 MB\nResponse time:            0.05 secs\nTransaction rate:      1289.49 trans/sec\nThroughput:           0.32 MB/sec\nConcurrency:           59.81\nSuccessful transactions:       60000\nFailed transactions:             0\nLongest transaction:          0.45\nShortest transaction:         0.00\n```\n\nSocket created:\n\n```bash\n[proxy.js:120000] keepalive, 50 created, 60000 requestFinished, 1200 req/socket, 0 requests, 0 sockets, 0 unusedSockets, 50 timeout\n{\" \u003c10ms\":662,\" \u003c15ms\":17825,\" \u003c20ms\":20552,\" \u003c30ms\":17646,\" \u003c40ms\":2315,\" \u003c50ms\":567,\" \u003c100ms\":377,\" \u003c150ms\":56,\" \u003c200ms\":0,\" \u003e=200ms+\":0}\n----------------------------------------------------------------\n[proxy.js:120000] normal   , 53866 created, 84260 requestFinished, 1.56 req/socket, 0 requests, 0 sockets\n{\" \u003c10ms\":75,\" \u003c15ms\":1112,\" \u003c20ms\":10947,\" \u003c30ms\":32130,\" \u003c40ms\":8228,\" \u003c50ms\":3002,\" \u003c100ms\":4274,\" \u003c150ms\":181,\" \u003c200ms\":18,\" \u003e=200ms+\":33}\n```\n\n## License\n\n[MIT](LICENSE)\n\n\u003c!-- GITCONTRIBUTOR_START --\u003e\n\n## Contributors\n\n|[\u003cimg src=\"https://avatars.githubusercontent.com/u/156269?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003efengmk2\u003c/b\u003e\u003c/sub\u003e](https://github.com/fengmk2)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/985607?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003edead-horse\u003c/b\u003e\u003c/sub\u003e](https://github.com/dead-horse)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/5557458?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003eAndrewLeedham\u003c/b\u003e\u003c/sub\u003e](https://github.com/AndrewLeedham)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/5243774?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003engot\u003c/b\u003e\u003c/sub\u003e](https://github.com/ngot)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/25919630?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003ewrynearson\u003c/b\u003e\u003c/sub\u003e](https://github.com/wrynearson)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/26738844?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003eaaronArinder\u003c/b\u003e\u003c/sub\u003e](https://github.com/aaronArinder)\u003cbr/\u003e|\n| :---: | :---: | :---: | :---: | :---: | :---: |\n|[\u003cimg src=\"https://avatars.githubusercontent.com/u/10976983?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003ealexpenev-s\u003c/b\u003e\u003c/sub\u003e](https://github.com/alexpenev-s)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/959726?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003eblemoine\u003c/b\u003e\u003c/sub\u003e](https://github.com/blemoine)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/398027?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003ebdehamer\u003c/b\u003e\u003c/sub\u003e](https://github.com/bdehamer)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/4985201?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003eDylanPiercey\u003c/b\u003e\u003c/sub\u003e](https://github.com/DylanPiercey)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/3770250?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003ecixel\u003c/b\u003e\u003c/sub\u003e](https://github.com/cixel)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/2883231?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003eHerringtonDarkholme\u003c/b\u003e\u003c/sub\u003e](https://github.com/HerringtonDarkholme)\u003cbr/\u003e|\n|[\u003cimg src=\"https://avatars.githubusercontent.com/u/1433247?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003edenghongcai\u003c/b\u003e\u003c/sub\u003e](https://github.com/denghongcai)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/1847934?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003ekibertoad\u003c/b\u003e\u003c/sub\u003e](https://github.com/kibertoad)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/5236150?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003epangorgo\u003c/b\u003e\u003c/sub\u003e](https://github.com/pangorgo)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/588898?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003emattiash\u003c/b\u003e\u003c/sub\u003e](https://github.com/mattiash)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/182440?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003enabeelbukhari\u003c/b\u003e\u003c/sub\u003e](https://github.com/nabeelbukhari)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/1411117?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003epmalouin\u003c/b\u003e\u003c/sub\u003e](https://github.com/pmalouin)\u003cbr/\u003e|\n[\u003cimg src=\"https://avatars.githubusercontent.com/u/1404810?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003eSimenB\u003c/b\u003e\u003c/sub\u003e](https://github.com/SimenB)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/2630384?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003evinaybedre\u003c/b\u003e\u003c/sub\u003e](https://github.com/vinaybedre)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/10933333?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003estarkwang\u003c/b\u003e\u003c/sub\u003e](https://github.com/starkwang)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/6897780?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003ekillagu\u003c/b\u003e\u003c/sub\u003e](https://github.com/killagu)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/15345331?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003etony-gutierrez\u003c/b\u003e\u003c/sub\u003e](https://github.com/tony-gutierrez)\u003cbr/\u003e|[\u003cimg src=\"https://avatars.githubusercontent.com/u/5856440?v=4\" width=\"100px;\"/\u003e\u003cbr/\u003e\u003csub\u003e\u003cb\u003ewhxaxes\u003c/b\u003e\u003c/sub\u003e](https://github.com/whxaxes)\u003cbr/\u003e\n\nThis project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sat Aug 05 2023 02:36:31 GMT+0800`.\n\n\u003c!-- GITCONTRIBUTOR_END --\u003e\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnode-modules%2Fagentkeepalive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnode-modules%2Fagentkeepalive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnode-modules%2Fagentkeepalive/lists"}