Our verdict

  • Personal Hobby project

    Vercel served a real static page and Node API.

    50/50 requests per route returned 200. Hobby is non-commercial personal use; deployment URL authentication needs an explicit check.

  • Static-first release

    Cloudflare Pages is our first candidate for a static-heavy site.

    The hosted fixture remained live on Oct 2. Build and file limits are documented; Functions have a separate Workers budget.

  • Preview workflow

    Consider Netlify after budgeting production publications.

    Local Functions worked, but hosted signup was blocked. Free shares 300 credits across deploys, bandwidth, requests and compute.

At a glance: choose by use case and budget

For a non-commercial personal project with a small Node endpoint, Vercel Hobby passed our hosted smoke test. For a static-heavy site, Cloudflare Pages is our first candidate: our existing page and Function were still reachable, and its documented build allowance is separate from Function usage. Netlify is a candidate when its preview and routing workflow matters enough to justify a shared credit budget. These are recommendations from a narrow fixture, not production capacity guarantees.

This is an uneven evidence set. We deployed Vercel Hobby, re-sampled an existing Cloudflare Pages fixture, and carried forward Netlify local tests from Oct 1. Netlify hosted signup remained blocked by a security check. We rechecked the supplied official documentation on Oct 2, 2026; documented quotas are not limits we reached.

Methodology: what the numbers can establish

The Oct 2 measurements came from the same Linux box with US-East/IAD egress. Vercel headers showed iad1; its API also reported function region iad1. Cloudflare’s API reported IAD and country US. The Asia/Singapore timestamp records the reporting timezone, not Singapore network origin.

Vercel used Python urllib total request time, 50 sequential GETs per route with warmup excluded, at about 10:40 SGT. Cloudflare used 50 curl GETs per route, recording time_starttransfer (TTFB), at about 10:41 SGT. The Cloudflare JSON notes an earlier urllib 403 with the Python user agent; the successful curl sample is the one reported here. Total request time and TTFB are different metrics. These tiny responses, separate tools and separate runs cannot establish a cross-vendor speed winner or explain tail latency.

Netlify’s 50 sequential requests used Python Requests against localhost on Oct 1, after one excluded warmup. They include the development proxy and Function process, with no WAN hop. We did not run parallel load, deliberately isolate cold starts, exercise a real application framework or observe sustained uptime.

Methodology: what the numbers can establish
EvidenceHTML median / p95API median / p95Scope
Vercel Hobby, Oct 239.251 / 246.910 ms54.539 / 248.861 msTotal time, US-East/IAD; 50/50 HTTP 200 per route
Cloudflare Pages, Oct 238.122 / 50.703 ms70.388 / 80.685 mscurl TTFB, same box/IAD; 50/50 HTTP 200 per route
Netlify Dev, Oct 1Not measured in this comparison161.313 / 225.998 msLocal total time; 50/50 HTTP 200; hosted Free not tested

Free-tier limits: checked October 2, 2026

Use Vercel Hobby docs, Vercel pricing and limits; Cloudflare Pages limits and Function pricing; and Netlify pricing with credit documentation. All table values are official/documented, not observed consumption. Netlify’s credit model applies to new accounts since September 4, 2025; eligible older accounts may retain legacy plans.

Free-tier limits: checked October 2, 2026
DimensionVercel HobbyCloudflare Pages FreeNetlify Free, credit plan
Price / eligibility$0; non-commercial personal use onlyFree Pages tier; Functions follow Workers billingFree; 300 credits/month hard limit
Publishing100 deployments/day; 1 concurrent deployment500 builds/month; 1 concurrent; 20-minute build timeout15 credits/successful production deploy; preview publication 0 deploy credits
Traffic100 GB Fast Data Transfer; 10 GB Fast Origin Transfer; 1M CDN requestsStatic asset requests are free and unlimited; Functions separate20 credits/GB bandwidth; 2 credits/10,000 web requests
Function budget1M invocations; 4 hours Active CPU; 360 GB-hours Provisioned MemoryWorkers Free docs: 100,000 requests/day shared with Workers; 10 ms CPU/invocation10 credits/GB-hour compute; shares the same monthly credits
Other constraints200 projects; 5K image transformations; current Hobby function maximum 300 seconds20,000 files; 25 MiB/file; 100 projects; 100 custom domains/projectDeploy, traffic and compute compete for one balance; exhaustion pauses projects on that balance
When allowance runs outNo purchased Hobby overages; usage recovery can require waiting roughly 30 daysBuild and Workers limits are distinct; account Workers plan not verifiedHard limit; no Free auto-recharge
Check date2026-10-022026-10-022026-10-02 (local tests: 2026-10-01)

The 300-second Vercel number is the current Hobby plan maximum, not a duration we executed. The limits page separately lists older projects created before April 23, 2025 without Fluid compute with a 10-second default and 60-second Hobby maximum. Check your project configuration before designing a long-running endpoint. Cloudflare’s Workers Free quotas are conditional: the earlier account test did not verify whether a Workers Paid subscription was active.

Vercel Hobby: a public alias, a real Function and a protected deployment

