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
- Set Reasonable Timeouts: Don't poll indefinitely
- Implement Retry Logic: Handle temporary failures
- Use Exponential Backoff: Avoid hammering the server
- Store Job Information: Track generation status in your database
- Handle Failures Gracefully: Notify users when generation fails