Skip to content
$_ setuptracking
Recipes

Umami on Vercel + Neon: Free Self-Hosted Analytics in 5 Minutes

6 min read
Light blue flat illustration of monitor with cloud sync icon phone and database stack

Goal: a fully working Umami install in under 5 minutes, deployed to Vercel’s free tier with a Postgres database from Neon (also free), wired to your custom subdomain. Total cost at any reasonable indie scale: €0/mo.

This is the absolute lowest-friction self-host setup in 2026. Zero servers, zero Docker, zero cron, zero TLS config — Vercel handles all of it. The catch: you’re trusting two SaaS providers (Vercel + Neon) for hosting, but the data and code remain yours. If either disappears, you redeploy elsewhere in 5 minutes from the same git repo. Tested 2026-05-02 on Vercel Hobby + Neon Free.

Why Umami (and the trade-offs)

Umami is the smallest cookieless tracker in the field — a 21KB-or-less script, a clean React dashboard, MIT licensed, written in TypeScript by a single maintainer. It’s perfect for personal sites, side projects, and indie SaaS that want pageviews + sources + browser/OS/country breakdowns without any of the enterprise baggage.

What you give up vs Plausible:

  • No EU-only hosting guarantee (Vercel + Neon US-default unless you pay for EU edge)
  • Less polished docs / smaller community
  • No event funnels (just custom events as raw counts)

What you give up vs Matomo: basically everything except pageviews. If you need goals, ecommerce, attribution — go straight to Matomo.

Create a Neon Postgres database (1 minute)

  1. Sign up at neon.tech with email or GitHub.
  2. Create new project → Postgres 16 → region: pick EU Frankfurt if you want EU data residency (GDPR), US East for cheaper Vercel routing.
  3. Project name: umami. Default branch: main.
  4. Once created, go to Connection Details → copy the postgres:// connection string. It looks like: postgres://username:[email protected]/neondb?sslmode=require

Save it somewhere — we’ll paste into Vercel in 30 seconds.

Free tier: 0.5 GB storage, 191 compute hours/month — enough for any indie site with <1M events/mo. Above that, $19/mo Pro plan or migrate to a CX23 + self-hosted Postgres.

Read:  PostHog on Hetzner: Self-Host Product Analytics with Docker (€15.99/mo, 45 min)

Before you budget around these numbers: Hetzner’s Cost-Optimized CX and CAX servers run on older hardware in deliberately limited supply. Hetzner listed the whole line as unavailable for new orders on 13 August 2026, and part of its shared-resource range was still flagged that way on 9 September. If the box you need cannot be ordered, the fallback is the CPX line at roughly three to four times the price — CPX22 at about €19.49/mo against the CX23’s €5.49. Check availability before you commit to a plan.

Fork Umami on GitHub

Go to github.com/umami-software/umami → click Fork. You’ll get github.com/your-username/umami.

(Why fork instead of clone? You’ll want to pull upstream updates and re-deploy. Forking gives you a controllable git history.)

Deploy to Vercel (90 seconds)

  1. Go to vercel.com/new, log in with GitHub.
  2. Import your forked umami repo.
  3. Framework preset: Vercel auto-detects Next.js. Don’t change anything.
  4. Environment Variables — add two:
    DATABASE_URL = 
    HASH_SALT    = 
  5. Click Deploy.

Vercel builds (Next.js Prisma migrate + Next build) for ~2 minutes. When it finishes, you have a working Umami at your-umami-xxxx.vercel.app.

First login + add your custom domain

Visit the Vercel URL. Default credentials:

Username: admin
Password: umami

Log in immediately. Settings → Profile → change password. Don’t skip this — those default creds are publicly known.

Now wire your subdomain (so events look like first-party):

  1. Vercel Project → Settings → Domains → Add → analytics.your-site.com.
  2. Vercel shows the DNS records you need. Two options:
    • CNAME (preferred for subdomain): analyticscname.vercel-dns.com
    • A record (apex domain): 76.76.21.21
  3. Add the record at your DNS provider. TLS is auto-issued (Vercel uses Let’s Encrypt under the hood).

Within 1–2 minutes, https://analytics.your-site.com serves your Umami dashboard. The Vercel URL keeps working too — both point at the same deployment.

Add a website + paste the snippet

  1. Umami dashboard → Settings → Websites → Add website.
  2. Name + domain. Save.
  3. Click the website → Edit → Tracking code → copy the <script> snippet.
  4. Paste into the <head> of your tracked site, OR if you want first-party tracking (avoids ad-blockers), use:
    <script defer
      src="https://analytics.your-site.com/script.js"
      data-website-id="YOUR-UUID-HERE"></script>

First pageview should appear in the dashboard within 30 seconds.

