Run it in production
What RoutingCat adds to your pages on Vercel or Cloudflare Workers, what visitors and records go through when RoutingCat can’t be reached, how routed pages work with caches, and how to upgrade, pause or remove RoutingCat.
Plan for its cost on each page
- RoutingCat picks a visitor’s variants locally, from routing data it refreshes in the background, with no call to RoutingCat on the page’s path.
- On Vercel, it runs in your root
middleware.ts, as Vercel’s Routing Middleware on Node.js, before Vercel’s cache, on every page request, prefetches of your links included: its matcher leaves out Astro’s built assets, its image endpoint, server islands, actions, paths under/api/and any path with a file extension. An endpoint elsewhere runs through it as a page does. Its own work takes about a millisecond per request, and Vercel bills its runs to your account. - On Cloudflare Workers, every request but Astro’s built assets reaches RoutingCat’s Worker first. It decides Astro’s pages and hands the rest, such as paths under
/api/, to Astro at once; an endpoint elsewhere runs through it as a page does. On a routed page it adds about 2 to 5 ms of CPU, which Workers Paid bills at some cents a million views. - Nothing RoutingCat sends delays a response. The middleware or the Worker sends its records after the response,
Astro.locals.routingcat.trackand.identifysend within the request’s lifetime without holding the response, and the browser posts its reports without waiting for an answer. <RoutingCat />adds two scripts to each page: the head snippet, 1,244 bytes inline, and the tracker, which Astro bundles with your scripts.- A page that carries every variant adds each variant’s markup to its HTML: a hero with three variants typically adds 1 to 3 KB, compressed.
Expect changes within about 2 minutes
- Deploys and acts reach visitors within about 2 minutes on the server instances that serve traffic. An instance idle for longer serves its next request with the routing data it had, then refreshes, so on a quiet site a paused variant can show once more.
- A page’s first production deploy, on Vercel, serves the page’s defaults for those 2 minutes, recording arrivals but no decisions. On Workers, the build waits up to a minute for routing data that carries its own changes, and the Worker embeds it, so a new page routes from the deployment’s first request; otherwise it, too, serves its defaults until the Worker refreshes.
- Right after a deploy that adds a page, a slot or a variant, a new server instance can hold its first routed requests for up to a second, while it fetches routing data that knows them.
Know what happens when RoutingCat is unreachable
Visitors always get a page.
| What can’t reach RoutingCat | Pages | Records |
|---|---|---|
| A running deployment, for routing data | Routing continues with the routing data each server instance last had; a new instance starts from the copy its build embedded. Acts and new learning reach visitors once RoutingCat is back. | Unaffected, unless ingestion is down too |
| A running deployment, for ingestion | Unaffected | The middleware’s or the Worker’s records and your server’s events are retried once, then lost, and so are the browser’s reports. A backend calling the events API gets an error, and can retry safely, since each event carries its id. |
| A build | The build ships as usual, with one line in its log, and its deployment shows your defaults. | That deployment records nothing until a deploy that reaches RoutingCat. |
| The command | It exits with code 4: run it again later. |
A deployment whose build registered nothing records no visits and no conversions, from your server or from the browser. After each deploy, look for RoutingCat’s line in the build log, or run
npx routingcat doctor, and redeploy if the build didn’t register.
Keep caches from hiding decisions
- A prerendered page stays cached by your host. It is the same HTML for every visitor, with every variant in it. On Vercel, RoutingCat’s middleware runs before Vercel’s cache and adds each visitor’s cookies, and the variants picked for them, to every cached copy Vercel serves. On Workers, the Worker serves the page from your built files and adds the same.
- A page rendered at each request is one visitor’s, so RoutingCat’s integration keeps it out of shared caches: it takes
s-maxageand the CDN cache headers off its response, and turns Astro’s route cache off for that render. On Vercel, a page rendered on demand that the adapter’sisror a route rule keeps for every visitor carries every variant instead, as a prerendered page does. - Never cache routed pages’ HTML in front of your host. A cache that serves your HTML before RoutingCat runs gives every visitor the cached variant, and nothing is recorded:
statuswarns that render beacons outnumber decisions, anddoctornames a page a shared cache answered. Caching assets there is fine. - On Cloudflare Workers, the Worker sends every routed response with
Cloudflare-CDN-Cache-Control: no-store, so that Cloudflare’s own cache keeps none of them. Workers Cache stays off for that Worker, and the zone’s rules, such as Cache Everything, must let routed pages’ HTML through: Cloudflare’s settings gives each one. - Cloudflare in front of Vercel works, since Cloudflare doesn’t cache HTML unless told to. Turn on its visitor-location headers: in Cloudflare, your domain → Rules → Settings → Managed Transforms → “Add visitor location headers”. Without them, visitors’ local times come from Cloudflare’s edge or from their country, and
doctorandstatussay so.
Upgrade
- Upgrade the
routingcatpackage with your package manager. It carries the command, the integration, the components and the agent skill, so they stay level. - Run
npx routingcat init. It brings the skill level with the package, unless the skill was edited here, which it keeps;doctorreports a skill older than the package. It also brings the note inAGENTS.mdup to date, if you have it. - Deploy. Visitors get the new version only with your deploy, and builds install the version in your lockfile.
Learning, settings and acts never need an upgrade: they reach the version you deployed within about 2 minutes.
Pause or remove RoutingCat
- Turn routing off for the whole site with
npx routingcat set routing=off. Every page shows its defaults, and visits and conversions are still recorded.npx routingcat set routing=onresumes from what routing had learned. See Routing settings. - Remove it from your code in one change, then deploy:
- in each routed page, each
<RoutingCatSlot>, replaced by the default variant’s content; - the
routingcat/folder; - the
Astro.locals.routingcat.trackand.identifycalls in your server code, theroutingcat.track,routingcat.identifyandroutingcat.linkcalls in your pages’ scripts, androutingcatPropertiesin your PostHoginit; <RoutingCat />in your layout,routingcat()in your Astro config’sintegrations, androutingcat.config.ts;- on Vercel,
middleware.ts, or RoutingCat’s part of it if you had one before; on Workers,src/worker.ts, and the Wrangler settingsinitset:mainas it was before,run_worker_firstand the version metadata binding; .routingcat/in.gitignore, the skill’s folders,.agents/skills/routingcat/and.claude/skills/routingcat/, and the package;- the note for coding agents in
AGENTS.mdandCLAUDE.md, from<!-- routingcat -->to<!-- /routingcat -->, andAGENTS.mditself if the note is all it holds.
- in each routed page, each
- Archive the site. Archiving revokes the site’s keys and its host binding, stops collection, and deletes the site’s records within 90 days, unless you ask otherwise. The site’s owner asks RoutingCat to archive it. To have the records deleted sooner, ask for their deletion.