Generate thousands of PDFs from URLs without running browsers
Bulk PDF generation usually arrives as a deadline: month-end statements, event certificates, a report per customer, a catalog per region. Running a headless browser fleet for one night a month is expensive and fragile. The PDF API takes the batch as parallel requests and returns a hosted document for each URL.
Bulk PDF generation breaks self-hosted browser pools
Ten thousand renders in an hour needs dozens of Chrome instances, memory to match, and a queue that survives crashes. One page with a runaway script stalls a worker, a leaked tab eats the instance, and the job that was meant to finish overnight is still running when customers log in.
Most teams build that pool once, watch it fail at the next peak, and rebuild it with more capacity that idles the rest of the month. PDF libraries that skip the browser avoid the fleet, and also skip the CSS, the fonts and the charts that made the page worth printing.
Microlink applies no throttling, so the batch runs as fast as your quota allows, in parallel. Each render gets its own isolated browser and a 60-second budget on Pro plans, transient failures are retried server-side with retry, and documents you request again are served from the cache.
How to generate PDFs in bulk from a list of URLs
The batch is a map over URLs. Concurrency, retries and caching are request options, not infrastructure. The production patterns guide covers rate-limit headers and backoff for long jobs.
import createClient from 'microlink.io'
const microlink = createClient({
apiKey: process.env.MICROLINK_API_KEY
})
const customers = await loadCustomers()
const documents = await Promise.all(
customers.map(({ id }) =>
microlink.pdf(`https://app.example.com/statements/${id}`, {
headers: {
'x-api-header-authorization': `Bearer ${process.env.APP_TOKEN}`
},
filename: `statement-${id}.pdf`,
retry: 3
})
)
)One request per document. The bearer token travels as a forwarded header, filename makes the output self-describing, and retry: 3 re-runs intermittent browser errors with exponential backoff. Each result carries the hosted url and the file size.
import createClient from 'microlink.io'
const microlink = createClient({
apiKey: process.env.MICROLINK_API_KEY
})
const pool = async (items, limit, worker) => {
const results = []
let cursor = 0
const run = async () => {
while (cursor < items.length) {
const index = cursor++
results[index] = await worker(items[index]).catch(error => ({ error }))
}
}
await Promise.all(Array.from({ length: limit }, run))
return results
}
const documents = await pool(urls, 20, url => microlink.pdf(url, { ttl: '7d' }))Microlink does not throttle, but a bounded pool keeps your own memory and the target site comfortable. Catching per document means one failed render is logged and requeued instead of rejecting the whole batch.
curl 'https://pro.microlink.io/?url=https%3A%2F%2Fapp.example.com%2Fstatements%2F42&pdf=true&meta=false&retry=3&ttl=7d' \
-H 'x-api-key: $MICROLINK_API_KEY'Every option is a query parameter, so any language with an HTTP client can drive the batch. For a one-off list, the bulk website to PDF converter does the same from the browser.
- retry Server-side retries with exponential backoff on unexpected browser errors. Default 2.
- ttl Keeps each response cached from 1 minute to 31 days while the batch is consumed. Default 24 hours. Pro plans.
- cacheKey Separate cache entries for the same URL rendered per tenant or per run. Pro plans.
- meta Set to false to skip metadata extraction on every render, the biggest single speedup.
- filename Names each document so the batch output is self-describing. Pro plans.
- timeout Per-request budget: 30 seconds on the free endpoint, 60 seconds on Pro.
Watch for EPDFTOOLARGE on very long documents and EPAGERANGE on invalid page ranges; both are per-request error codes that should not stop the batch. The PDF caching and performance guide lists the settings that shave seconds off each render.
Why a managed PDF API fits batch generation
Batches are peaks by definition. Capacity that exists only when you need it is the whole point.
Size the plan to the batch on the pricing page; every paid plan carries a 99.9% SLA, and Enterprise adds a dedicated endpoint and browser pool.
The isolation feature describes the sandbox each request gets. Log x-request-id from each response; it is the handle for support when a specific document misbehaves.
When not to: a handful of documents a day does not need a batch pattern; a single request per document as the need arises is simpler and fits the free tier. For text pipelines, bulk Markdown conversion is the lighter output.
FAQ
How many PDFs can I generate in parallel?
What is the time limit for each PDF in a batch?
How do I handle failures inside a bulk PDF job?
Are the generated PDFs stored for me after the batch?
Do repeated PDF requests for the same URL use up my quota?
Solve the next problem with the same API
PDF invoices from authenticated pages
PDFs of JavaScript-rendered pages
PDF download links and previews
Archive web articles as PDF
Screenshots under traffic spikes
Bulk Markdown conversion with caching
Ready to render PDFs in bulk?
No browser fleet, no queue to babysit. Pick a Pro plan sized for your batch and generate your first thousand documents tonight.