PxShot is built entirely on Cloudflare's edge platform — Workers for logic, Browser Rendering for headless Chrome, D1 for the database, and R2 for storage. This architecture provides sub-second screenshot capture from 300+ edge locations worldwide. Here's how it all fits together.
Architecture Overview
Every screenshot request flows through this pipeline:
- Cloudflare Worker receives the request — Validates the API key, checks rate limits, and parses parameters
- Browser Rendering API — The Worker launches a headless Chromium instance via Cloudflare's Browser Rendering binding
- Page navigation and capture — The browser navigates to the target URL, waits for the page to finish loading, and takes a screenshot
- Image encoding — The screenshot is encoded in the requested format (PNG, JPEG, WebP, or PDF)
- Response delivery — The image is returned directly to the caller with appropriate caching headers
Why Cloudflare Workers?
- Zero cold starts — Workers start in under 5ms, no container boot time
- Global distribution — Code runs in 300+ cities worldwide
- Integrated Browser Rendering — Access headless Chrome as a Worker binding
- Built-in D1 database — SQL database at the edge for user data and API keys
- Cost efficiency — Pay per request, not for idle server time
Browser Rendering Binding
Cloudflare's Browser Rendering API provides a Puppeteer-compatible interface within Workers:
import puppeteer from '@cloudflare/puppeteer';
export default {
async fetch(request, env) {
const browser = await puppeteer.launch(env.BROWSER);
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
const screenshot = await page.screenshot({ type: 'png' });
await browser.close();
return new Response(screenshot, {
headers: { 'Content-Type': 'image/png' }
});
}
};
Database Layer: D1
User accounts, API keys, usage stats, and billing data are all stored in Cloudflare D1:
// Check API key and rate limits
const keyRow = await env.DB.prepare(
'SELECT user_id, plan, monthly_usage FROM api_keys WHERE key_hash = ?'
).bind(keyHash).first();
if (!keyRow) return errorResponse('Invalid API key', 401);
if (keyRow.monthly_usage >= planLimits[keyRow.plan]) {
return errorResponse('Monthly limit exceeded', 429);
}
Performance Characteristics
- Average screenshot time — 1.5–3 seconds (including page load)
- Worker startup — <5ms
- Global latency — Requests routed to the nearest edge location
- Concurrent capacity — Scales automatically with demand
Challenges and Solutions
Browser session management
Each screenshot uses a fresh browser context to ensure isolation. This prevents state leakage between requests but requires efficient session lifecycle management.
Timeout handling
Some pages load slowly or hang indefinitely. PxShot enforces a maximum navigation timeout and falls back to capturing whatever has loaded so far.
Resource limits
Cloudflare Workers have CPU time limits. Complex pages that trigger heavy JavaScript execution need careful timeout management.
Why This Architecture Wins
Traditional screenshot services run centralized servers in one or two regions. PxShot's edge-native architecture means:
- Lower latency for users worldwide
- No single point of failure
- Automatic scaling without provisioning
- Lower costs (no idle server time)
Want to see it in action? Try PxShot free or read the API docs.