Skip to content
FFormhook
Back to blog

Blog

Serverless contact forms: what "serverless" actually means here

· 4 min read

"Serverless" started life as a precise term: your code runs as a function, on someone else's infrastructure, and you never provision, patch, or scale a server yourself. Applied to contact forms, the term has drifted - it now gets used for two genuinely different setups, and which one you pick changes how much work you're signing up for.

Here's the distinction, and where a hosted form backend fits into it.

The two things "serverless contact form" can mean

Search that phrase and you'll find two different answers mixed together:

  • You write a function. An AWS Lambda, a Cloudflare Worker, a Vercel or Netlify function - a small handler you deploy that receives the POST, sends an email through a provider like SES or Resend, and returns a response.
  • You write no backend code at all. Your form POSTs directly to a hosted service that already exists - no function to write, deploy, or version.

Both are "serverless" in the narrow sense: neither involves a machine you SSH into and patch. But they land in very different places on the effort scale.

Option A: your own function

Writing your own handler gives you full control over the payload, the email template, and the storage destination. That control comes with real ownership:

  • Cold starts. A function that hasn't run recently takes a moment to spin up, which shows up as a slow first submission on quiet sites.
  • Email deliverability is yours. SPF, DKIM, and DMARC records, a sending reputation to protect, and a provider account to configure and monitor.
  • Spam filtering is yours. Nothing stops a bot from POSTing straight to your function's URL unless you build rate limiting, a honeypot, or a CAPTCHA challenge yourself.
  • Storage is yours, if you want any history at all. Without a database call inside the function, a submission that fails to email is just gone.

This is the right tradeoff when the form triggers real business logic - writing to a CRM, kicking off a workflow, anything past "get the message to a human." For a plain contact form, it's a lot of undifferentiated plumbing to own.

Option B: no backend code at all

The other reading of "serverless" skips the function entirely. Your <form> POSTs to an endpoint that already exists, run by someone else, where receiving, spam-filtering, notifying, and storing are already built and already running. You write zero backend code and deploy nothing - there's no function of yours to cold-start, patch, or monitor, because there's no function of yours in the picture at all.

The tradeoff is control: you get the provider's spam filter, the provider's retention policy, the provider's notification channels - not bespoke logic of your own. For a form whose entire job is "get the submission to me reliably," that's rarely a real cost.

Which one actually fits a contact form

Most contact forms don't need custom workflow logic - they need to reach a human without getting lost or filtered as spam. If that's the whole job, writing and owning a function is solving a problem you don't have: you'll spend real hours on SPF records and rate-limit logic to reinvent what a hosted backend already does. Reach for your own function when the form feeds something more than an inbox - a database write, a paid workflow, a multi-step process a generic service can't express. (For the broader case of what a form backend does day to day, see what is a form backend.)

Formhook: the endpoint that already exists

Formhook is the second kind of serverless. Point a form at https://formhook.app/f/{apiKey} and there's nothing to deploy, cold-start, or patch - not even a function. Spam filtering (a honeypot field, rate limiting, and Cloudflare Turnstile on by default), storage, a searchable dashboard, and notifications - email plus web push on every tier including Free - are already running before you write a line of code. Outgoing webhooks, with automatic Discord, Slack, and Teams detection, cover the cases where you do want to hand a submission to another system, without you writing that receiving function either.

The Free tier handles 250 submissions a month with no card required. Pro adds file uploads up to 10MB and a verified sending domain with reply-to; Studio raises the ceiling to 25,000 submissions a month for teams. See the docs for the integration itself, or pricing for the full breakdown.

Ship a working form in one line

EU-hosted, submissions kept forever, push notifications on every tier.

Start free

No credit card · read the docs

Keep reading