Skip to content
Fixedmark
Integration · Serverless and edge functions

Vercel Static IP for Functions: Setup and Cost

Vercel Functions send traffic from a shared, changing pool of cloud IPs, so a partner cannot allowlist them. Vercel sells Static IPs for $100 per project per month on Pro and Enterprise, plus data transfer. Fixedmark routes the calls that need a fixed address through a proxy URL instead, so one dedicated IP pair can serve every project and every platform you deploy to.

Why Vercel's outbound IP changes

Vercel runs your functions on managed compute in the regions you select. Each invocation can land on a different instance, and those instances share a large pool of provider IP addresses with other Vercel customers. Vercel does not publish a fixed list of egress IPs for regular deployments, and the address your function used yesterday is not guaranteed today.

That is fine for public APIs. It breaks when the other side checks the source IP: a MongoDB Atlas access list, a bank payout API, a broker's order API, a customer's firewall, or GitHub Enterprise with IP allow lists. Allowlisting 0.0.0.0/0 defeats the point, and allowlisting a cloud provider's published ranges lets in everyone else on that cloud.

Vercel Static IPs: what it costs

Vercel's own answer is Static IPs. Per Vercel's docs, it is available on Pro and Enterprise plans and costs $100 per project per month, plus Private Data Transfer at regional rates of $0.15 to $0.31 per GB. Each configured region gets its own static IP pair, for up to 3 regions per project. The IPs come from a VPC shared by a small group of customers and cover outbound traffic only. Routing Middleware does not use them. Dedicated, isolated networking is Secure Compute, an Enterprise feature with custom pricing.

If you have one Vercel project on Pro and want zero client code, Static IPs is the simplest route and keeps billing in one place. It gets expensive when you have several projects that call the same partner, because the fee is per project, and it does not help the parts of your stack that run elsewhere.

Sources for Vercel pricing

Checked October 2026. Confirm current details on the vendor's site before you decide. Prices and limits change.

Set up a static IP on Vercel

You route only the requests that need a fixed IP. Everything else, including Vercel's own platform calls, stays direct.

Fixedmark is in early access. Proxy URLs are issued at launch. Join early access to get yours when your region opens.

