Introduction
Using Vercel is a popular choice for hosting apps, thanks to its ease of use and support for Next.js framework. This hosting platform can accommodate even large traffic spikes and different use cases. However, as your projects scale their hosting costs can grow as well and have you look elsewhere for a different hosting provider.
Still, there’s a way to limit how much you’re spending on cloud hosting and make Vercel support the budget of your Next.js app. Even small adjustments to the code, how you configure your project settings, deploy your project, or how often check the dashboard can make a difference.
In this step-by-step guide I’ll introduce you to smart strategies we’re using to lower hosting expenses, and help you decide when staying on a Pro subscription is the best choice, and when upgrading to Enterprise is necessary.
Chris Lojniewski and I held a live session on this subject, which included a live demo of the optimizations I’ll be describing in the article. You can watch it here.
Now, let’s start by breaking down what affects your Vercel hosting bill.
Factors Driving Costs in Vercel
We can divide the factors influencing your costs into Fixed-Price and Usage-Based.
Fixed-Price Factors
These stay roughly the same each month, as Vercel sets their price for all users.
Plan Selection – When starting a new project, choosing the right plan matters, especially if you’re too big for the generous free tier Vercel offers. Before you start the deployment process, ensure your plan aligns with your expected usage so your project can be deployed quickly and securely. Hobby, Pro, and Enterprise plans have different pricing structures and limits. The Pro plan includes additional resources but charges for overages, while the Enterprise plan offers custom pricing based on usage.
Number of Seats – Vercel charges per seat for users needing access to the dashboard. Make sure that only necessary team members have access to your repository or use automation (e.g., GitLab CI/CD or GitHub Actions for deployment, which I’ll talk about more later).
Usage-Based Factors
This type of costs can rise or fall, depending on your setup and decisions.
Execution Time – You’re billed based on the total time serverless functions take to execute. Vercel’s automatic scaling helps optimize performance by adjusting resources based on traffic demand.
Invocations – Each time a serverless function runs, it becomes an invocation. High invocation counts can quickly increase costs, particularly if middleware, API routes, or unnecessary prefetching is triggering multiple function calls. You can avoid this by limiting function calls and caching responses where possible.
Bandwidth – The volume of JavaScript bundles, images, API responses, and any external asset loads transferred between users and the server contributes to costs. Compressing assets, reducing data payloads, and utilizing caching strategies can reduce bandwidth expenses.
Once you become aware of what affects your bill, you can start working on lowering it. To help you, I’ve prepared a list of the code optimizations we’ve been using in our projects, which you can implement as well.
Lowering Hosting Costs with Code Tweaks
Sometimes smart and strategic choices and taking advantage of Vercel as the easiest way to deploy Next.js applications without breaking the bank. Below are the examples of code-level adjustments we’ve been using in our projects to lower the costs.
Choosing the Optimal Rendering Method
Rendering methods play a significant role in shaping your hosting costs. Using Static Site Generation (SSG) is an effective way to minimize execution costs and reduce unnecessary deploying. It lets you shift processing from runtime to build time, a particularly useful feature for content that does not change frequently.
Server-Side Rendering (SSR) on the other hand, should be used sparingly, as it adds new execution costs with every page request. Incremental Static Regeneration (ISR) balances the two by allowing updates to static content at scheduled intervals. This reduces unnecessary function executions while keeping content fresh.
Minimizing Data Transfer
Large API payloads can lead to increased bandwidth usage and higher costs. Efficient query techniques, such as database-level aggregations instead of frontend filtering, can significantly cut down on data transfer.
getStaticProps
applied for pre-building pages rather than fetching data at runtime stops users from repeatedly triggering API requests. This further reduces bandwidth consumption, but limiting the props passed to pages can also decrease data transfer volumes and improve page load times.
Optimizing Prefetching
Knowing how to optimize prefetching is crucial in controlling function invocations. Next.js prefetches links by default, which can lead to excessive function executions when multiple pages are loaded in advance. While this improves performance, it can also increase costs unnecessarily, a common problem in the modern web development process.
Disable prefetching for non-critical pages or implement hover-based prefetching to balance top performance and cost efficiency.
Function Optimization
Function execution time directly impacts hosting expenses. Optimizing its performance is key to savings. Instead of making multiple sequential API requests, parallelize requests using Promise.all()
to reduce execution time.
Database queries should also be optimized to minimize expensive calculations within API functions. Offload long-running processes like PDF generation to background jobs outside Vercel and implement caching strategies to limit unnecessary API requests, so frequently accessed data is served efficiently.
Reducing Middleware Executions
Badly managed middleware executions can accumulate unnecessary costs. Implementing route matchers makes middleware run only when required, lowering strain on the back-end and preventing excess function executions. Static assets should be excluded from middleware processing to optimize performance and reduce costs.
Regex filters can further refine when middleware is executed, allowing developers to fine-tune application behavior without incurring excessive execution charges. Here’s how you can do it:
export default async function middleware(request: NextRequest) {
if (!request.nextUrl.pathname.startsWith("/protected")) {
return NextResponse.next();
}
// OTHER MIDDLEWARE ACTIONS
return NextResponse.next();
}
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|favicon.ico|assets|.*\\.png$).*)",
],
};
Optimizing Vercel Dashboard
A lot of the savings for your app can be found in the Vercel dashboard settings, depending on how you want to deploy it.
Setting maximum execution time for functions helps prevent excessive processing costs. This ensures that long-running functions do not consume unnecessary resources, avoiding unpredictable costs caused by inefficient execution loops.
The Fluid Compute feature is another valuable addition Vercel offers. It allocates resources to functions, which helps balance cost and performance by optimizing resource utilization based on demand. Enable it in your app to test the potential gains it might offer.
New image optimization pricing has changed Vercel’s billing approach. Instead of charging based on the number of images transformed, costs are now tied to transformation actions. However, the platform still supports a variety of optimization strategies. Teams should review their image processing workflows and limit unnecessary transformations.
Performing front-end bundle analysis using tools like Lighthouse and Webpack Analyzer helps identify and eliminate unused JavaScript and CSS, reducing page load times and bandwidth consumption. Streamlining bundles ensures assets are delivered without adding to hosting costs. Taking advantage of features of Next.js, such as automatic code splitting and tree-shaking, can help you further optimize performance.
Remember to allocate only the necessary resources for each function. You’ll be able to avoid over-provisioning, reduce execution time expenses, and properly set a custom domain without unnecessary redirects or misconfigurations. Regularly monitoring and fine-tuning these settings will help you match actual usage needs to avoid overpaying.
Alternatives to Vercel Premium Features
Lowering reliance on Vercel’s premium features like image optimization through alternatives can lower your costs while maintaining a high-performing app.
Limiting seats using solutions like GitHub workflows is an effective strategy. Instead of granting all team members direct access to the Vercel dashboard, teams can configure GitHub Actions to automate Vercel’s deployment. This removes the need for additional paid seats but also restricts real-time monitoring, debugging, and direct deployment control.
Image optimization is another area where external solutions can help cut expenses on Vercel. The platform integrates seamlessly with third-party CDNs (Content Delivery Networks) and CMSs (Content Management Systems) which makes it easy to reduce reliance on Vercel’s image handling if you are already using one of these.
Built-in analytics tools can also be replaced with third-party solutions like DebugBear, SpeedCurve, or web.dev.
For password protection, instead of using Vercel’s built-in feature, you can implement middleware-based authentication. Redirecting users to a custom authentication route lets developers control access without incurring extra Vercel costs.
How to Implement Password Protection with Middleware
To implement password protection outside of Vercel’s built-in tools, you’ll need to do three things. First is the setting of the middleware, which will check your password. Start by updating your middleware file with this code:
import { NextRequest, NextResponse } from "next/server";
function checkForPassword(request: NextRequest) {
const hashedPassword = request.cookies.get("site-access")?.value;
const envPassword = process.env.SITE_PASSWORD;
if (!envPassword) {
return null;
}
// You should use a better hashing algorithm here
const hash = (str: string) => Buffer.from(str).toString("base64");
if (!hashedPassword || hashedPassword !== hash(envPassword)) {
const response = NextResponse.rewrite(
new URL("/password-check", request.url)
);
response.cookies.set("requested-path", request.nextUrl.pathname);
response.headers.set("cache-control", "no-store, must-revalidate");
response.headers.set("x-middleware-cache", "no-cache");
return response;
}
}
export default async function middleware(request: NextRequest) {
const redirectResponse = checkForPassword(request);
if (redirectResponse) {
return redirectResponse;
}
return NextResponse.next();
}
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|favicon.ico|assets|.*\\.png$).*)",
],
};
Now that this is ready, it’s time to set up the page which will prompt for a password. Create a file in the /app/password-check/page
path and type this:
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
export default function PasswordCheck() {
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const router = useRouter();
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
try {
const response = await fetch("/api/password", {
method: "POST",
body: JSON.stringify({ password }),
});
if (!response.ok) {
throw new Error("Failed to validate password");
}
const requestedPath =
document.cookie
.split("; ")
.find((row) => row.startsWith("requested-path"))
?.split("=")[1] || "/";
router.push(requestedPath);
} catch {
setError("Invalid password. Please try again.");
}
}
return (
<main className="grid place-items-center min-h-[100vh] bg-gray-50 p-4">
<div className="w-full max-w-sm space-y-4">
<h1 className="text-3xl font-bold text-center text-gray-900">
Access Forbidden
</h1>
<p className="text-sm text-center text-gray-600">
This page is protected by password. To access the site, please ask the
administrator for the password and type it below.
</p>
<form onSubmit={handleSubmit} className="space-y-4">
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full px-3 py-2 border rounded text-gray-900 placeholder-gray-500 focus:ring-2 focus:ring-indigo-500"
placeholder="Enter password"
/>
{error && <p className="text-red-500 text-sm text-center">{error}</p>}
<button
type="submit"
className="w-full py-2 px-4 bg-indigo-600 text-white text-sm font-medium rounded hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500"
>
Submit
</button>
</form>
</div>
</main>
);
}
The last step is to create an API request for password verification since client logic doesn’t have access to environment variables. Create a new file in the /api/password/route
path and type:
import { NextRequest, NextResponse } from "next/server";
export async function POST(request: NextRequest) {
try {
const { password } = await request.json();
if (password !== process.env.SITE_PASSWORD) {
return NextResponse.json(
{ message: "Invalid password" },
{ status: 401 }
);
}
const response = NextResponse.json(
{ message: "Password valid" },
{ status: 200 }
);
// Set secure HTTP-only cookie with base64 encoded password
response.cookies.set({
name: "site-access",
value: Buffer.from(password).toString("base64"),
httpOnly: true,
sameSite: "strict",
path: "/",
});
return response;
} catch {
return NextResponse.json(
{ message: "Error validating password" },
{ status: 500 }
);
}
}
Bear in mind, this is not the perfect solution for apps requiring high security. Companies that need to adhere to strict standards or handle sensitive information might be better off using Vercel’s built-in protections. Speaking of…
When Do You Need Vercel Enterprise?
Time to discuss the elephant in the room – is upgrading to Enterprise necessary for growth? The answer depends on what your project requires.
Vercel Enterprise is designed for businesses that need security, scalability, dedicated support, and advanced features. While the Pro plan is enough for most applications, Enterprise offers additional features for high-traffic, compliance-driven, or mission-critical applications.
You’ll Need Enterprise If:
More Support is Necessary
Enterprise customers receive dedicated customer support with service level agreements (SLAs) guaranteeing uptime and response times. This level of support could be a good investment if your app relies heavily on uptime and fast troubleshooting.
You’re Constantly Exceeding Pro Plan Limits
In case when a project exceeds Pro plan limits in execution time, bandwidth, or function invocations, Enterprise can provide a more flexible usage allowance with a custom pricing option. This can be the less expensive option compared to paying for overages on the Pro plan.
Security and Compliance Are a Must
Compliance standards like SOC 2, ISO 27001, and HIPAA require strict data handling policies that Enterprise plans support. Single Sign-On (SSO), role-based access control, private networking, and dedicated infrastructure could be needed if your organization handles sensitive data.
Advanced Performance Optimization Options Can Help Your App
Enterprise users have access to additional performance improvements. This includes enhanced CDN configurations, lower cold start times, and priority deployment processing for faster build times.
Custom Billing and Procurement is Important to You
Larger companies often require flexible billing arrangements, invoicing options, and procurement workflows aligning with internal procedures. Vercel Enterprise allows for custom contracts, bulk seat management, and additional auditing capabilities.
Enterprise Won’t Be Necessary If:
You’re Running a Small to Mid-Sized Project
Vercel supports the hosting and deployment of a variety of apps, from personal projects outgrowing the Free plan, to e-commerce sites. All of them can run efficiently on the Pro plan without requiring the additional features of Enterprise.
The App You’re Working on Is Cost-Sensitive
If budget control is your priority, explore cost optimizations within the Pro plan, like reducing function executions, optimizing data transfer, and limiting seats. It can be a better (and more affordable) solution than upgrading to Enterprise.
There Are Alternative Hosting Solutions You Can Pursue
In a situation where Vercel’s pricing becomes unsustainable at scale, you might consider alternative hosting solutions. Self-managed cloud infrastructure (AWS, GCP, Azure) or hybrid deployments that combine Vercel with other providers for cost efficiency can be a good investment.
Before deciding on upgrading, carefully evaluate your business requirements, traffic volume, and budget constraints. Only then you’ll know if Vercel Enterprise will provide you with a better value than sticking to Pro plan.
Conclusion
Vercel has evolved over the years to accommodate different Next.js apps in modern development. Keeping it affordable comes down to making smart choices. Simple tweaks to rendering, function execution, and dashboard settings can save your budget.
It’s important to remember that your subscription matters. For most projects, the Pro plan is enough with the right optimizations, but if security, compliance, or heavy traffic are concerns, Enterprise might be the better, and sometimes even more affordable fit. As long as you understand your usage and align your hosting strategy with business goals, Vercel makes hosting cost-effective for your Next.js applications, whether you’re working on a small project, web application, or a big venture.
Top comments (0)