Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

createImageSizes decodes the source once per image size, all at once, so one upload can take hundreds of MB

Open Beginner friendly
#18,531 0 comments 1 reaction 0 assignees View on GitHub

Maintainers usually reply within 1 day

@Kshot3000 is already working on this.

Since Oct 6, 2026.

  • #18534 by @Kshot3000 — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
node.js, typescript

Research direction

Read packages/payload/src/uploads/image-resizing/createImageSizes.ts and trace how imageSizes are processed, especially the concurrent Promise.all and the omit branch. Compare peak memory when sizes are built sequentially rather than concurrently. Done means uploads produce the configured sizes and the measured peak memory is reduced; verify with the reported 7000x7000 PNG reproduction.

Written by the indexing model from the issue text.

Description

area: core Bug Uploads
Describe the Bug

createImageSizes builds every configured image size at once (Promise.all over imageSizes). Each size pipeline decodes the whole source image, so one upload holds one full decoded copy per size at the same time. Peak memory is roughly sizes x width x height x channels.

A small file can therefore take hundreds of MB. A flat 7000x7000 PNG of ~320 KB with four imageSizes grows the process by ~600 MB. In a memory-limited container that is enough for the kernel to kill the process, and since the client retries, each retry takes down the next replica.

Measured on 3.90.1 (sharp 0.34.3), one payload.create on a collection with WebP imageSizes, peak RSS growth:

imageSizes growth
0 4 MB
1 138 MB
4 591 MB
4, sizes built one after another 162 MB

The code is unchanged in 3.90.2: packages/payload/src/uploads/image-resizing/createImageSizes.ts.

Link to the code that reproduces this issue

Not a public repo. Minimal config below.

Reproduction Steps
  1. Collection with upload.imageSizes of four WebP sizes, for example widths 1600, 1240, 960 and 690, with withoutEnlargement: true.
  2. Pass sharp in the config.
  3. Upload a 7000x7000 PNG with a flat background (a few hundred KB).
  4. Watch process RSS during the create: it grows by about four decoded copies of the image.

Building the sizes in sequence (for ... of in place of Promise.all(imageSizes.map(...)), with continue for the omit branch) brings the peak down to about one decoded copy.

Which area(s) are affected?

area: core, Uploads

Environment Info
payload: 3.90.1
sharp: 0.34.3
node: 24
Dominant language
TypeScript
Stars
45.5k
Forks
4.3k
Avg merge
1d 19h
Merged PRs (30d)
309

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

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.

More from payloadcms/payload

All issues in payloadcms/payload

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.