What just happened (mechanism)

  • Umami app — a Next.js 14 server-rendered app deployed as Vercel Functions. The dashboard is React; the /api/send ingest endpoint is a serverless function that writes to Postgres.
  • Neon Postgres — your event store. Two tables you’ll care about: website_event (every event) and session (deduplicated sessions, salted-hash-based). Auto-suspends after 5 min idle to save free-tier compute.
  • Vercel Edge Network — serves the static dashboard JS/CSS from CDN, routes /api/send requests to the Functions runtime in your selected region.
  • HASH_SALT — server-side salt for the daily-rotating visitor hash. Unique sessions are computed as hash(IP + User-Agent + website-id + salt + day). Salt rotation is tied to the env var; we don’t rotate ours daily, so your “unique visitor” count is stable per HASH_SALT lifetime.

Cookies set on visitors: zero. Same legitimate-interest GDPR basis as Plausible — no consent banner needed.

The free-tier limits (real numbers)

ServiceFree includesYou’ll hit limit at
Vercel Hobby100 GB bandwidth, 100k function invocations~3M events/mo (each event is one function call)
Neon Free0.5 GB storage, 191 compute hrs~1M events stored (then need to prune)
Combined practical limit~500k events/mo before you start watching

Above that point, you have three escalation paths:

  1. Vercel Pro ($20/mo) + Neon Pro ($19/mo) = $39/mo and ride the SaaS curve.
  2. Move just the database to Hetzner ($5/mo VPS with self-hosted Postgres) and keep Vercel Hobby. Total: $5/mo.
  3. Move both to a self-hosted box. Same Hetzner CX23 can run Umami too.

Auto-prune old data (so you stay free)

The cheapest way to stay under Neon’s 0.5 GB: prune events older than N days. Umami doesn’t ship a cron — but Vercel Cron Jobs are free and can call any endpoint.

Add a file to your fork: app/api/cron/prune/route.ts:

import { headers } from 'next/headers';
import prisma from '@/lib/prisma';

export async function GET() {
  const auth = (await headers()).get('authorization');
  if (auth !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('unauthorized', { status: 401 });
  }
  const cutoff = new Date(Date.now() - 365 * 86400 * 1000);
  await prisma.websiteEvent.deleteMany({ where: { createdAt: { lt: cutoff } } });
  return Response.json({ pruned_before: cutoff.toISOString() });
}

Add a vercel.json:

{
  "crons": [{ "path": "/api/cron/prune", "schedule": "0 4 * * 0" }]
}

Add env var CRON_SECRET in Vercel (any random string). Push, redeploy. Now every Sunday at 04:00 UTC, events older than 365 days are deleted. Adjust cutoff to your retention policy.

Updating Umami (every 4–6 weeks)

Umami releases roughly monthly:

  1. In your fork on GitHub: Sync fork → Update from upstream → Discard my changes if not customizing.
  2. Vercel auto-deploys when main branch updates. Watch the deployment for migration errors.
  3. Check Umami changelog for breaking schema changes.

Total time per update: ~1 minute.

3-year cost

Item3-year total
Vercel Hobby€0
Neon Free€0
Domain (subdomain — no extra)€0
Total€0

Yes, really €0 if you stay under ~500k events/mo. The closest commercial alternative (Plausible Cloud Starter at €9/mo) is €324 over 3 years. Umami on Vercel is the price-per-feature king for indie scale.

When NOT to use this setup

  • You exceed 1M events/mo regularly. The free tiers won’t sustain you and the Vercel+Neon Pro stack ($39/mo) is now more than Plausible Cloud Starter. Switch.
  • You need goals/funnels/attribution. Umami has custom events but no funnel builder. Matomo is a better fit.
  • EU-only data residency required. Vercel’s free tier doesn’t pin to EU regions. Pick Neon EU Frankfurt at minimum, but Vercel Functions still execute globally on Hobby. Self-host on Hetzner instead.
  • You’re skeptical of vendor lock. While Umami code is portable, your specific deployment depends on Vercel + Neon staying in business. Self-hosting on a VPS removes both dependencies.

Troubleshooting

Build fails with “P3009: migrate found failed migrations”. Neon went into “branch was reset” state. In Neon Console → Branches → Reset branch → main. Then redeploy on Vercel.

Default password “umami” still works after I changed it. The login page caches credentials per-deployment. Hard refresh (Ctrl+Shift+R), incognito, then re-login.

Events not appearing in dashboard but script loads. Browser ad-blocker. Open DevTools → Network → look for send request. If blocked, deploy under your own subdomain (analytics.your-site.com) so the request is first-party — uBlock Origin won’t block it.

Compute hours warning from Neon. Auto-suspend isn’t kicking in. Settings → Compute → enable auto-suspend at 5 min. Reduces idle hours dramatically.

Next

Server and vendor prices re-checked against the Hetzner price API on 13 August 2026.


Found this useful?

Try the Stack Picker to get a personal recommendation, or browse the install recipe library.