Skip to content
Screenshot API · Use case

Serve high-volume screenshots through traffic spikes

High-volume screenshots rarely arrive at a steady rate. A product launch, a viral post or a Monday morning batch job multiplies demand in minutes, and a self-hosted browser pool has to be sized, and paid for, at that peak. The Screenshot API applies no throttling, serves repeats from a cache whose hits do not count against your quota, and spends your plan only on fresh captures.

The problem

Screenshot traffic spikes are when self-hosted browsers fail

Headless Chrome is memory hungry and slow to start. A pool sized for average load queues or times out when ten times the traffic arrives, so captures fail exactly when the most people are looking. A pool sized for the peak sits idle, and billed, for the rest of the month.

The usual workarounds move the problem instead of removing it. A job queue protects the browsers but turns a burst into minutes of latency. Adding containers on demand helps only if new browsers boot faster than the spike grows, and a rate limiter in front of everything drops the requests you cared about.

Microlink applies no throttling limitation: you can run as many parallel requests as your quota allows. Every response is cached for 24 hours by default, a repeat of the same request is a cache hit that does not count against your quota, and each fresh capture runs in its own isolated browser. Every paid plan adds a 99.9% uptime SLA, so a burst hits the cache first and a managed browser fleet second.

How it works

How to serve high-volume screenshots during a spike

Three request options turn a spiky workload into a predictable one, and none of them needs infrastructure on your side. The screenshot caching and performance guide covers the same setup in more depth.

1 · Serve repeats from the cache
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const { url } = await microlink.screenshot('https://example.com', {
  ttl: '1d',
  staleTtl: 0
})

ttl keeps the capture for a day, and staleTtl at 0 serves the cached copy instantly while a fresh one is generated in the background. The result is the usual asset object with url, width, height and size.

2 · Fire fresh captures in parallel
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const targets = ['https://a.com', 'https://b.com', 'https://c.com']

const screenshots = await Promise.all(
  targets.map(target => microlink.screenshot(target, { retry: 3 }))
)

No per-second limiter sits in front of the API, so Promise.all over a list of targets is fine and only your quota bounds it. retry raises the server-side retries with exponential backoff from the default of 2 to 3.

3 · The same request as a URL
curl 'https://pro.microlink.io/?url=https%3A%2F%2Fexample.com&screenshot=true&meta=false&ttl=1d&staleTtl=0' \
  -H 'x-api-key: $MICROLINK_API_KEY'

ttl and staleTtl need a Pro key, so the URL targets pro.microlink.io and carries the x-api-key header. Read x-cache-status in the response: MISS on the first call, HIT on every repeat.

Parameters used
  • ttl Cache lifetime from 1 minute to 31 days, including the min and max aliases. Pro plans; the default is 24 hours everywhere.
  • staleTtl Serves the cached response immediately while revalidating in the background. Cannot exceed ttl. Pro plans.
  • retry Server-side retries with exponential backoff on unexpected browser errors. Default 2.
  • meta false skips metadata extraction, usually the biggest single speedup for screenshot-only requests.
  • cacheKey Appends a custom identifier to the cache key to keep separate entries per tenant or variant. Pro plans.

Log x-cache-status, x-response-time and x-rate-limit-remaining from the response headers to see how much of a burst the cache absorbed and how much quota is left. The production patterns guide lists every header worth watching.

Why it works

Why a managed API survives screenshot traffic spikes

Bursty traffic is a capacity problem, and capacity is exactly what a managed browser service pools across every customer. Three properties do the work.

01 · No throttling
Parallel requests are bounded by your quota, not by a rate limiter.
The API applies no per-second throttling. A burst of a thousand captures is a thousand requests against your quota, processed as they arrive, with no queue for you to drain afterwards.

When the quota runs out you get HTTP 429 with the ERATE error code, plus x-rate-limit-remaining and x-rate-limit-reset headers, so back-pressure is explicit instead of a silent slowdown.

02 · Cache absorbs repeats
The same URL is captured once and served many times.
A launch drives thousands of views of the same handful of pages. With the 24-hour default cache, or up to 31 days with ttl on Pro, those views become cache hits served from the nearest CDN edge node. Cache hits do not count against your quota, so a spike costs you the unique captures and nothing else.

staleTtl at 0 is the caching default worth copying: visitors always get an instant response while the copy refreshes behind them. The same pattern keeps dynamic Open Graph images fast when a link goes viral.

03 · Availability you can quote
99.9% uptime SLA on every paid plan, one browser per request.
Every request runs in its own isolated browser instance, so a slow or broken target never affects another capture. Every paid plan commits to 99.9% uptime, a figure you can plan a launch around.

When not to: a steady trickle of a few captures per day fits the free tier of 25 requests per day, and a one-off batch of up to 25 URLs is quicker with the bulk screenshot tool. The API pays off when demand moves faster than you can provision.

FAQ

Does the screenshot API rate limit requests per second?

No. Microlink applies no throttling limitation, so you can run as many parallel screenshot requests as your quota allows. The free endpoint has a soft limit of 25 requests per day and paid plans use a monthly quota, both described in the rate limit docs.

What happens when a screenshot spike exceeds my quota?

The API returns HTTP 429 with the ERATE error code instead of slowing down silently. The x-rate-limit-remaining and x-rate-limit-reset headers tell you how much is left and when the window resets, so you can queue the remaining captures instead of dropping them.

Do cached screenshots count against my quota?

No. Cache hits do not count against your quota. A repeat of the same request within the cache lifetime is served from the edge with x-cache-status: HIT, and only fresh captures consume a request.

How do I keep high-volume screenshots fresh without re-rendering on every hit?

Set ttl to how often the page changes and staleTtl to 0, both Pro options. Requests are served from the cache instantly while a background refresh keeps the copy current, and force: true bypasses the cache when you need a one-off refresh.

Can I get dedicated capacity for screenshot workloads?

Yes. Enterprise plans include a dedicated endpoint and browser pool, plus dedicated storage and CDN. See the enterprise page and share your expected peak so the capacity matches it.
Related use cases

Solve the next problem with the same API

Faster, smaller screenshots

Skip metadata, pick JPEG quality and pixel density, and wait for a selector instead of a timer to cut time and bytes.

Dynamic Open Graph images

Point og:image at an API URL and every share shows a current, cached screenshot of the page.

Screenshot blocked websites

When a site blocks headless browsers, one option routes the capture through a managed, rotating proxy pool.

PDFs in bulk

Render thousands of documents from URLs in one job: parallel requests, server-side retries and per-document caching.

Bulk Markdown conversion with caching

Convert thousands of URLs in parallel, cached per URL and refreshed in the background for cheap re-indexing.

Link previews at scale

Unfurl links at any volume: no throttling, background refresh and cache hits that never count against your quota.

Ready for unpredictable traffic?

No browsers to size, no queues to babysit. Start on the free tier with 25 requests per day, then pick a paid plan matched to your monthly volume.