Comparison

Self-host vs managed CORS proxy: which one for which job?

corsproxy.dev ships in two shapes — an MIT-licensed Go binary you run yourself, and a hosted API we run for you. Same proxy core, different operational shape. Here's how to pick.

~7 min read

The two-line summary

For most "I just need to ship this prototype" situations, managed wins on time-to-first-request. For most production-scale or security-sensitive cases, self-host wins on long-term control.

What you give up either way

Both options use the same proxy semantics: GET/POST/PUT/DELETE/PATCH, the target URL as a query parameter, response headers sanitized, private-network targets refused. The behavioral surface is identical — what changes is who runs it and what's bolted on around it.

Self-hosted: what you get and what it costs

The OSS repo (github.com/melihbirim/corsproxy) ships a single Go binary, ~10 MB, no external dependencies, MIT licensed. Deploy with:

git clone https://github.com/melihbirim/corsproxy
cd corsproxy
go run main.go

One-click deploys exist for Railway, Render, Fly.io, and Koyeb. A $5/month box handles tens of millions of requests/month.

You get:

You take on:

Managed: what you get and what it costs

The hosted API at api.corsproxy.dev wraps the same proxy core in account management, rate limits, and a dashboard.

You get:

You take on:

The decision in four questions

  1. Is what I'm proxying sensitive enough that I want it inside my own perimeter? Yes → self-host. No → managed is fine.
  2. Will I have steady, predictable volume above a few thousand requests per day? Yes → self-host probably cheaper. No → managed.
  3. Do I want to build API keys, rate limits, and a usage dashboard myself? Yes → self-host. No → managed.
  4. Is "time to first proxied request" more important than long-term operational control? Yes → managed. No → either works; go with the one whose constraints match the rest of your team's habits.

Switching between them

The request format is identical, so swapping is one URL change in your client. Use environment variables and you can A/B test them side by side:

// Same client code; the only thing that changes is the base URL
// and the auth header (managed needs one; self-hosted doesn't).
const proxyBase = process.env.PROXY_URL ||
                  'https://api.corsproxy.dev';
const authHeader = process.env.PROXY_KEY
  ? { 'X-API-Key': process.env.PROXY_KEY }
  : {};

fetch(`${proxyBase}/proxy?url=${encodeURIComponent(targetUrl)}`, {
  headers: authHeader
});

Many teams start managed for prototypes, move to self-hosted when usage gets serious, then end up running both — managed for non-production environments where keys make per-engineer attribution easy, self-hosted for production hot paths.

Try either in five minutes

Hosted account on the Free tier: create an account. Self-host: clone the repo. Or both — they cohabit fine.