1"use strict";(globalThis.webpackChunk=globalThis.webpackChunk||[]).push([[9027],{29906(e,n,o){o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"other-topics/connection-pool","title":"Connection Pool","description":"Sequelize uses a connection pool,","source":"@site/docs/other-topics/connection-pool.md","sourceDirName":"other-topics","slug":"/other-topics/connection-pool","permalink":"/docs/v7/other-topics/connection-pool","draft":false,"unlisted":false,"editUrl":"https://github.com/sequelize/website/tree/main/docs/other-topics/connection-pool.md","tags":[],"version":"current","lastUpdatedBy":"renovate[bot]","lastUpdatedAt":1775795365000,"frontMatter":{"title":"Connection Pool"},"sidebar":"tutorialSidebar","previous":{"title":"Using sequelize in AWS Lambda","permalink":"/docs/v7/other-topics/aws-lambda"},"next":{"title":"Dialect-Specific Features","permalink":"/docs/v7/other-topics/dialect-specific-things"}}');var t=o(74848),s=o(28453);const r={title:"Connection Pool"},a=void 0,c={},l=[{value:"Pool Configuration",id:"pool-configuration",level:2},{value:"Pool Monitoring",id:"pool-monitoring",level:2},{value:"<code>ConnectionAcquireTimeoutError</code>",id:"connectionacquiretimeouterror",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",em:"em",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["Sequelize uses a connection pool,\npowered by ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/sequelize-pool",children:"sequelize-pool"}),", to manage connections to the database.\nThis provides better performance than creating a new connection for every query."]}),"\n",(0,t.jsx)(n.h2,{id:"pool-configuration",children:"Pool Configuration"}),"\n",(0,t.jsxs)(n.p,{children:["This connection pool can be configured through the constructor's ",(0,t.jsx)(n.a,{href:"pathname:///api/v7/interfaces/_sequelize_core.index.PoolOptions.html",children:(0,t.jsx)(n.code,{children:"pool"})})," option:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"const sequelize = new Sequelize({\n // ...\n pool: {\n max: 5,\n min: 0,\n acquire: 30000,\n idle: 10000,\n },\n});\n"})}),"\n",(0,t.jsxs)(n.p,{children:["By default, the pool has a maximum size of 5 active connections.\nDepending on your scale, you may need to adjust this value to avoid running out of connections by setting the ",(0,t.jsx)(n.code,{children:"max"})," option."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"When increasing the connection pool size,\nkeep in mind that your database server has a maximum number of allowed active connections."}),(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"max"})," option should be set to a value that is less than the limit imposed by your database server."]}),(0,t.jsxs)(n.p,{children:["Keep in mind that the connection pool is ",(0,t.jsx)(n.em,{children:"not shared"})," between Sequelize instances.\nIf your application uses multiple Sequelize instances, is running on multiple processes, or other applications are connecting\nto the same database, make sure to reserve enough connections for each instance."]}),(0,t.jsxs)(n.p,{children:["For instance, if your database server has a maximum of 100 connections, and your application is running on 2 processes,\nyou should set the ",(0,t.jsx)(n.code,{children:"max"})," option to 45; reserving 10 connections for other uses, such as database migrations, monitoring, etc."]})]}),"\n",(0,t.jsx)(n.h2,{id:"pool-monitoring",children:"Pool Monitoring"}),"\n",(0,t.jsx)(n.p,{children:"Sequelize exposes a number of properties that can be used to monitor the state of the connection pool."}),"\n",(0,t.jsxs)(n.p,{children:["You can access these properties via ",(0,t.jsx)(n.a,{href:"pathname:///api/v7/classes/_sequelize_core.index.unknown.ReplicationPool.html#write",children:(0,t.jsx)(n.code,{children:"sequelize.connectionManager.pool.write"})})," and\n",(0,t.jsx)(n.a,{href:"pathname:///api/v7/classes/_sequelize_core.index.unknown.ReplicationPool.html#read",children:(0,t.jsx)(n.code,{children:"sequelize.connectionManager.pool.read"})})," (if you use ",(0,t.jsx)(n.a,{href:"/docs/v7/other-topics/read-replication",children:"read replication"}),")."]}),"\n",(0,t.jsx)(n.p,{children:"These pools expose the following properties:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"size"}),": how many connections are currently in the pool (both in use and available)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"available"}),": how many connections are currently available for use in the pool"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"using"}),": how many connections are currently in use in the pool"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"waiting"}),": how many requests are currently waiting for a connection to become available"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["You can also monitor how long it takes\nto acquire a connection from the pool\nby listening to the ",(0,t.jsx)(n.code,{children:"beforePoolAcquire"})," and ",(0,t.jsx)(n.code,{children:"afterPoolAcquire"})," ",(0,t.jsx)(n.a,{href:"/docs/v7/other-topics/hooks#instance-sequelize-hooks",children:"sequelize hooks"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"const acquireAttempts = new WeakMap();\n\nsequelize.hooks.addListener('beforePoolAcquire', options => {\n acquireAttempts.set(options, Date.now());\n});\n\nsequelize.hooks.addListener('afterPoolAcquire', _connection, options => {\n const elapsedTime = Date.now() - acquireAttempts.get(options);\n console.log(`Connection acquired in ${elapsedTime}ms`);\n});\n"})}),"\n",(0,t.jsx)(n.h2,{id:"connectionacquiretimeouterror",children:(0,t.jsx)(n.code,{children:"ConnectionAcquireTimeoutError"})}),"\n",(0,t.jsxs)(n.p,{children:["If you start seeing this error,\nit means that Sequelize was unable to acquire a connection from the pool within the configured ",(0,t.jsx)(n.code,{children:"acquire"})," timeout."]}),"\n",(0,t.jsx)(n.p,{children:"This can happen for a number of reasons, including:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Your server is doing too many concurrent requests, and the pool is unable to keep up. It may be necessary to increase the ",(0,t.jsx)(n.code,{children:"max"})," option."]}),"\n",(0,t.jsx)(n.li,{children:"Some of your queries are taking too long to execute, and requests are piling up. Monitor your database server to see if there are any slow queries, and optimize them."}),"\n",(0,t.jsxs)(n.li,{children:["You have idle transactions that are not being committed or rolled back.",(0,t.jsx)(n.br,{}),"\n","This can happen if you use ",(0,t.jsx)(n.a,{href:"/docs/v7/querying/transactions#unmanaged-transactions",children:"unmanaged transactions"}),".\nMake sure you are committing or rolling back your unmanaged transactions properly,\nor use ",(0,t.jsx)(n.a,{href:"/docs/v7/querying/transactions#managed-transactions-recommended",children:"managed transactions"})," instead.\nWe also recommend monitoring for connections that have been idle in transaction for a long time."]}),"\n",(0,t.jsxs)(n.li,{children:["You have other slow operations that are preventing your transactions from being committed in time.\nFor instance, if you are doing network requests inside a transaction,\nand there is a network slowdown, your transaction is going to stay open for longer than usual,\nand cause a cascade of issues.\nTo solve this, make sure to set ",(0,t.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static",children:"a t
1imeout"})," on relevant asynchronous operations."]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453(e,n,o){o.d(n,{R:()=>r,x:()=>a});var i=o(96540);const t={},s=i.createContext(t);function r(e){const n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.