16 days ago
Issue Summary
We're hitting browser launch failures with Puppeteer under moderate PDF generation load on a Railway Metal service (8 GB RAM, 8 vCPUs). Happens sporadically when multiple jobs are triggered close together.
Environment
Plan: Railway Metal
Specs: 8 GB RAM, 8 vCPUs
Use case: PDF generation from HTML via Puppeteer
Tech stack: Node.js, Express, Puppeteer
Concurrency control:
p-queue
with concurrency set to 2
Relevant Code Snippet
// Shared browser instance
let browserInstance;
async function getBrowser() {
if (!browserInstance) {
browserInstance = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
timeout: 60000,
});
}
return browserInstance;
}
// Queue with limited concurrency
const queue = new PQueue({ concurrency: 2 });
export function createDynamicPDF(text) {
return queue.add(() => generatePDF(text));
}
queue.on('idle', async () => {
if (browserInstance && queue.size === 0 && queue.pending === 0) {
await browserInstance.close();
browserInstance = null;
}
});
Each incoming request sends HTML, and the server generates and streams back a PDF.
Errors Observed
Error: Failed to launch the browser process!
pthread_create: Resource temporarily unavailable
Failed to connect to the bus: No such file or directory
read ECONNRESET
from WebSocket
What We Suspect
Thread or file descriptor limit being hit in the Metal environment
Chromium's internal parallelism possibly triggering container limits, even with conservative concurrency
What We’re Looking For
Any known resource/thread limits on Railway Metal that may affect Puppeteer/Chromium?
Any recommended flags or configs to make Puppeteer more stable in a constrained or containerized environment?
1 Replies
13 days ago
Can anyone help?