Run it in production
What RoutingCat adds to your pages, what visitors and records go through when RoutingCat can’t be reached, how routed pages work with caches in front of Vercel, and how to upgrade, pause or remove RoutingCat.
Plan for its cost on each page
- RoutingCat’s own work takes about a millisecond per page. The proxy picks a visitor’s variants locally, from routing data it refreshes in the background, with no call to RoutingCat on the page’s path.
- The proxy runs on every page request, prefetches of your links included; RoutingCat’s matcher entry leaves out assets, API routes and
/_rc. On Vercel it runs as Routing Middleware, before Vercel’s cache, and Vercel bills its runs to your account. On a site that had no proxy before, each run also adds Vercel’s own time to a page: in RoutingCat’s tests, from nothing measurable to about 20 ms, depending on the region. - Nothing RoutingCat sends delays a response. The proxy sends its records after the response, the browser posts its reports without waiting for an answer, and server-side
trackandidentifysend after the response. - The browser code adds about 11 KB, gzipped, to each page’s first load:
<RoutingCat />, its reports and its web vitals.
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 serves the page’s defaults for those 2 minutes, recording arrivals but no decisions.
- 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 proxy’s records and server-side 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
- Vercel’s own cache works as usual. Each combination of a static routed page is prerendered and cached. The proxy runs before the cache and serves each visitor their combination, so cached pages still route, and RoutingCat’s cookies and
Server-Timingheader leave them cached. - Never cache routed pages’ HTML in front of Vercel. A CDN that serves your HTML from its own cache bypasses the proxy: every visitor gets the cached variant, and nothing is recorded.
statusthen warns that render beacons outnumber decisions. Caching assets there is fine. - Keep server-rendered routed pages out of shared caches. Such a page renders each visitor’s own variants, and Next.js marks it uncacheable; never override that with a shared
Cache-Control. - 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. Behind Cloudflare, visits also reach more of Vercel’s regions, so more of them meet a new server instance after a deploy.
Upgrade
- Upgrade the
routingcatpackage with your package manager. It carries the command, the SDK 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, the
routingcat.decidecall and the slot components, replaced by the default variant’s content; - each static page’s wrapper route,
app/…/routingcat/[rc]/page.tsx, and theroutingcat/folder; - the
trackandidentifycalls, androutingcatPropertiesin your PostHoginit; <RoutingCat />in each root layout,withRoutingCat()innext.config, RoutingCat’s part ofproxy.ts, or the whole file ifinitwrote it,routingcat.config.ts, 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, the
- Archive the site. Archiving revokes the site’s keys and its Vercel 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.