Skip to content
New storyWe built Skald to count visitors. It caught an AI-key thief.
SkaldEvery visit, truly told.

set-up · vercel · log drain

Vercel log analytics, from a log drain

Vercel log analytics starts with Vercel's own request logs. A log drain posts every request your site answered to Skald, with nothing to change in your site's code.

Vercel log analytics is reading the requests Vercel served for your site, not only the browsers that ran a script. Vercel keeps its request logs to itself, but a Log Drain, on Vercel Pro or Enterprise, posts them to an address you give it. Skald reads Vercel's drain format directly.

30-day free trial · no card · we set it up within one working day · free to self-host

vercel log drain · sample recordssource
  1. 09:14:02 203.0.113.24 "GET /pricing" 200 static "GPTBot/1.2"AI · training
  2. 09:14:04 198.51.100.140 "GET /docs" 200 lambda "Claude-User/1.0"AI · live fetch
  3. 09:14:05 198.51.100.23 "GET /docs" 200 static ref "chatgpt.com"people · from ChatGPT
  4. 09:14:07 203.0.113.66 "GET /blog" 200 edge "bingbot/2.0"search
  5. 09:14:09 192.0.2.91 "GET /wp-login.php" 404 static "python-requests"bots · probe

Sample records from a drain. A script tag would have seen one of these five: the person.

[01] your vercel plan

What Skald sees on your Vercel plan

Server log analytics needs a record of every request. On Vercel that record is a Log Drain, and Log Drains are a Vercel Pro and Enterprise feature. Your plan is in Vercel's Settings > Billing.

tap one

A log drain: everything

Vercel posts every request to Skald. You see people, AI assistants such as ChatGPT, Claude and Perplexity, search crawlers, bots, and your own traffic, in five groups that add up to the whole log. Add the script tag too, for forms, clicks and bookings.

SeenLog drain
People and their sourcesyes
AI live fetches and training crawlsyes, each one named
Search crawlersyes
Bots and scannersyes
Forms, clicks, bookingswith the script tag beside it

[02] where skald runs

Skald runs beside Vercel, not on it

Skald keeps its history on a disk and runs its own schedule all day. Vercel's functions stop between requests and keep no disk, so Skald runs somewhere that stays up, and Vercel sends it your site's traffic.

  1. Hosted Skald

    We set it up for you on app.skaldanalytics.com within one working day. Then you add the drain.

  2. Render or Railway

    One service from the Skald image with a disk. On Render a disk needs a paid instance: without one the history is lost at every restart.

  3. A small server

    Docker on any small Linux server, with a name such as stats.example.com and HTTPS, which sign-in needs.

[03] the log drain

Set up the Vercel log drain, step by step

In Skald, Settings > Connections > Send this site's visits to Skald, then Vercel. The dialog shows your send address and makes a sending token. Then in Vercel:

  1. Team Settings > Drains > Add Drain > Logs

    Projects: your site's project. Sources: static, edge, lambda, plus external and redirect if you rewrite or redirect to other domains. Leave out build. Environments: production.

  2. Sampling: 100%

    A sample would undercount every figure. Skald never scales one up.

  3. Destination: custom endpoint

    https://stats.example.com/traffic-ingest/example.com?format=vercel, with your own Skald and site. Format: JSON or NDJSON; both work.

  4. Custom header

    Authorization: Bearer <your sending token>. Create the drain: Vercel tests the address, and Skald answers 200.

  5. Keep IP Address Visibility on

    Team Settings > Security & Privacy. Without the visitor's address Skald cannot tell people apart, so it refuses those requests and counts them as rejected.

[04] what is kept

What Skald keeps from each Vercel record

The time, the visitor's address, the host, method, path and query, status, referrer, user agent, response size and the request id. Everything else in the record is dropped before anything is written.

  • Function output, build logs and background revalidations are not requests: Skald skips them and counts them as skipped.
  • A request whose function wrote several log lines is read once, by its request id.
  • A delivery Vercel retries is kept once.
  • Records for host names that are not your site's, such as a test's sample records, are kept but never counted.

Vercel's signature (optional)

