lovell / lovell/sharp

OOM Crashes when Resizing Multiple Image Sizes to AVIF and WebP Formats

Open
#4,232 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
JavaScript
Stars
32.7k
Forks
1.4k
Avg merge
1d 14h
Merged PRs (30d)
5

Description

## Question about an existing feature

### What are you trying to achieve?

I’m using sharp to resize images into multiple formats, specifically AVIF and WebP. I’m running the application on Digital Ocean App Platform with 1GB RAM. When uploading images (around 1.5MB in size), it takes about 20 seconds to resize them into six different image sizes, but this process causes the app to crash and restart due to high memory usage.

A Digital Ocean representative confirmed that even a small number of image requests leads to memory exhaustion and app restarts. I'm using Next.js alongside Payload CMS (v3.0.0-beta.76). Although the repo link I provided and tested with on App Platform just uses express alongside sharp.

I suspect the memory spike is related to processing AVIF and WebP formats, but I’m unsure how to mitigate the issue with my current memory constraints.

Any insights or suggestions for optimizing memory usage or handling large image workloads in Sharp would be highly appreciated.

### When you searched for similar issues, what did you find that might be related?

I’ve seen similar issues regarding high memory usage when resizing to AVIF and WebP formats, but I haven’t found a specific solution or optimization recommendation for my case, where multiple sizes of these formats are being generated simultaneously.

### Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question

- [Repo Link](https://github.com/techswarn/expressjs-sharp-processimage) with sample images and additional context.
- [Discord Thread](https://discord.com/channels/967097582721572934/1271157489143910441/1271157489143910441) with the Payload Team

### Please provide sample image(s) that help explain this question

Under `/assets` in repo link.

Image Sizes:

```js
const imageSizes = [
// Original Size (for WebP & Avif)
{
name: "original_webp",
width: undefined,
height: undefined,
formatOptions: {
format: "webp",
options: {
quality: 80,
},
},
},
{
name: "original_avif",
width: undefined,
height: undefined,
formatOptions: {
format: "avif",
options: {
quality: 60,
effort: 1,
chromaSubsampling: "4:4:4",
bitdepth: 8,
lossless: false,
},
},
},
// Thumbnail Sizes
{
name: "thumbnail",
width: 200,
height: undefined,
position: "centre",
},
{
name: "thumbnail_webp",
width: 200,
height: undefined,
position: "centre",
formatOptions: {
format: "webp",
options: {
quality: 80,
},
},
},
{
name: "thumbnail_avif",
width: 200,
height: undefined,
position: "centre",
formatOptions: {
format: "avif",
options: {
quality: 60,
effort: 1,
chromaSubsampling: "4:4:4",
bitdepth: 8,
lossless: false,
},
},
},
// Mobile Sizes
{
name: "mobile",
width: 500,
height: undefined,
},
{
name: "mobile_webp",
width: 500,
height: undefined,
formatOptions: {
format: "webp",
options: {
quality: 80,
},
},
},
{
name: "mobile_avif",
width: 500,
height: undefined,
formatOptions: {
format: "avif",
options: {
quality: 60,
effort: 1,
chromaSubsampling: "4:4:4",
bitdepth: 8,
lossless: false,
},
},
},
// Tablet Sizes
{
name: "tablet",
width: 800,
height: undefined,
},
{
name: "tablet_webp",
width: 800,
height: undefined,
formatOptions: {
format: "webp",
options: {
quality: 80,
},
},
},
{
name: "tablet_avif",
width: 800,
height: undefined,
formatOptions: {
format: "avif",
options: {
quality: 60,
effort: 1,
chromaSubsampling: "4:4:4",
bitdepth: 8,
lossless: false,
},
},
},
// Desktop Sizes
{
name: "desktop",
width: 1200,
height: undefined,
},
{
name: "desktop_webp",
width: 1200,
height: undefined,
formatOptions: {
format: "webp",
options: {
quality: 80,
},
},
},
{
name: "desktop_avif",
width: 1200,
height: undefined,
formatOptions: {
format: "avif",
options: {
quality: 60,
effort: 1,
chromaSubsampling: "4:4:4",
bitdepth: 8,
lossless: false,
},
},
},
];

module.exports = imageSizes;
```

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 standalone expressjs-sharp-processimage repository and the sample images under its assets directory. Reproduce the six-size AVIF and WebP workload under the reported 1GB limit, then measure memory usage and determine whether the behavior is actionable in sharp or requires changes to the workload or deployment.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
backend, performance
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.