payloadcms / payloadcms/payload

Excessive memory usage when using Payload CMS as a layout agnostic page builder

Open
#17,214 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

created-by: Contributor db: mongodb status: needs-triage v3
Dominant language
TypeScript
Stars
44.8k
Forks
4.2k
Avg merge
2d 21h
Merged PRs (30d)
53

Description

Describe the Bug

My company's Next.js functions surpassed the maximum memory size of a Vercel function (4GB), so adding one more block to the config makes every single route error, preventing us from adding new functionality without removing existing functionality.

I performed a heap snapshot of the server and found that an overwhelming majority of the memory is coming from 219,801 instances of Mongoose's Schema class.

We have pnpm patched Payload to memoize the block schemas to get us back to manageable memory usage, but we'd like to see this fixed upstream if possible.

Vercel observability showing the memory usage going from a plateau of over 4GB to one under 1GB in one sharp cliff

I am not as confident as I'd like to be in this fix outside of my own project at the moment since I am not as familiar with the inner workings of the DB adapter. I wanted to surface this for implementation by someone more familiar or for discussion before I tackle a fleshed out PR. Do you have thoughts on cache safety of these Schemas, or do you see an alternative root cause?


Reproduction

The reproduction is a contrived layout builder config which has a block tree that fans out wide.

This issue can be reproduced with any configuration with reused blocks and verified by Chrome DevTools attached to Node as well, the attached reproduction is mostly to show the explosive growth clearly.

Link to the code that reproduces this issue

https://github.com/evelynhathaway/payload/blob/evelyn/block-schema-memory-repro/test/_community/config.ts

Reproduction Steps
  1. Clone evelynhathaway/payload @ evelyn/block-schema-memory-repro
  2. Install packages
  3. Run node --expose-gc --import tsx test/_community/measure-schemas.ts
$ node --expose-gc --import tsx test/_community/measure-schemas.ts
================ Schema instance count ================
Total mongoose.Schema instances built by one init: 193,751

Schemas built per collection (live + _versions combined):
     55,351  pages
     27,677  sections
     27,677  landingPages
     27,677  marketingPages
     27,677  campaigns
     27,677  guides
          5  media
          2  users
          2  menu
          1  posts
          1  payload-kv
          1  payload-locked-documents
          1  payload-preferences
          1  payload-migrations
          1  globals

================ Process memory ================
  RSS:        2442.9 MiB
  Heap total: 2279.2 MiB
  Heap used:  1775.7 MiB
  1. Checkout evelyn/block-schema-memory-potential-fix for a potential fix (https://github.com/evelynhathaway/payload/commit/6920225c02870f5b7ac97e94d8e9ad801a6ef5e5) similar to our temporary workaround that caches the schemas
  2. Run node --expose-gc --import tsx test/_community/measure-schemas.ts
$ node --expose-gc --import tsx test/_community/measure-schemas.ts
================ Schema instance count ================
Total mongoose.Schema instances built by one init: 725

Schemas built per collection (live + _versions combined):
        625  pages
         17  sections
         17  landingPages
         17  marketingPages
         17  campaigns
         17  guides
          5  media
          2  users
          2  menu
          1  posts
          1  payload-kv
          1  payload-locked-documents
          1  payload-preferences
          1  payload-migrations
          1  globals

================ Process memory ================
  RSS:        358.9 MiB
  Heap total: 247.8 MiB
  Heap used:  83.0 MiB
Which area(s) are affected?

db: mongodb

Environment Info
Binaries:
  Node: 24.14.0
  npm: 11.9.0
  Yarn: N/A
  pnpm: 10.10.0
Relevant Packages:
  payload: 3.85.0 (note this was also replicated in the repo against the main branch with package.json 4.0.0-beta.0, see git tree of repro)
Operating System:
  Platform: linux
  Arch: x64
  Version: #58~22.04.1-Ubuntu SMP Thu May  7 22:16:53 UTC 2026
  Available memory (MB): 31743
  Available CPU cores: 8

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproduction at test/_community/config.ts and run test/_community/measure-schemas.ts using the documented Node command to establish the schema count and memory baseline. Compare the behavior with commit 6920225c02870f5b7ac97e94d8e9ad801a6ef5e5 and inspect how the database adapter builds schemas. Done means reused blocks no longer cause explosive Mongoose Schema growth while the reproduction remains functional.

Written by the indexing model from the issue text.

Assessment

Tech stack
mongodb, nextjs, node.js, typescript
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.