We used Vercel CLI 62.1.0 on Node 22.23.3, logging into account sudoai-dev, Hobby team sudoai-devs-projects. The deployment OIDC claim reported plan=hobby; no paid upgrade was purchased. The fixture is one static HTML page that fetches /api/hello, plus a Node serverless handler returning JSON with region and deployment ID. The page has a noindex meta tag and the project header rule sets X-Robots-Tag: noindex.

Production deployment dpl_AFbRLtMozwYkdTXVu69n4Qkb3WQw reached READY and served the public alias https://sudoai-vercel-hobby-fixture.vercel.app/. Its first measured HTML response showed X-Vercel-Cache: HIT. The API showed MISS, Cache-Control: no-store, the custom X-SudoAI-Test header and region: iad1. That establishes a hosted Node response; it does not test Next.js, ISR, databases or an authenticated application.

Our live Vercel Hobby fixture page showing the API response.
Real Vercel Hobby static page and API fixture, captured October 2, 2026.
The hosted Vercel API JSON response with region and deployment ID.
The hosted Node endpoint reported iad1 and the READY deployment ID.

The HTML sample ranged from 29.425 to 277.573 ms; the API from 40.144 to 279.002 ms. All 100 measured requests returned 200, but the p95 values were much larger than the medians. We did not isolate the reason and will not label these samples cold starts or attribute them to a platform fault.

Deployment protection changed what an unauthenticated visitor could reach

A later --prod attempt, dpl_Ea3P641hSxbnZA9cR6EqY3e4tmj1, ended BLOCKED with Vercel Authentication. Its specific deployment hostname returned 302 and “Protected by Vercel Authentication.” The project API reported ssoProtection.deploymentType = all_except_custom_domains. The earlier READY production .vercel.app alias remained publicly reachable. These are observations about this project and these hostnames, not a claim that every Hobby production alias is protected.

The Vercel Authentication screen observed on a protected deployment URL.
Observed Vercel Authentication protection on a deployment URL, October 2, 2026.

The Vercel Authentication documentation explains the protection method. Our recommendation is to test the exact URL you will share from an unauthenticated browser or HTTP client, including an API or webhook route. A working production alias does not establish that its deployment-specific URL is public. Custom domains and bypass mechanisms were not tested.

Cloudflare Pages: a hosted recheck and separately dated Singapore evidence

The existing sudoai-cf-free-test.pages.dev fixture still served HTML and its Pages Function on Oct 2. The new same-box sample reported IAD, with medians of 38.122 ms HTML TTFB and 70.388 ms API TTFB. It is a recheck of the existing deployment, not a new timed deploy or a repeat of the Singapore experiment.

Prior evidence, September 30, 2026: a Mac mini in Singapore sent 20 sequential curl requests to the Pages Function. Median TTFB was 48 ms, range 29–198 ms, and the Function reported SIN. The original command-line Pages deploy took 12.3 seconds, an unchanged redeploy 8.3 seconds, and a preview deploy 7.5 seconds. Those dated observations belong to the original Cloudflare review; they are not Oct 2 Vercel or Netlify results.

The prior run also observed a deployment-hash URL initially failing TLS before returning 200 roughly a minute after deploy, while the production alias worked immediately. Unknown Pages paths returned 200 with index.html because the fixture had no 404.html. A static _headers rule applied to HTML but not the production Function response. Those concrete behaviors matter for publishing a static site and monitoring an API; none establishes long-term reliability.

Netlify: useful local checks, no hosted result

On Oct 1, Netlify CLI 27.10.2 offline on Node 22.23.3 served static HTML and a regular Function. The corrected 50-request sample had median 161.313 ms and p95 225.998 ms, with a range of 147.093–235.456 ms. The excluded warmup is described in the methodology above.

netlify dev --offline --no-open --skip-gitignore --dir /absolute/path/to/fixture/public --functions /absolute/path/to/fixture/functions --port 5683

We used explicit absolute paths because the fixture lived inside the sudoai.net repository. Our first run loaded the parent repository’s go Function instead of the fixture’s echo Function, and the rewritten endpoint returned 404. Supplying both paths loaded echo and fixed the problem. This is a monorepo/configuration discovery observation in our run; we did not establish a general CLI defect.

Our static page calling the real Netlify Dev Function on localhost. Local emulation only.
Our static page calling the real Netlify Dev Function on localhost. Local emulation only. Captured Oct 1, 2026.
Netlify: useful local checks, no hosted result
CheckObserved resultWhat it establishes
GET /200Static HTML served
GET /api/echo200, JSON200 rewrite reaches the Function
POST /api/echo200, echoed message and sequenceJSON request body survives routing
GET /.netlify/functions/echo200Direct Function route works
GET /missing404Unknown path does not silently become a success
X-SudoAI-Test response headerlocal-fixtureConfigured static header was applied

Signup security verification blocked account creation. We did not deploy hosted Free, measure its CDN or production Functions, observe a credit balance or test a cold start. The Oct 2 official-docs recheck confirmed the credit plan; it did not resolve signup or turn local emulation into hosted evidence.

