Skip to content

Memory issue on the big amount of queries #2894

Closed
@avorozheev-mwb

Description

@avorozheev-mwb

I'm debugging a memory issue in my application, and noticed an interesting pattern in how pg-pool works, that leads to an increased memory consumption. This may be not the fault of the library, but more of how I use it, therefore any insights or advice would be helpful.

I've got a NodeJS application that uses Postgres integrated via node-postgres with a big traffic, therefore a significant amount of reads from the database. The consumption from the database happens via typeorm.

The configuration is quite simple:

  • connectionsLimit = 100
  • idleTimeout = 10 000 ms
  • replication with one master and one read replica

The fun begins when application is working in production - with the increase of load the amount of consumed memory significantly increases. When the load is stopped, memory gets released over a span of ~25 minutes.

I've taken a memory snapshot and uploaded it into the visualizing tool, which showed me that a big chunk of memory is occupied by the Postgres connection pool.

image

I've surfed around the pg-pool internals, and figured out the following:

  • when the database query is executed, the available connection tries to be obtained from the pool
  • if there is a free idle connection or the room to create a new one - query gets executed
  • otherwise the query gets added to _pendingQueue and is executed once the next occupied connection becomes idle

So in my case:

  • the application load is higher than the amount of available connections can handle
  • when the amount of pending queries grows bigger than {N} connections, _pendingQueue starts to grow
  • it keeps growing under the constant load, because the query arrival rate is higher than the release rate
  • on a long run it "eats" a significant amount of memory

The main questions at this point are:

  1. Am I doing something dramatically wrong here? What is the best pattern for handling huge database load?
  2. Is there a way to reduce the memory footprint used by pending queries?
  3. I suspect the best way out of this situation is scale the application when the pending queue grows too large. Is consuming waitingCount on an instance of the pool and making a decision based on it is a right thing to do?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions