From 06071ea03581cc81b35d607cf4703df16b016bd7 Mon Sep 17 00:00:00 2001 From: Lucas Smith Date: Tue, 16 Dec 2025 11:34:30 +1100 Subject: [PATCH] fix: memory leak in PDF to images conversion (#2325) Add proper cleanup for PDF.js pages and loading task to prevent memory leaks when processing multiple PDF pages. Ensure page cleanup is called after each page is rendered and both PDF document and loading task are properly destroyed with error handling. --- packages/lib/server-only/ai/pdf-to-images.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/lib/server-only/ai/pdf-to-images.ts b/packages/lib/server-only/ai/pdf-to-images.ts index a52c281dd..ea8d8dccb 100644 --- a/packages/lib/server-only/ai/pdf-to-images.ts +++ b/packages/lib/server-only/ai/pdf-to-images.ts @@ -44,10 +44,12 @@ export type PdfToImagesOptions = { export const pdfToImages = async (pdfBytes: Uint8Array, options: PdfToImagesOptions = {}) => { const { scale = 2 } = options; - const pdf = await pdfjsLib.getDocument({ + const task = await pdfjsLib.getDocument({ data: pdfBytes, CanvasFactory: SkiaCanvasFactory, - }).promise; + }); + + const pdf = await task.promise; const images = await pMap( Array.from({ length: pdf.numPages }), @@ -68,18 +70,23 @@ export const pdfToImages = async (pdfBytes: Uint8Array, options: PdfToImagesOpti viewport, }).promise; - return { + const result = { pageNumber, image: await canvas.toBuffer('jpeg'), width: Math.floor(viewport.width), height: Math.floor(viewport.height), mimeType: 'image/jpeg', }; + + void page.cleanup(); + + return result; }, { concurrency: 10 }, ); - void pdf.destroy(); + void pdf.destroy().catch((e) => console.error(e)); + void task.destroy().catch((e) => console.error(e)); return images; };