Backend: multer.memoryStorage holds 500 MB parts in RAM — concurrent uploads OOM the API #120

Closed
opened 2026-05-26 18:21:19 -04:00 by zgaetano · 1 comment
Owner

Fixed in 04ce096. services/mam-api/src/routes/upload.js now uses multer.diskStorage writing to UPLOAD_TMP_DIR (defaults to os.tmpdir()/df-uploads). /part and /simple stream the on-disk file to S3 with fs.createReadStream and unlink the tmp file in finally. Concurrent 500 MB uploads no longer hold their bytes in RAM.

Fixed in 04ce096. `services/mam-api/src/routes/upload.js` now uses `multer.diskStorage` writing to `UPLOAD_TMP_DIR` (defaults to `os.tmpdir()/df-uploads`). `/part` and `/simple` stream the on-disk file to S3 with `fs.createReadStream` and unlink the tmp file in `finally`. Concurrent 500 MB uploads no longer hold their bytes in RAM.
Author
Owner

Fix Plan — #120 multer.memoryStorage OOM on concurrent uploads

Root cause: upload.js and assets.js use multer.memoryStorage() with 500MB cap. Each concurrent upload chunk lives in heap. 3 operators × 4GB files = ~12GB → OOM.

Fix — switch to disk storage + stream to S3:

// before:
multer({ storage: multer.memoryStorage(), limits: { fileSize: 500e6 } })

// after:
multer({
  storage: multer.diskStorage({ destination: "/tmp/uploads" }),
  limits: { fileSize: 500e6 }
})
// then stream file from disk to S3, unlink after success

Better: use @aws-sdk/lib-storage Upload class with createReadStream() for streaming multipart direct to S3.

Files: src/routes/upload.js, src/routes/assets.js
Effort: ~2h
**Priority: P1 — OOM risk

## Fix Plan — #120 multer.memoryStorage OOM on concurrent uploads **Root cause:** `upload.js` and `assets.js` use `multer.memoryStorage()` with 500MB cap. Each concurrent upload chunk lives in heap. 3 operators × 4GB files = ~12GB → OOM. **Fix — switch to disk storage + stream to S3:** ```js // before: multer({ storage: multer.memoryStorage(), limits: { fileSize: 500e6 } }) // after: multer({ storage: multer.diskStorage({ destination: "/tmp/uploads" }), limits: { fileSize: 500e6 } }) // then stream file from disk to S3, unlink after success ``` Better: use `@aws-sdk/lib-storage` `Upload` class with `createReadStream()` for streaming multipart direct to S3. **Files:** `src/routes/upload.js`, `src/routes/assets.js` **Effort:** ~2h **Priority: P1 — OOM risk
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: WildDragonLLC/dragonflight#120
No description provided.