Before you start

  • A Vercel project with at least one function on the Node.js, Python, or Go runtime. Any plan works, including Hobby.
  • A Fixedmark proxy URL (https://APP_ID:TOKEN@mum.egress.fixedmark.com:443) and the two IPs of your pair. Both are issued at launch. Join early access to get them.
  • The Vercel CLI (npm i -g vercel) if you want to set variables from the terminal.
  • Access to the partner's or database's allowlist, or a contact who can add two IPv4 addresses for you.

Steps

  1. 1
    Pick a region close to your function regionChoose the Fixedmark region nearest your Vercel function region (for example Mumbai for bom1, Frankfurt for fra1, Virginia for iad1). This keeps the extra hop short.
  2. 2
    Store the proxy URL as an environment variableRun vercel env add FIXEDMARK_PROXY_URL production and paste the URL when prompted. Repeat for preview if previews call the partner. Production and preview variables are sensitive by default, so the value is hidden after you save it. Redeploy so functions pick it up.
  3. 3
    Use the Node.js runtime for the calling functionThe Edge runtime's fetch cannot use a proxy. Any route handler, API route, or server action that calls an allowlisted API must run on the Node.js runtime, which is the default. Python and Go functions work as shown below.
  4. 4
    Pass the proxy to your HTTP clientIn Node.js, install undici, import fetch and ProxyAgent from it, and pass the agent as dispatcher. Create the agent at module scope so warm invocations reuse the connection.
  5. 5
    Verify, then allowlist both IPsRun the IP check below from a deployed function. When it prints a Fixedmark IP, send both IPs of your pair to the partner.
// npm install undici  (undici 8 needs Node.js 22.19+)
import { fetch, ProxyAgent } from "undici";

// FIXEDMARK_PROXY_URL=https://APP_ID:TOKEN@mum.egress.fixedmark.com:443
const proxy = new ProxyAgent(process.env.FIXEDMARK_PROXY_URL);

const res = await fetch("https://api.partner.example/v1/orders", {
  dispatcher: proxy,
  headers: { authorization: `Bearer ${process.env.PARTNER_API_KEY}` },
});
console.log(res.status, await res.json());

SDKs that do not use fetch (the Stripe and Salesforce Node SDKs, got, axios) accept an HTTP agent. Pass new HttpsProxyAgent(process.env.FIXEDMARK_PROXY_URL) from the https-proxy-agent package, which supports https:// proxy URLs. With axios, also set proxy: false so it does not apply its own proxy logic. undici 8 needs Node 22.19 or later. On older Node, install undici@7.

Verify the egress IP on Vercel

Check the IP before you send it to a partner. Run curl locally after vercel env pull to test the credentials. Then deploy a temporary route with the Node.js check to test the deployed code path. The endpoint https://fixedmark.com/api/ip returns the caller's IP as plain text, and the What's my IP tool shows the same thing in a browser.

The proxied call should print one of your two Fixedmark IPs every time. The direct call should print a different address. If both print the same platform IP, the client is not using the proxy.

# Needs curl 7.52 or later for an https:// proxy URL.
# Prints the IP the destination sees. Run it a few times:
# you should only ever see the two IPs of your pair.
curl -sS --proxy "$FIXEDMARK_PROXY_URL" https://fixedmark.com/api/ip

# Same check over SOCKS5, the path database drivers use.
curl -sS --proxy "$FIXEDMARK_SOCKS_URL" https://fixedmark.com/api/ip

# Without the proxy, for comparison. This is the platform's own IP.
curl -sS https://fixedmark.com/api/ip

Databases: Postgres, MySQL, and MongoDB

Vercel functions cannot run a background process, so the bm tunnel CLI is not an option there. Use a driver that can dial through SOCKS5 with FIXEDMARK_SOCKS_URL. The MongoDB Node.js driver supports this with its proxyHost, proxyPort, proxyUsername, and proxyPassword options (install the socks package next to it). Go's pgx accepts a SOCKS5 dialer through DialFunc.

node-postgres, mysql2, and psycopg have no SOCKS5 option. For those, move the queries into a small long-running service on a platform that can run bm tunnel, or use your database provider's HTTP API through the HTTPS proxy. Connection setup costs more with a proxy hop: open the client once per function instance, not per request.

// npm install mongodb socks
import { MongoClient } from "mongodb";

// FIXEDMARK_SOCKS_URL=socks5h://APP_ID:TOKEN@mum.egress.fixedmark.com:1080
const socks = new URL(process.env.FIXEDMARK_SOCKS_URL);

const client = new MongoClient(process.env.MONGODB_URI, {
  proxyHost: socks.hostname,
  proxyPort: Number(socks.port),
  proxyUsername: decodeURIComponent(socks.username),
  proxyPassword: decodeURIComponent(socks.password),
});
await client.connect();

Common errors and fixes

process.env.FIXEDMARK_PROXY_URL is undefined

Variables apply only to new deployments. Redeploy after adding it, and check it is set for the environment you are testing (production, preview, or development).

Works locally, fails in a route marked runtime = 'edge'

Edge functions cannot load undici or set a proxy. Remove the edge runtime export from that route.

407 Proxy Authentication Required

The proxy did not get valid credentials. Check that the env var holds the full URL with APP_ID:TOKEN@, with no quotes or trailing newline. If the token contains @, :, or /, URL-encode it. Some clients drop credentials from the URL: pass them separately (Deno's basicAuth, axios proxy.auth) or switch to undici's ProxyAgent, which reads them from the URL.

TLS errors to the proxy: wrong version number, EPROTO, Proxy CONNECT aborted, or unable to connect to proxy

The client does not support an https:// proxy URL and is speaking plain HTTP to port 443. Upgrade it: curl 7.52+, urllib3 1.26+ (requests), httpx 0.26+, undici ProxyAgent, Go 1.10+. In Ruby, use Typhoeus: Net::HTTP and Faraday's default adapter cannot tunnel HTTPS through a TLS proxy. For older axios releases, set proxy: false and pass https-proxy-agent as httpsAgent. Java's built-in HttpClient cannot speak TLS to a proxy at all. If you cannot upgrade, use the SOCKS5 URL.

ETIMEDOUT or ECONNRESET to the partner, or a 403 from the partner

The proxy connected, but the destination dropped you. Usually only one IP of the pair is on the allowlist, or the partner has not applied the change yet. Add both IPs. If a destination allowlist is set on your Fixedmark token, check the host and port are on it.

The IP check prints the platform's IP, not a Fixedmark IP

The request went direct. Node's built-in fetch ignores HTTPS_PROXY unless NODE_USE_ENV_PROXY=1 is set (Node 22.21+ and 24+). Many SDKs ignore proxy env vars too. Pass the proxy to the client explicitly, as in the snippets above.

429 or 407 with an X-Proxy-Error: quota_exceeded header

Planned behavior when you pass your plan's soft limit. Check usage in the dashboard or raise the plan.

Database driver has no proxy option

node-postgres, mysql2, psycopg, and most ORMs cannot use an HTTP proxy. Use a SOCKS5-capable driver with FIXEDMARK_SOCKS_URL, or run bm tunnel where the platform allows a second process.

Gotchas on Vercel

The proxy adds one network hop. Inside the same region it is typically a few milliseconds, but a function in iad1 calling through Mumbai crosses an ocean. Keep regions aligned.

  • Edge Middleware and Edge runtime functions cannot use the proxy.
  • Next.js data caching does not apply to fetch imported from undici. That is usually what you want for partner API calls.
  • Do not set NODE_USE_ENV_PROXY and HTTPS_PROXY project-wide. That would send every outbound call through the proxy, including calls that do not need it.
  • Image Optimization and other Vercel-managed fetches always use Vercel's own IPs.

Frequently asked questions

Does Vercel have static IPs?

Yes. Vercel Static IPs is available on Pro and Enterprise plans for $100 per project per month plus Private Data Transfer. Each region gets a static IP pair, up to 3 regions. Hobby projects have no native option.

How do I get a static IP on the Vercel Hobby plan?

Vercel's Static IPs feature is not available on Hobby. Route the calls that need a fixed address through a static IP proxy from a Node.js, Python, or Go function instead.

Can I use one Fixedmark IP pair for several Vercel projects?

Yes. The proxy URL is a credential, not a project setting. Store it in each project's environment variables and all of them leave through the same pair. Use separate tokens per project if you want separate connection logs.

Does this work with Next.js server actions and route handlers?

Yes, on the Node.js runtime. Import fetch and ProxyAgent from undici and pass the agent as the dispatcher option. It does not work on the Edge runtime, because Edge fetch has no proxy setting.

Will my HTTPS traffic be decrypted?

No. Your client opens an HTTP CONNECT tunnel and negotiates TLS with the destination through it. Fixedmark forwards encrypted bytes and logs only connection metadata such as destination host, bytes, and result.

Fix your egress IP.

Fixedmark is in early access. Join the list to get a dedicated IP pair for Vercel when your region opens.