Vercel Free Tier Limits: What the Hobby Plan Really Allows
Most people know you can run a real site on Vercel for free. What is less obvious is where that free tier ends. The Hobby plan is more than enough to keep a personal site or portfolio online, but "free" comes with conditions and configuration details that are easy to miss. This post covers both: how to put together a solid production setup, and what the Vercel free tier limits actually are in numbers.
The licensing condition first
The Hobby plan is for non-commercial use. A personal portfolio, blog or side project is fine. If the site is a business's main site or directly generates revenue, you need the Pro plan.
Using a portfolio to land freelance work is a grey area; if the site promotes you rather than selling a service, it's generally fine. If there's serious commercial activity involved, check the terms.
Connecting a domain
Add your domain under Settings → Domains in your project. Vercel will give you a DNS record to create.
For an apex domain (example.com) it usually asks for a CNAME. That looks wrong — normally you can't have a CNAME at the apex. Providers like Cloudflare support it via CNAME flattening, which is why it works.
A critical detail: if you use Cloudflare, turn the proxy off for this record (grey cloud, "DNS only"). With the proxy enabled, Vercel can't validate its SSL certificate.
Pick one of www and the apex as your primary. If both serve the same content, search engines see duplicates. Vercel offers a "Redirect apex domains to www" option when adding the domain; decide which is canonical and redirect the other.
Preview deployments and SEO
Vercel creates a preview URL for every push. If those are publicly reachable, search engines can index them and create content conflicts with your real site.
Keep "Vercel Authentication" enabled under Settings → Deployment Protection. Preview URLs then require a logged-in team member. Your production domain is unaffected.
Separately, the *.vercel.app address can never be fully removed — a project always has one. To stop it competing with your site in search results, redirect it to your canonical domain:
// proxy.ts (Next.js 16) or middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
const CANONICAL_HOST = "example.com";
export default function middleware(request: NextRequest) {
const host = request.headers.get("host");
if (host && host.endsWith(".vercel.app")) {
const url = new URL(request.url);
url.host = CANONICAL_HOST;
url.protocol = "https";
return NextResponse.redirect(url, 308);
}
return NextResponse.next();
}308 is a permanent redirect; it tells search engines where the real address is and passes link equity along.
Watch your middleware matcher
If you use middleware, the matcher expression that decides which paths run through it can cause silent failures. Custom routes without a file extension (/og, /icon) can be caught and redirected by accident, producing a 404:
export const config = {
matcher: ["/((?!api|og|icon|apple-icon|_next|_vercel|.*\\..*).*)"],
};Remember to update this list whenever you add a special route (dynamic icon, OG image, feed). The symptom is distinctive: the route 404s in the browser while the file sits right there.
Environment variables
Add them under Settings → Environment Variables. There are three environments: Production, Preview, Development.
Two things to watch:
The NEXT_PUBLIC_ prefix. Variables with this prefix are embedded in the client bundle and visible to everyone. Use it only for values that are genuinely public — an API base URL, a publishable key. Secrets must not carry the prefix.
Redeploy after changes. Adding a variable doesn't update the current deployment; a new build is required. Use "Redeploy" from the Deployments tab.
Scheduled content without cron
The Hobby plan allows one cron invocation per day. But you don't need it to schedule content — ISR offers something simpler.
Filter out entries dated in the future, and give the page a revalidation window:
function isVisible(post: Post) {
const today = new Date().toISOString().slice(0, 10);
if (post.published === false) return false;
if (post.date > today) return false;
return true;
}export const revalidate = 3600;
export const dynamicParams = true;When the page regenerates each hour, new Date() returns the new day and that day's content appears on its own. No cron, no automated commits, no external service.
When you want a post live without waiting for the hourly window, that is what the on-demand side of ISR is for; I walk through it with revalidatePath in ISR and on-demand revalidation in Next.js.
Sending email
Vercel has no SMTP server; you can't send mail directly from serverless functions. You need an email API service. Most offer a free tier of a few thousand messages a month, which is plenty for a contact form.
To send from your own domain you'll need to add verification records to DNS (typically DKIM, SPF and DMARC). Without them you can still send, but messages go out from the provider's shared address and are far more likely to land in spam.
Analytics
Vercel Web Analytics is free on Hobby up to 50,000 events per month. Past the limit, collection pauses — you are not charged extra. Collection stops once the grace period expires and can resume after 7 days.
Setup is a single component:
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Analytics />
<SpeedInsights />
</body>
</html>
);
}Speed Insights collects Core Web Vitals from real users. Unlike a Lighthouse lab score, this is the kind of data Google actually uses for ranking — it's the number worth watching. Moving that number is a separate job; I go through it step by step in Core Web Vitals and Lighthouse optimisation.
One caveat: these scripts are blocked by some ad blockers, so the data represents a subset of real traffic. Watch the trend rather than the absolute figure.
Vercel free tier limits: the actual numbers
"Will the free tier be enough for me?" is a question that only numbers answer. The figures below come from Vercel's own limits reference and Hobby plan page, as of September 2026:
| Item | Hobby limit |
|---|---|
| Fast Data Transfer | 100 GB / month |
| Edge requests | Up to 1,000,000 / month |
| Function invocations | 1,000,000 / month |
| Active CPU | 4 CPU-hours / month |
| Provisioned memory | 360 GB-hours / month |
| Function maximum duration | 300 seconds (5 minutes) |
| Projects | 200 |
| Deployments per day | 100 |
| Concurrent builds | 1 |
| Build time | 45 minutes per deployment |
| Domains per project | 50 |
| Cron | 100 jobs per project, but one invocation per day |
| Runtime log retention | 1 hour |
| Web Analytics | 50,000 events / month |
| Image transformations | 5,000 / month |
| Team collaboration features | None |
| Commercial use | Not permitted |
Two caveats. The 300-second ceiling applies to current projects; projects deployed before April 2025 that do not use Fluid compute default to 10 seconds with a 60-second maximum. And these numbers change over time — if you are making a decision that matters, confirm them at the links above.
A personal portfolio or blog will not come close to most of these. Two places can pinch: sites serving heavy images or video can burn through 100 GB of transfer a month, and long-running background jobs hit the 300-second function ceiling. For the second case, serverless is the wrong tool to begin with — a production Docker Compose setup for Next.js + Django covers running those jobs on your own server instead.
How many projects can you deploy for free?
A Hobby account can host up to 200 projects, with a cap of 100 deployments per day. In personal use you will never see either number; the limit that actually matters is the non-commercial condition, not a technical one.
Is a custom domain free on Vercel?
Connecting a domain is free on Hobby, and you can attach up to 50 domains per project. SSL is free too: Vercel automatically tries to issue a Let's Encrypt certificate for every domain added to a project, no matter where the domain was registered. The certificate goes live once your DNS records have propagated and validation succeeds.
The only thing you pay for is the domain itself, bought from a registrar. Vercel takes no cut of that.
Pre-launch checklist
- Domain connected and SSL active?
wwwvs apex decided, with one redirecting to the other?- Preview deployments protected?
*.vercel.appredirecting to the canonical domain?- Redeployed after adding environment variables?
robots.txtandsitemap.xmlreturning the right content?- Sitemap submitted to Google Search Console?
Once those pass, the infrastructure side is done. The rest is content — which is what actually brings traffic.