Skip to content

Commit

Permalink
Limit sharp's concurrency (#53385)
Browse files Browse the repository at this point in the history
Sharp by default spawns #cpu_cores threads to process images which could lead to large memory consumption. This PR caps the `concurrency` value especially on dev.

Locally I see a small memory improvement (10~20 MB) from this, but it will mostly affect long-running servers.

Related: lovell/sharp#2607

Co-authored-by: Steven <229881+styfle@users.noreply.github.com>
  • Loading branch information
shuding and styfle authored Aug 11, 2023
1 parent 10cb740 commit 707b1e3
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions packages/next/src/server/image-optimizer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createHash } from 'crypto'
import { promises } from 'fs'
import { cpus } from 'os'
import type { IncomingMessage, ServerResponse } from 'http'
import { mediaType } from 'next/dist/compiled/@hapi/accept'
import chalk from 'next/dist/compiled/chalk'
Expand Down Expand Up @@ -43,15 +44,17 @@ const VECTOR_TYPES = [SVG]
const BLUR_IMG_SIZE = 8 // should match `next-image-loader`
const BLUR_QUALITY = 70 // should match `next-image-loader`

let sharp:
| ((
input?: string | Buffer,
options?: import('sharp').SharpOptions
) => import('sharp').Sharp)
| undefined
let sharp: typeof import('sharp') | undefined

try {
sharp = require(process.env.NEXT_SHARP_PATH || 'sharp')
if (sharp && sharp.concurrency() > 1) {
// Reducing concurrency should reduce the memory usage too.
// We more aggressively reduce in dev but also reduce in prod.
// https://sharp.pixelplumbing.com/api-utility#concurrency
const divisor = process.env.NODE_ENV === 'development' ? 4 : 2
sharp.concurrency(Math.floor(Math.max(cpus().length / divisor, 1)))
}
} catch (e) {
// Sharp not present on the server, Squoosh fallback will be used
}
Expand Down

0 comments on commit 707b1e3

Please sign in to comment.