Netlify, deploying a site without your own server
Putting a site online once meant a server, configuration, and keeping updates current. Netlify reduces that to connecting a repository: after every push the platform builds the project and serves it at an address, with a certificate and a content delivery network included.
That was the platform's original idea and remains its strongest side. Edge functions, backendless form handling, and deploy previews grew around it, but the core stays: a site from a repository onto the internet with no administrative work.
Deployment and previews
Configuration fits in one repository file, so it is part of the code and goes through review like everything else.
[build]
command = "pnpm build"
publish = "dist"
[[redirects]]
from = "/old-path"
to = "/new-path"
status = 301
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"The most useful feature is the deploy preview. Every pull request gets its own address with a working version of the site, so review means looking at the result rather than reading a diff and imagining it.
That changes how visual changes are handled more than it appears to. Somebody outside the development team can see a change and comment before it reaches production, without running anything locally.
Set two things up from the start. The first is password protecting previews if the site holds content not ready for publication. The second is excluding previews from indexing, otherwise a search engine finds twenty copies of your site at different addresses.
Credit billing
This is the most important change of recent years and the first thing to understand when planning cost.
Limits were previously counted separately: gigabytes of bandwidth, build minutes, function invocations. In September 2025 that gave way to one currency. Every action consumes credits at its own rate, and a plan grants a monthly allowance.
A production deploy costs fifteen credits regardless of build time, which favours projects that build slowly and disfavours ones deployed ten times a day. Bandwidth runs at twenty credits per gigabyte, compute at ten credits per gigabyte hour, and web requests at two credits per ten thousand. Build minutes are not counted at all.
The change simplifies one thing and complicates another. It simplifies because there is one counter rather than four. It complicates because predicting a bill now means estimating several different actions and converting them to a shared unit, which in a first month is guesswork.
The practical approach works a month and checks actual usage in the panel. That number says more than any calculator, since it reflects your deploy frequency and your traffic.
Pricing
| Plan | Cost | Credit allowance |
|---|---|---|
| Free | 0 USD | 300 credits monthly, a hard cap |
| Personal | 9 USD monthly | 1,000 credits, one concurrent build |
| Pro | 20 USD per person monthly | From 3,000 team credits, three concurrent builds |
| Enterprise | quoted individually | Organisational and compliance requirements |
The free plan suffices for a personal project, a portfolio, and a site with moderate traffic. It also covers edge functions and ordinary serverless functions in counts a small site comes nowhere near.
Concurrent build count often matters more than the credit allowance in team work.
Nothing happens automatically once the allowance runs out, and that matters more than it looks. Auto recharge is off by default, so the free plan simply stops at a hard cap while paid plans need it switched on first: five dollars for five hundred credits on Personal, ten dollars for fifteen hundred on Pro. Another concurrent build is a separate add on at forty dollars a month, so you shorten the queue by paying for it rather than by changing plan. One build at a time means that with three people pushing changes a queue forms and the deploy preview arrives late.
When estimating cost, count three things separately: production deploys per month, expected bandwidth, and compute consumption. One rule governs this and is easy to miss: only production deploys draw credits. Deploy previews and branch builds cost zero, so an active team opening dozens of pull requests pays nothing for them. The largest line usually turns out to be bandwidth rather than the build count.
Functions and forms
Beyond serving files the platform runs server side code in two variants.
Ordinary functions work like classic serverless functions: a full environment, library access, execution in a chosen region. Edge functions run closer to the user on a restricted environment and suit fast things: conditional redirects, comparison tests, header personalisation.
export default async (request: Request) => {
const country = request.headers.get('x-country')
if (country === 'PL') return Response.redirect(new URL('/pl', request.url))
}
export const config = { path: '/' }Backendless form handling is a separate feature. A form marked with an attribute reaches the panel, and the platform handles receipt, spam filtering, and notification. That suffices for a contact form and saves an entire server layer.
Complexity is the boundary. A form needing validation against a database, a write to an external system, or file processing exceeds this solution and calls for a function of your own.
import type { Config, Context } from '@netlify/functions'
export default async (request: Request, context: Context) => {
const data = await request.formData()
const email = String(data.get('email') ?? '')
if (!email.includes('@')) {
return new Response('Invalid address', { status: 400 })
}
await saveSubmission({ email, country: context.geo.country?.code })
return Response.json({ ok: true }, { status: 201 })
}
export const config: Config = { path: '/api/submission' }The context object also supplies the request's location without asking the user for it, which is often more convenient than a country dropdown in the form.
Redirects and headers
Two parts of the configuration file deserve separate treatment, since search visibility and security both depend on them.
Redirects handle URL structure changes, multiple languages, and rewriting paths to a back end. Order matters, since the first matching rule wins, and that is the commonest reason a rule added at the end does nothing.
[[redirects]]
from = "/old-blog/*"
to = "/blog/:splat"
status = 301
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Reversing the order of those two entries breaks everything. The wildcard rule covering the whole site matches every address, so placed above it also catches the old blog and the redirect to the new structure never runs.
[[redirects]]
from = "/api/*"
to = "https://api.example.com/:splat"
status = 200
force = trueA two hundred status on a redirect means a server side rewrite rather than a redirect visible to the browser. The address bar keeps the same URL while the content comes from elsewhere. That solves the origin policy problem without configuring headers on the back end.
Set security headers on the first deployment, since nobody returns to them later. Protection against framing, a content security policy, and forcing an encrypted connection are three entries taking five minutes.
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
Strict-Transport-Security = "max-age=31536000; includeSubDomains"
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"The second entry concerns something other than security and is equally worth setting straight away. Files whose names carry a content hash never change, so they can sit in the browser cache for a year. Without that entry the browser asks about them on every visit.
The error page is a separate matter. The default missing resource message looks poor, while your own page with a link home and a search box retains some visitors who would otherwise close the tab.
Netlify against the alternatives
| Platform | Strength | Weakness | Pick it when |
|---|---|---|---|
| Netlify | Simplicity, deploy previews, forms included | Credit billing harder to predict | Static sites, projects across many frameworks |
| Vercel | Deepest Next.js integration | Cost at high traffic | Application in that framework |
| Cloudflare | No bandwidth charges, global network | Edge runtime restrictions | High traffic, low budget |
| Your own server | Full control, predictable cost | Maintenance on your side | Compliance requirements, unusual configuration |
Choosing between the first two rows depends on what you build with. For an application in that particular framework, integration at its makers runs deeper and some features work there without configuration. For a site built with any other tool that advantage disappears while the first row's simplicity remains.
Consider the third row at high traffic, since no bandwidth charges change the arithmetic fundamentally. The price for that sits in runtime restrictions, which on a simple site do not hurt and on an application with a back end sometimes do.
Bear in mind too that migrating between these platforms is relatively cheap. A project built with standard tooling deploys anywhere after changing a few settings, and the platform specific parts usually come down to one configuration file and a function format. That changes the nature of the decision: a choice made at the start need not be a choice for years.
The exception is features relying on mechanisms available from one vendor only: form handling, edge storage, a built in authentication system. Each such element adds work to any future move, so it pays to know how many of them you have.
Build time and caching
A deploy costs the same credits regardless of build time, so the direct cost of time is zero. The indirect one is not, since a long build means a late preview and slower team work.
Dependency caching gives the largest gain. Without it every build downloads and installs everything afresh, which on a large project takes minutes. The platform does this by default for popular package managers, though with an unusual configuration it is worth checking that it actually works.
The second thing is build scope. A project holding several applications in one repository builds everything on every change, even when one changed. Setting a condition to skip a build when changes miss a directory saves time and credits.
The third is page generation. A site with a thousand pages generated at build time can take a quarter of an hour, while incremental revalidation or on demand generation cuts that to a minute. That decision sits with the framework rather than the platform and affects cost here.
Watch build time as a number rather than an impression. Growth from two minutes to eight happens gradually and nobody notices until somebody compares against a log from six months ago.
Common mistakes
The first is publicly reachable and indexed deploy previews. A search engine then finds copies of the site at temporary addresses, which harms results and shows the world unfinished versions.
The second is confusing build count with cost. Only production deploys draw credits, so a team estimating the bill from its commit count arrives at a figure several times too high while still missing bandwidth, which usually weighs most.
The third is secrets in the build configuration rather than in environment variables. The configuration file lives in the repository, so a key typed there is visible to anybody with code access.
The fourth is edge functions used for tasks needing a full environment. The restrictions are real and the error appears only after deployment, since everything works locally.
The fifth is missing redirects after a URL structure change. Old addresses then return an error and search results built over years are lost.
The sixth is relying on built in form handling as requirements grow. The solution suits a contact form and ends at the first need for validation depending on data.
Domains and certificates
Connecting your own domain comes down to naming it in the panel and setting records at your name provider. A certificate is issued automatically and renews itself, so that part stops being anything to watch.
Two decisions deserve making deliberately. The first is whether the primary address carries a prefix. Both versions work, but one must redirect to the other, otherwise a search engine sees two copies of the site.
The second concerns subdomains. A test environment on its own subdomain is convenient and needs excluding from indexing, otherwise an unfinished version competes in results with the production one.
When moving an existing domain, mind the order. First a deployment working at a temporary address and verified, then the record change at your name provider. The reverse means several hours with the site down, since the old server has stopped answering and the new one holds no content yet.
The last thing is propagation time. A record change spreads across the network over tens of minutes, so checking immediately after the change shows the state before it and causes unnecessary panic.
FAQ
What does Netlify cost?
The free plan covers three hundred credits monthly, which suffices for a personal project. Paid plans start at nine dollars a month, and the team plan costs twenty dollars per person with more credits and concurrent builds.
What are credits?
A billing unit introduced in place of separate bandwidth, build minute, and function invocation limits. Every action consumes credits at its own rate, with a deploy costing the same regardless of build time.
Netlify or Vercel?
Vercel integrates more deeply with Next.js, being built by the same team, so some things work there without configuration for applications in that framework. For a site built with another tool the differences are slight, and simplicity plus form handling argue for the first.
Are deploy previews secure?
They are public by default, so with content not ready for publication, enable password protection. Exclude them from indexing too, otherwise a search engine finds many copies of the site at temporary addresses.
Can server side code run there?
Yes, in two variants. Ordinary functions give a full environment and suit tasks needing libraries and database access. Edge functions run closer to the user on a restricted environment and suit redirects and personalisation.
Documentation sits on the project site, and the billing changes appear in the free plan announcement.