Serverless Functions
Adding backend logic to your site

Pixl presents
Need a little backend but don't want to babysit a server? Drop a file in the api folder. Done. Shocking, I know.Need a little backend but don't want to babysit a server? Drop a file in the api folder. Done. Shocking, I know.

Up to now we've used Vercel to host websites. But what happens when your website needs to do something on the server? Maybe process a form, talk to a database, or hide an API key? That's exactly where serverless functions come in.
What is Serverless?#
Let's clear up the name first, because it's kinda misleading. There are definitely servers involved. "Serverless" just means YOU don't have to manage them.
Think about tap water. You turn on the faucet and water comes out. You don't think about the pipes, the pumps or the treatment plant, because somebody else handles all of that. You just use the water.
Serverless works the same way. You write some code. When somebody needs it to run, Vercel's servers run it. When nobody needs it, those servers go do other stuff. You manage exactly nothing.
Why Use Serverless Functions?#
Serverless functions let you add backend logic to a frontend project. Here's when you'd reach for one.
Hide API Keys#
Some services hand you API keys that have to stay secret. You can't put them in frontend code, because anybody can look at it. A serverless function keeps the key tucked away on the server.
Process Forms#
When someone fills out your contact form, that data has to go somewhere. A serverless function can catch the form and send an email or save it to a database.
Talk to Databases#
Databases usually need passwords and shouldn't be hit directly from the browser. A serverless function acts as the secure middleman.
Transform Data#
Maybe you need to combine data from a few sources or reshape it. A serverless function can do that work before anything gets sent to the browser.
How They Work on Vercel#
Vercel makes this RIDICULOUSLY simple. Here's the basic idea.
Step 1. Create a File#
In a Next.js project, you create a file in the app/api folder (or pages/api for older projects). Each file becomes an API endpoint.
Step 2. Write Your Code#
Inside the file you write a function that handles requests. It takes in data, does something with it and sends back a response.
Step 3. Deploy#
When you deploy to Vercel, it turns these files into serverless functions automatically. Zero extra setup.
Step 4. Use It#
Your frontend calls these endpoints like any other API. The function runs, returns its data and shuts down.
A Simple Example#
Here's what a basic serverless function looks like in Next.js.
// app/api/hello/route.js
export async function GET() {
return Response.json({ message: "Hello, World!" });
}That creates an endpoint at /api/hello. Visit that URL and you get this back.
{ "message": "Hello, World!" }Yep, that's it. That's a complete serverless function.
A More Useful Example#
Say you want to grab the weather, and the weather API needs a secret key. Here's how you'd keep it hidden.
// app/api/weather/route.js
export async function GET() {
// This key is stored in Vercel's environment variables
const apiKey = process.env.WEATHER_API_KEY;
// Fetch weather data using the secret key
// (made-up URL, every real weather API has its own)
const response = await fetch(
`https://api.weather.com/data?key=${apiKey}`
);
const data = await response.json();
// Return just the data you need
return Response.json({
temperature: data.temp,
conditions: data.conditions
});
}The browser never sees your API key. It just calls /api/weather and gets the weather back.
The API Folder Structure#
In a Next.js project, your API routes live in one specific spot.
your-project/
├── app/
│ ├── api/
│ │ ├── hello/
│ │ │ └── route.js → /api/hello
│ │ ├── weather/
│ │ │ └── route.js → /api/weather
│ │ └── users/
│ │ └── route.js → /api/users
│ └── page.js
└── package.jsonThe folder structure turns into the URL path. A file at app/api/users/route.js creates an endpoint at /api/users.
Request Methods#

Serverless functions can handle different kinds of requests.
GET#
Fetch data, like viewing a webpage.
export async function GET() {
// Return some data
return Response.json({ data: "here" });
}POST#
Send data, like submitting a form.
export async function POST(request) {
const body = await request.json();
// Do something with body.data
return Response.json({ success: true });
}And you can have both in the same file.
export async function GET() {
return Response.json({ message: "Getting data" });
}
export async function POST(request) {
const body = await request.json();
return Response.json({ message: "Received data" });
}Calling Functions from Your Frontend#
From your website's JavaScript, you call these endpoints the same way you'd call any other API.
// Get data from your serverless function
const weatherResponse = await fetch('/api/weather');
const data = await weatherResponse.json();
console.log(data.temperature);
// Send data to your serverless function
const contactResponse = await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: '[email protected]' })
});Limits and Pricing#
Serverless functions come with a few limits to keep in mind.
Execution Time#
As of October 2026, a function on the free Hobby plan can run for up to 5 minutes before Vercel cuts it off with a timeout error. Paid plans can go longer. Most functions finish in milliseconds anyway, so you'll only bump into this with slow jobs (and those belong on Railway, more on that below).
Memory#
Functions get a limited amount of memory, 2 GB on the Hobby plan. For most things you'll build, that's plenty.
Usage#
The Hobby plan includes 1 million function runs and 4 hours of active CPU time a month. For personal projects and learning, you won't hit that. These numbers change, so check vercel.com/pricing when it matters.
When to Use Serverless Functions#
Good Use Cases:#
- Form handling
- API key hiding
- Simple database queries
- Authentication checks
- Data transformation
Better Handled by Railway:#
- Long-running background jobs
- Complex databases
- Real-time applications
- Anything running constantly
Rule of thumb... Vercel is great for frontend and quick backend tasks. When the backend work gets heavy, send it to Railway.
TL;DR#
- Serverless means you don't manage the servers, even though they're still there
- Functions only run when they're needed, then they shut down
- In Next.js, you add serverless functions by creating files in
app/api/ - Use them to hide secrets, process forms and talk to databases
- The free tier has plenty of function usage for learning
What's Next?#
You can deploy, preview, configure and add backend logic now. There's one more common job left, which is hooking up your own custom domain. Let's do that next!
This lesson ends with 2 short activities.