Vercel signs each delivery with the drain's secret. To require it, the person who runs your Skald puts the secret in an environment variable and names it in Skald's config. A delivery with a wrong or missing signature is then refused, even with a token.

config.yml · on skald's server
ingest:
  enabled: true
  drains:
    example.com:
      vercel_secret_env: SKALD_VERCEL_DRAIN_SECRET   # the variable's name, not the secret

A secret that is named but cannot be read refuses every delivery, never lets one through. Details: HOSTING.md on GitHub.

[05] what a log cannot see

Add the script tag for forms, clicks and bookings

A drain sees requests, not what happens inside a page. The tag reports forms started and sent, clicks, scroll depth and booking embeds such as Calendly. It needs nothing on Vercel: it posts to Skald directly.

To serve it from your own domain instead, so fewer ad blockers stop it, add two rewrites to vercel.json and tell Skald your site's address. Skald leaves those two paths out of the drain's figures.

vercel.json · first-party tag, optional
{
  "rewrites": [
    { "source": "/traffic-beacon", "destination": "https://stats.example.com/traffic-beacon" },
    { "source": "/traffic-js/:path*", "destination": "https://stats.example.com/traffic-js/:path*" }
  ]
}

Put your own Skald's address in place of stats.example.com. In Next.js, the tag goes in the root layout.

[06] check it

Check that Vercel's logs reach Skald

Open your site in a private window. Within minutes the visit shows in Skald's live view, and the dialog's Test says what arrived, or why it was refused, with the fix.

You seeWhat to do
Vercel says the drain test failedYour Skald is not reachable over HTTPS yet, or the site name in the address is wrong.
Nothing in Live after 10 minutesCheck the drain's sources and environments, and the site's host names in Skald.
Rejected: no visitor addressTurn IP Address Visibility on in Vercel.

What it does not do

  • No drain on Vercel Hobby. There, Skald has only the script tag, which never sees AI crawlers, search crawlers or bots.
  • No country in Vercel's records. Countries come only from a GeoIP file on Skald's server; without one they say Not recorded.
  • On a Next.js site, a page opened by a click inside the site is not counted from the drain: its records carry no request headers. Only the first page of each visit shows.
  • Skald cannot run on Vercel itself. It runs beside it, hosted or on a server you choose.
  • No middleware road: Vercel's middleware runs before the response exists, so it cannot see the status.

questions

Vercel log analytics FAQ

Straight answers, including what Skald does not do.

Which Vercel plan do I need for Skald?

Log Drains are a Vercel Pro and Enterprise feature, so the full picture needs Pro or Enterprise. On Hobby, Skald can use only the script tag: you see people, sources, forms and bookings, but not AI assistants or crawlers, because they never run scripts.

Can Skald run on Vercel?

No. Skald needs an always-on process and a disk for its history, and Vercel's functions stop between requests and keep no disk. Skald runs beside your site instead: hosted Skald, or your own copy on Render, Railway or a small server, and Vercel posts the site's requests to it.

Why not use Vercel middleware instead of a log drain?

Vercel's Routing Middleware runs before the response is made, so it cannot see the status or the cache result of a request. A log drain is sent after Vercel answered, with the status, so Skald uses the drain.

Why do my Vercel visits have no country?

Vercel's drain records carry no country. Skald looks each address up in a GeoIP country file when the person who runs your Skald server has set one. Without a file, the country says Not recorded, and it is never guessed.

Does a Next.js site on Vercel count every page?

Not from the drain alone. A click inside a Next.js site loads no new HTML page, and the drain's records carry no request headers, so Skald cannot tell a click from a prefetch and counts neither. Only the first page of each visit shows as a page view. The script tag reports in-site page views as its own events, kept apart.

Is the drain's data checked like a server log?

Yes. Skald keeps each drain record as one line and an independent audit recounts it with its own reader. A day the two counts disagree on is withheld, never guessed.

$ tail -f access.log | skald

See what AI does with your site. Free for 30 days.

No card. We set up hosted Skald for you within one working day, or you self-host it free. Every line of your log, sorted and added up.

Start free trial Live demo