Calculate publishing cost before traffic

Calculate publishing cost before traffic
Illustrative monthCalculated creditsImplication
20 successful production publications, no traffic/compute20 × 15 = 300Entire Free allowance used publishing
4 publications + 5 GB + 100,000 requests60 + 100 + 20 = 180120 credits remain before compute or other usage
Daily production publication for 30 days30 × 15 = 450Above Free before any visitors

These are calculations using documented rates, not observed invoices. Preview publication costs zero deploy credits, but preview bandwidth and requests still count. A page view can cause multiple asset requests, so do not equate web requests with visitors. Actual metering and dashboard rounding were not tested.

Unused monthly credits do not roll over. Forms submissions are free on credit plans; Free includes one concurrent build and one free team member, according to the plan comparison. Switching from a legacy plan to credits is irreversible according to the plan documentation. The shared hard limit and meter rates are in the comparison table above; exhaustion pauses all web projects on that balance. We did not test quota exhaustion.

Individual Hacker News commenters report scheduled rebuilds burning their allocation and moving the build schedule to GitHub Actions, and adding credits after HN traffic increased demand. These are user reports, not our reproduction. GitHub issue #8423 reports Functions failing when netlify dev --cwd is invoked outside a project; we did not reproduce that specific error. Our problem was resolving the Function folder.

The public plans list Personal at $9/month with 1,000 credits and Pro starting at $20/month with 3,000 credits and unlimited members; Pro has additional credit tiers, and optional recharge and add-ons can add cost. Every paid tier is untested. A successful free hosted deploy, measured publication time, before/after credit screenshots and external latency would let us assess hosting and reconsider the verdict; until then, the evidence establishes local tooling and a documented release budget.

Gotchas that can decide the choice

  • Commercial intent comes before Vercel latency. The fair-use policy restricts Hobby to non-commercial personal use. A successful Hobby deploy is not permission to host a commercial product. Pro lists $20/month per seat; we did not test it.
  • Check deployment access independently. We observed Vercel Authentication on a specific deployment URL while an earlier alias stayed public. Test the hostname your visitor, client or webhook sender will use.
  • Retained deploys are a storage concern. Vercel’s September 16, 2026 retention change describes 10 GB Hobby Deployment Storage. Each project keeps its three most recent production deployments plus three most recent of any type regardless of age; current production, aliased and active-branch deployments have exceptions. Over-limit storage can block deploying. We did not fill storage or test deletion/rollback behavior.
  • Cloudflare static success can hide missing routes. Our no-404.html fixture returned index.html with 200 for an unknown path. Check actual response content, and set Function headers in the Function rather than assuming static header rules cover it.
  • Netlify Free is a shared budget. Frequent production publications can consume credits before traffic. Plan the release cadence and verify the account’s current plan, especially if it predates the credit model.

Recommendation and the boundary of this test

Start with Cloudflare Pages for a static-heavy candidate, Vercel Hobby for an eligible personal project needing a small Node endpoint, or Netlify when its workflow is the reason to choose it and the credit arithmetic fits. Then deploy your actual framework, test public access and routes, and measure from your audience’s region. We have not established a framework compatibility winner, commercial-use enforcement outcome or production cost at scale.

Who should not use this

Do not use Vercel Hobby for commercial work: its fair-use policy permits non-commercial personal use only. Do not choose a host for Asian latency from these US-East/IAD results, or treat Netlify’s localhost timing as hosted performance. Netlify Free is a poor fit if your production publication schedule alone exceeds 300 credits. Cloudflare Pages needs an explicit Workers budget when Functions are central to the application. Teams needing verified custom domains, CI, recovery, sustained load or paid features need further testing before committing.

Frequently asked questions

Can I use Vercel Hobby for a commercial site?

The checked fair-use policy restricts Hobby to non-commercial personal use. Commercial usage requires Pro or Enterprise. We did not test enforcement; a successful deployment does not establish permission.

Which host was fastest in Singapore?

This comparison cannot answer that. The Oct 2 box had US-East/IAD egress. Only the prior Sep 30 Cloudflare Pages Function check ran from a Singapore Mac mini: median 48 ms TTFB over 20 requests, colo SIN. No Vercel Singapore or hosted Netlify latency was measured.

Why did a Vercel deployment URL ask for login?

Our project reported ssoProtection.deploymentType = all_except_custom_domains. A later production attempt was BLOCKED and its deployment hostname returned 302 with Protected by Vercel Authentication. The earlier READY production alias remained public. Check the exact hostname from an unauthenticated client.

Does Netlify Free include unlimited production deploys?

On the current credit plan, successful production deploys use 15 credits each from a 300-credit monthly hard limit. Twenty deploys alone consume that allowance by calculation. Preview deploy publication costs zero deploy credits, but preview traffic still uses credits. We did not observe hosted billing.

Are Cloudflare Pages Functions unlimited with static hosting?

No. Pages Functions use Workers billing. The documented Workers Free allowance is 100,000 requests per day shared with Workers and 10 ms CPU per invocation. We did not verify the account’s Workers subscription or exhaust those limits.