Render Tutorials
Web service or static site?

The decision in 60 seconds

⏱ 5 min

When you deploy a frontend or a web app on Render, you’re picking between two service shapes:

  • A static site - pre-built files served from Render’s global CDN. No process, no port, no server-side code at runtime.
  • A web service - a long-running process (Node, Python, Go, Rust, Docker, …) listening on a port. Render’s edge proxies traffic to it.

The whole tutorial collapses to one question.

Before you start

This tutorial is decision-focused, so you don’t need to deploy anything to follow along. To actually ship one of the patterns at the end, you’ll want:

  • A Render account. The free tier covers static sites and small web services.
  • A frontend or web app to deploy. Any project you can git push to GitHub, GitLab, or Bitbucket works.
  • Comfort reading a render.yaml snippet. The Blueprint examples in steps 2 to 5 are short.

The static sites docs and web services docs are good companions if you want to read the platform’s full surface as you go.

The decisive question

Does my code need to run on a server to respond to a request?

If yes → web service. If no → static site. That’s it.

flowchart TB
  q["Does code need to run<br/>per-request on a server?"]
  yes["Yes:<br/>API, SSR, websockets,<br/>auth, DB queries"]
  no["No:<br/>HTML/CSS/JS bundle,<br/>built once, served from CDN"]
  ws["Web service"]
  ss["Static site"]

  q -->|"yes"| yes
  q -->|"no"| no
  yes --> ws
  no --> ss

A few examples to anchor it:

What you’re shippingPickWhy
React/Vue/Svelte SPAStatic siteBuilt once, runs in the user’s browser
Marketing site, blog, docs (Hugo, Docusaurus, Jekyll)Static siteNo server-side logic at runtime
Next.js with next export / output: 'export'Static siteFramework produces static files
Next.js with next start (full SSR)Web serviceServer renders pages per request
Express, FastAPI, Rails, Django, Go HTTP serverWeb serviceA long-running process serves traffic
WebSocket server, real-time backendWeb servicePersistent connection requires a process
Astro with no SSR adapterStatic siteOutput is HTML files
Astro with Node adapterWeb serviceThe adapter runs a Node process

The middle two are where teams get tripped up. The framework name doesn’t decide - its output shape does. Run your build locally and look at what’s in the publish folder. If it’s HTML/CSS/JS files you could open in a browser without a server, you have a static site.

The full comparison

DimensionStatic siteWeb service
What runs at request timeNothing - the CDN serves built filesYour process
Free tierYes, with bandwidth and build minutesYes, but services spin down on inactivity
Cold startsNone - CDN is always warmYes on free tier (first request after idle)
Custom domainsYes, on free tier tooYes, but not on free instance type
Private networkNo - can’t talk to other services internallyYes - can reach pserv, KV, Postgres
Persistent disksNoYes
ScalingGlobal CDN, unlimited concurrent readsManual or autoscaling instances
TLSAuto-provisioned, freeAuto-provisioned, free, terminates at edge
PR previewsYesYes
Build artifactFolder of files (dist, build, public)Runnable process or container
Cost shapeBandwidth + build minutesInstance hours + bandwidth

A few of those rows decide cases on their own:

  • No private network on static sites. A static site cannot call your pserv over auth.onrender.com-style internal hostnames. It has to call the public URL. We dig into the workaround in the hybrid pattern step.
  • Free static sites get custom domains; free web services don’t. If you want mysite.com for free, ship it as a static site (or move the web service to a paid plan).
  • Static sites don’t sleep. A free web service spins down after 15 minutes of inactivity and cold-starts on the next request. Static sites never sleep - the CDN is always warm.

When you genuinely need both

Most real apps end up shipping both: a static site for the frontend, a web service for the API. That’s the right answer when:

  • Your frontend is a SPA (React, Vue, etc.) and you have a backend with auth, DB queries, or third-party integrations.
  • You want to take advantage of the free CDN for the frontend without giving up server logic for the backend.
  • You want to scale the frontend (free, infinite) and the backend (sized for actual load) independently.

We cover the wiring in step 04. For now, the takeaway: picking one doesn’t lock the other out. Two services in one Blueprint is the most common shape for a serious app.

What this tutorial walks you through

flowchart LR
  s1[01 the decision]
  s2[02 static sites]
  s3[03 web services]
  s4[04 hybrid pattern]
  s5[05 migration paths]

  s1 --> s2 --> s3 --> s4 --> s5

Steps 02 and 03 are the focused chapters for each service type. Step 04 covers the most common production shape. Step 05 covers what happens when you outgrow your initial choice.

A teammate asks: 'I'm shipping a Vite-built React app that talks to Stripe and Supabase from the browser. Do I deploy it as a static site or a web service on Render?'

What you learned

  • The decisive question: 'does my code need to run on a server to respond to a request?'
  • Most SPAs, marketing sites, docs, and blogs are static sites. APIs, SSR, websockets, and anything with persistent connections are web services
  • Static sites have a free CDN, free custom domains, no cold starts - but no access to Render's private network
  • Web services can talk to internal services and use disks, but free-tier services sleep on inactivity and don't get custom domains
  • Real apps often ship both: static frontend + web service API in the same Blueprint