Skip to main content

Async Workflows

Best practices for asynchronous PDF generation workflows.

When to Use Async Generation

Use async generation when:

  • Generating large PDFs that may take more than 30 seconds
  • Bulk generating multiple PDFs
  • Generating PDFs in background jobs
  • Avoiding timeout issues

Workflow Patterns

Pattern 1: Fire and Forget

Generate PDF and send URL via webhook or email when complete.

async function generateAndNotify(params, email) {
// 1. Start async generation
const { url, fileId } = await generatePDFAsync(params);

// 2. Save job to database
await saveJob({
fileId,
url,
status: 'processing',
email
});

// 3. Poll status and notify when complete
pollAndNotify(fileId, url, email);

return { fileId, url };
}

Pattern 2: Polling with Progress

Poll generation status and show progress to user.

async function generateWithProgress(params, onProgress) {
const { url, fileId } = await generatePDFAsync(params);

// Poll every 2 seconds
const maxAttempts = 60;
for (let i = 0; i < maxAttempts; i++) {
await sleep(2000);

try {
const response = await axios.head(url);
if (response.status === 200) {
onProgress(100);
return { url, fileId };
}
} catch (error) {
onProgress((i / maxAttempts) * 100);
}
}

throw new Error('Generation timeout');
}

Pattern 3: Batch Processing

Process large batches in chunks.

async function processBatch(items, batchSize = 50) {
const chunks = chunkArray(items, batchSize);
const results = [];

for (const chunk of chunks) {
const chunkResults = await Promise.all(
chunk.map(item => generatePDFAsync(item))
);
results.push(...chunkResults);

// Rate limiting
await sleep(1000);
}

return results;
}

Best Practices

  1. Set Reasonable Timeouts: Don't poll indefinitely
  2. Implement Retry Logic: Handle temporary failures
  3. Use Exponential Backoff: Avoid hammering the server
  4. Store Job Information: Track generation status in your database
  5. Handle Failures Gracefully: Notify users when generation fails

Next Steps