On this page
TL;DR: choose by platform gravity, then prove it with your traffic
Choose Cloudflare AI Gateway when edge policy, exact-match caching, per-request log controls, explicit rate or budget branches, and versioned dynamic routes are central to the design. Choose Vercel AI Gateway when the team values AI SDK integration, a unified creator/model catalog, automatic provider selection, Vercel OIDC, and app-platform observability. If neither advantage is material, keep an OpenAI-compatible adapter and decide with a seven-day shadow test—not a feature-count contest.
Traffic shaping, cache controls, request-level log behavior, and visual or JSON dynamic routes.
AI SDK, unified model access, automatic provider selection, OIDC, budgets, and app-adjacent observability.
One warm request says little about p95 latency, throttling, provider fallback, or regional behavior.
Keep gateway URLs, credentials, model aliases, routing policy, and log parsing outside business logic.
What this comparison must help you decide
People searching “Cloudflare vs Vercel AI Gateway” usually already understand the category. They need to know which gateway fits their stack, whether current APIs are compatible, how routing and caching actually behave, what gets logged, how costs are composed, and whether migration is reversible. Marketing summaries do not answer those questions; an executable decision contract does.
Who this guide is for and prerequisites
This guide is for teams moving from direct provider calls, standardizing several model vendors, or choosing a gateway for an AI application already deployed on Cloudflare or Vercel.
- One representative model and one fallback model with access confirmed on both candidates.
- A fixed prompt set containing short, long, streaming, tool-call, structured-output, and safety-sensitive cases.
- Server-side secrets, a request ID, tenant identity, timeout budget, and a redaction policy.
- Success thresholds for p95 latency, error rate, fallback rate, output validity, and cost per accepted response.
Decision matrix: when each gateway is the stronger default
| Your dominant requirement | Stronger starting point | Why | Prove before launch |
|---|---|---|---|
| Edge-first traffic policy | Cloudflare | Dynamic routes expose conditions, percentage splits, rate limits, budget limits, retries, and fallbacks as versioned flows. | Rule evaluation, route rollback, region-level p95 |
| Next.js / AI SDK workflow | Vercel | The gateway is designed around AI SDK plus OpenAI, Responses, and Anthropic-compatible access. | Local, preview, and production auth; streaming parity |
| Exact-match prompt caching | Cloudflare | Documented cache keys and per-request cache overrides make behavior explicit. | Key completeness, stale-answer risk, measured hit rate |
| Unified catalog and provider selection | Vercel | Creator/model IDs, a model endpoint, and automatic provider selection reduce application-side vendor wiring. | Model availability, provider allowlist, fallback trace |
| Per-request prompt log suppression | Cloudflare | Documented headers can disable the full log or retain metadata without payload bodies. | Inspect the resulting record; test retention and access |
| Avoid platform lock-in | Neutral adapter | Both expose OpenAI-compatible paths, but policies, model names, auth, and telemetry still differ. | Dual-run test and one-command rollback |
Architecture: keep gateway policy out of business logic
Normalize messages, tools, structured-output schema, streaming, timeout, tenant, and request ID.
Application code asks for fast, balanced, or reasoning; deployment configuration resolves the current gateway model ID.
Translate credentials, provider order, cache eligibility, log controls, retry budget, and gateway metadata.
Return output plus gateway, provider, model, request ID, timing, token usage, cache status, fallback path, and policy version.
Only count schema-valid, policy-compliant responses; raw HTTP success is not a successful business result.
Cloudflare vs Vercel AI Gateway: current capability comparison
| Area | Cloudflare AI Gateway | Vercel AI Gateway | Decision implication |
|---|---|---|---|
| Primary API | Cloudflare REST API and OpenAI-compatible chat/responses; provider-specific paths also exist | Unified endpoint for AI SDK, OpenAI Chat/Responses, Anthropic Messages, and other clients | Both can sit behind an adapter; do not assume identical extensions. |
| Routing | Versioned Dynamic Routes with condition, percentage, rate, budget, model, retry, and fallback nodes | Automatic provider selection plus request-level order/only policies, timeouts, and model fallback | Cloudflare exposes a flow; Vercel emphasizes model/provider policy inside the app workflow. |
| Caching | Exact-match text and image cache with documented key inputs and request overrides | Gateway/provider caching controls are available through provider options | Compare semantic safety and measured hit rate, not the checkbox. |
| Authentication | Cloudflare API token for REST; provider credentials, stored keys, or Unified Billing depend on path | AI Gateway API key everywhere; Vercel OIDC can be automatic on Vercel; team BYOK supported | Test local, CI, preview, and production separately. |
| Observability | Analytics and detailed logs with configurable payload collection; retention and export depend on plan | Gateway usage, events, budgets, and Vercel observability integrations | Build your own normalized event envelope for cross-gateway comparison. |
| Billing posture | Core gateway features documented as free; Unified Billing adds a credit fee; provider inference is passed through | Credit-based gateway billing and BYOK paths; current pricing should be verified at purchase time | Model cost is only one part of total cost. |
Cloudflare marks its old Universal Endpoint as deprecated. New implementations should use the OpenAI-compatible REST endpoint and Dynamic Routing. Existing Universal Endpoint integrations can continue to run, but do not copy that older array-based fallback format into a new architecture.
Step-by-step implementation with the same client contract
Start with the OpenAI client because both gateways document compatible chat completion paths. Discover and pin a model available in your account; model catalogs change, so the example intentionally uses an environment variable rather than a hard-coded “latest” model.
import OpenAI from "openai";
type Gateway = "cloudflare" | "vercel";
const profiles = {
cloudflare: {
apiKey: process.env.CLOUDFLARE_API_TOKEN!,
baseURL:
"https://api.cloudflare.com/client/v4/accounts/" +
process.env.CLOUDFLARE_ACCOUNT_ID + "/ai/v1",
model: process.env.CLOUDFLARE_MODEL_ID!,
},
vercel: {
apiKey: process.env.AI_GATEWAY_API_KEY!,
baseURL: "https://ai-gateway.vercel.sh/v1",
model: process.env.VERCEL_MODEL_ID!,
},
} satisfies Record<Gateway, {
apiKey: string; baseURL: string; model: string;
}>;
export async function runGateway(gateway: Gateway, prompt: string) {
const profile = profiles[gateway];
const client = new OpenAI({
apiKey: profile.apiKey,
baseURL: profile.baseURL,
timeout: 30_000,
maxRetries: 0, // own retries once; avoid retry multiplication
});
const started = performance.now();
const response = await client.chat.completions.create({
model: profile.model,
messages: [{ role: "user", content: prompt }],
temperature: 0,
});
return {
gateway,
model: response.model,
text: response.choices[0]?.message?.content ?? "",
usage: response.usage,
durationMs: Math.round(performance.now() - started),
};
}
For Cloudflare’s REST API, the account token authenticates the call and third-party models use author/model naming. Provider-specific Cloudflare endpoints use different credential/header patterns, so choose one path and document it. For Vercel, query the model catalog before pinning an ID.
curl "https://ai-gateway.vercel.sh/v1/models" \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json"
# Store the reviewed creator/model ID in VERCEL_MODEL_ID.
# Re-run discovery during planned model upgrades, not per request.
Routing and fallback: make failure semantics explicit
| Policy question | Required answer | Test |
|---|---|---|
| What triggers fallback? | Timeout, provider 5xx, 429, empty stream, invalid schema, or policy rejection are not equivalent. | Inject each failure separately. |
| Who owns retries? | Client, gateway, provider SDK, and job worker must not all retry independently. | Count upstream attempts per user request. |
| Is fallback output compatible? | Tool calls, JSON schema, safety behavior, context windows, and finish reasons can differ. | Validate output after every route branch. |
| Can you reconstruct the path? | Record requested alias, resolved model, provider, attempts, policy version, and terminal reason. | Trace a known forced fallback end to end. |
Set one end-to-end deadline and one maximum upstream-attempt budget. A 30-second request with three layers each retrying twice can create six or more billable attempts and still miss the user deadline.
Caching: optimize only requests that are semantically reusable
Cloudflare documents an exact-match cache key that includes provider, endpoint, model, provider authorization header, and full request body. That makes repeated deterministic calls a natural candidate, but identity, tool state, retrieval freshness, and authorization can make two text-identical prompts semantically different.
- Cache classification, extraction, and static transformations when inputs are complete and deterministic.
- Do not cache user-private conversations, permission-dependent answers, live balances, or tool results without an explicit identity and freshness key.
- Measure accepted-answer cache hit rate, not raw cache hit rate.
- Define bypass and purge procedures before enabling cache in production.
Logging, privacy, and observability controls
Cloudflare logging is enabled by default and can include prompts and model responses. Its current docs specify cf-aig-collect-log: false to skip the log and cf-aig-collect-log-payload: false to keep metadata without request and response bodies. Treat these as implementation controls, not a complete privacy program.
Mark public, internal, confidential, regulated, and prohibited payloads before choosing log behavior.
Remove tokens, credentials, session cookies, unnecessary PII, and retrieved secrets before the gateway.
Use your own request ID and event schema so dashboards survive a gateway switch.
Send a canary marker, inspect logs and exports, then prove deletion, retention, and role access.
A same-workload validation plan
Run both gateways against the same accepted-answer contract. Use at least three regions, cold and warm periods, streaming and non-streaming requests, concurrency ramps, and forced provider failures. Keep the model and provider fixed for baseline latency; test routing policy separately.
| Metric | How to measure | Why it matters |
|---|---|---|
| TTFT p50 / p95 / p99 | Time from request start to first streamed content token | Perceived responsiveness |
| Accepted success rate | Schema-valid and policy-compliant results divided by user requests | Excludes empty or malformed 200 responses |
| Fallback recovery | Accepted fallback results divided by injected primary failures | Tests real resilience, not configured resilience |
| Cost per accepted response | All model, retry, gateway, logging, and egress costs divided by accepted results | Captures retry and quality waste |
| Trace completeness | Requests with gateway, provider, model, attempt, tokens, timing, and terminal reason | Determines incident diagnosability |
type Run = {
ok: boolean;
schemaValid: boolean;
policyAllowed: boolean;
durationMs: number;
attempts: number;
costUsd?: number;
};
export function summarize(runs: Run[]) {
const accepted = runs.filter(
(r) => r.ok && r.schemaValid && r.policyAllowed
);
return {
requests: runs.length,
acceptedRate: accepted.length / runs.length,
retryAmplification:
runs.reduce((n, r) => n + r.attempts, 0) / runs.length,
costPerAccepted:
runs.reduce((n, r) => n + (r.costUsd ?? 0), 0) /
Math.max(accepted.length, 1),
};
}
Cost model: compare total accepted-output cost
Gateway pricing changes, so verify the current plan pages before purchase. The durable comparison is an equation: provider inference + gateway or credit fees + retries and fallbacks + log storage/export + application compute + engineering operations, divided by accepted business results.
Cloudflare currently documents core analytics, caching, and rate limiting as available without a gateway charge, with plan-based log limits; Unified Billing applies a credit fee while provider inference is passed through without markup. Confirm the current table and your Workers plan.
Common failure modes and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Cloudflare returns 401 | Account token and provider credential placed in the wrong header, or endpoint styles mixed | Use the documented auth pattern for the chosen REST or provider-specific path |
| Fallback multiplies cost | Client retries plus gateway retries plus worker retries | Centralize retry ownership and cap upstream attempts |
| Cached answer leaks context | Tenant, permissions, retrieval version, or tool state omitted from eligibility | Disable cache by default; allow only classified deterministic workloads |
| 200 response breaks the app | Fallback model returned incompatible JSON or tool-call shape | Validate every output branch and count invalid output as failure |
| Benchmark winner reverses in production | Warm single-region tests ignored concurrency, throttling, and provider selection | Run regional p95/p99 tests and a controlled traffic ramp |
Migration and rollback plan
List SDKs, endpoints, models, tools, streaming, credentials, retries, timeouts, and log destinations.
Move base URL, auth, model aliases, and gateway extensions into configuration.
Use redacted production-shaped prompts and compare output validity, not exact wording.
Mirror eligible requests, then ramp 1% → 5% → 25% → 50% → 100% only when thresholds hold.
A single config flag should restore the previous profile without code deployment or data migration.
- Rollback if accepted success rate drops, p95 exceeds budget, retry amplification rises, or trace completeness falls.
- Keep old credentials and dashboards active through the observation window.
- Freeze routing policy during benchmark runs; otherwise you are comparing changing systems.
Where QVeris fits: capability layer, not model gateway replacement
Cloudflare or Vercel can govern traffic between your application and model providers. QVeris complements that layer when an agent also needs external APIs and tools. The pattern is Discover → Inspect → Call: find a capability, inspect schema and permissions, then invoke it with bounded inputs. Keep model-routing evidence from the gateway and tool-source evidence from QVeris as separate provenance chains.
Search for the required external capability by task, freshness, geography, and trust boundary.
Review inputs, outputs, permissions, limits, provider identity, and failure semantics.
Invoke the narrowest tool, preserve evidence, validate output, and send only necessary context to the model gateway.
Cloudflare vs Vercel AI Gateway FAQ
Which is better, Cloudflare AI Gateway or Vercel AI Gateway?
Neither is universally better. Cloudflare is a strong fit for edge policy, explicit cache and logging controls, and versioned visual routing. Vercel is a strong fit for AI SDK workflows, a unified model catalog, automatic provider selection, and Vercel-native operations.
Is Cloudflare Universal Endpoint still recommended?
No for new integrations. Cloudflare marks it deprecated and recommends its OpenAI-compatible endpoint plus Dynamic Routing for fallbacks, retries, and conditional routing.
Can both gateways use an OpenAI-compatible client?
Yes. Both document compatible chat completion endpoints. Use environment-specific base URLs and keep model aliases in configuration.
How should I compare latency fairly?
Run the same model, prompt, region, streaming mode, timeout, and concurrency. Measure TTFT, total duration, error rate, fallback rate, and p95 or p99 rather than one warm request.
Does gateway caching always reduce cost?
No. Exact-match cache helps deterministic repeats, but can return stale or contextually wrong answers if identity, permissions, freshness, or tool state are omitted.
How do the gateways handle sensitive prompts?
Treat logging as an explicit governance decision. Cloudflare documents per-request controls to disable full logging or payload collection. On either platform, classify data, redact secrets, restrict access, set retention, and verify the actual log record.
Can I migrate without changing application code?
An adapter can limit changes, but model naming, authentication headers, provider policies, cache semantics, and observability fields still need translation and tests.
Where does QVeris fit?
QVeris complements either gateway by helping agents discover, inspect, and call external capabilities. The gateway governs model traffic; QVeris governs the broader tool and API capability layer.
Official sources
Gateway APIs, model catalogs, pricing, and plan limits change. These primary sources were checked for this July 2026 revision; verify them again before production rollout.
Choose with evidence, and keep the exit reversible
Shortlist by platform gravity, prove the decision with accepted-output metrics, and keep gateway-specific configuration behind one adapter. Then add QVeris when agents need governed discovery and invocation of external tools beyond model traffic.
Explore financial agent tools
