Hoppa till innehållet
Ketryon
Blogg

8 min läsning

Cookies och CDN-cache på Vercel för inloggade sidor

Vercel slutar CDN-cacha svar med Vary: Cookie, vilket påverkar säkerhet, svarstider och belastning på personliga sidor.

Av Skriven med AI-stöd utifrån källan

Dimma över mörka kustklippor och ett lugnt hav
Foto: Phill Brown på Unsplash

Vad Vercel har ändrat

Vercel har ändrat hur plattformens CDN hanterar svar som innehåller HTTP-headern Vary: Cookie. Sådana svar lagras inte längre i den delade CDN-cachen. Besökaren får fortfarande svaret, men nästa begäran måste åter gå till applikationen eller dess ursprungskälla i stället för att återanvända en lagrad kopia.

Ändringen beskrivs i Vercels ändringsnotis från 30 september 2026. När ett svar nekas lagring av den här anledningen visar x-vercel-cache värdet MISS, medan Vercels Runtime Logs anger vary_key_denied:cookie som orsak.

Det viktiga är att skilja mellan att en begäran innehåller cookies och att svaret anger Vary: Cookie. Cookies används ofta för inloggning, sessionshantering, samtycke, språkval och analys. Deras blotta närvaro stoppar inte automatiskt CDN-cachen genom den här ändringen. Det är Vary-headern från din app, ditt ramverk eller en mellanliggande proxy som är avgörande.

Vary talar om för en cache vilka delar av begäran som kan påverka svaret. Med Vary: Cookie säger servern i praktiken att innehållet kan bli annorlunda när cookie-headern är annorlunda. Cachen skulle därför behöva hålla isär svar för olika cookie-värden.

Problemet är att cookie-headern ofta är nästan unik för varje besökare. Sessionscookies och analyscookies skapar då en stor mängd varianter som sällan kan återanvändas. En CDN-cache ger mest nytta när många besökare kan dela samma svar. Om nästan varje begäran får en egen variant försvinner en stor del av poängen med cachen.

Ändringen påverkar inte andra stödda Vary-headers. Den är specifikt riktad mot headers med så många möjliga värden att delad caching blir olämplig.

Varför ändringen är relevant för säkerheten

En delad CDN-cache ligger mellan besökaren och din applikation. Den är byggd för att återanvända samma innehåll till flera besökare. Det passar bra för publika produktsidor, dokumentation, bilder och API-svar som är identiska för alla. Det passar dåligt för ett konto, en dashboard eller ett API-svar som innehåller personliga uppgifter.

Vary: Cookie kan se ut som en lösning eftersom cachen får instruktionen att skilja svaren åt med hjälp av cookie-headern. Men det gör en känslig säkerhetsgräns beroende av att varje cachevariant skapas och matchas exakt som avsett. Samtidigt blir cachen fragmenterad av sessions- och analysvärden.

Vercels nya beteende är därför ett tydligare skyddsräcke: om svaret säger att det varierar med cookies behandlas det inte som lämpligt för delad CDN-lagring. Det minskar risken att ett personligt svar oavsiktligt hanteras som delbart innehåll och undviker lagring av varianter som sannolikt aldrig återanvänds.

Det betyder däremot inte att inloggade sidor automatiskt är säkra. CDN-regeln ersätter inte behörighetskontroller i din app. Servern måste fortfarande kontrollera sessionen och säkerställa att användaren får läsa rätt konto, organisation, projekt och databasrader. Om du använder Supabase bör åtkomsten inte enbart skyddas av vad gränssnittet visar. Databasens regler och serverkod måste också avgränsa användarens åtkomst.

Det är även viktigt att skilja mellan private och no-store i Cache-Control:

  • private markerar att svaret inte ska lagras av en delad cache, men kan tillåta privat lagring i användarens webbläsare.
  • no-store instruerar cachar att inte lagra svaret alls och passar när även lokal lagring är olämplig.
  • Ett publikt cache-direktiv passar bara när innehållet verkligen kan delas mellan besökare.

För svar som faktiskt beror på cookies rekommenderar Vercel att du behåller Vary: Cookie och använder Cache-Control: private. För särskilt känsliga eller snabbt föränderliga svar kan du behöva en striktare policy, beroende på hur applikationen fungerar.

Vad som kan hända med prestanda och kostnader

När ett svar inte längre hämtas från CDN-cachen måste applikationen skapa eller hämta det på nytt. Det kan innebära att en Vercel Function körs, att serverkod verifierar en session och att data läses från exempelvis Supabase. Svarstiden kan då bli längre än för ett cacheträffat svar, särskilt om databasen eller en extern tjänst ligger i en annan region.

Belastningen kan också flyttas nedåt i systemet. En route som tidigare återanvände lagrade svar kan börja orsaka fler funktionskörningar, databasfrågor och anrop till externa API:er. Om din användning debiteras utifrån sådana resurser kan kostnaden påverkas. Effekten beror på trafikmönster, regioner, databasarbete och hur mycket av sidan som renderas på servern.

Det här gäller bara de berörda svaren. Statiska filer, bilder, JavaScript och andra cachebara resurser kan fortfarande levereras från Vercels nätverk. En inloggad sida behöver därför inte bli långsam i sin helhet bara för att själva HTML-svaret eller ett personligt API-anrop inte lagras i CDN-cachen.

En vanlig onödig prestandaförlust uppstår när en publik route skickar Vary: Cookie trots att innehållet är identiskt för alla. Det kan hända om headern läggs till globalt i middleware, i en proxy eller genom en generell serverkonfiguration. Besökarnas analyscookies kan då skapa intrycket att sidan behöver variera, fast applikationen aldrig läser dem när innehållet byggs.

I det läget bör Cookie tas bort från Vary, men först efter att du har verifierat att svaret verkligen är oberoende av cookies. Kontrollera bland annat språk, experiment, samtycke, valuta, geografisk anpassning och inloggningsstatus. En liten personlig detalj i serverrenderad HTML räcker för att svaret inte ska delas öppet.

För genuint personliga sidor är utebliven CDN-cache normalt rätt beteende. Optimera då i stället den dynamiska vägen:

  • Hämta bara den data som behövs för den aktuella vyn.
  • Lägg index på databasfrågor som körs ofta.
  • Undvik att göra oberoende externa anrop efter varandra.
  • Placera funktioner och databas så att nätverksresan blir rimlig.
  • Cacha opersonlig underliggande data separat från det personliga svaret.
  • Låt statiska delar av gränssnittet byggas och levereras separat när arkitekturen tillåter det.

Försök inte kringgå ändringen genom att flytta ett unikt användar-id till en egen Vary-header. Det återskapar samma problem under ett annat namn och kan göra cachebeteendet svårare att förstå.

Så granskar du din app

Börja med de routes där du förväntar dig CDN-cache eller där svarstiden nyligen har förändrats. Testa den driftsatta produktionsmiljön, eftersom lokal utveckling inte visar hur Vercels CDN faktiskt behandlar svaret.

Öppna webbläsarens nätverkspanel och granska svarens headers. Leta särskilt efter:

  • Vary
  • Cache-Control
  • CDN-Cache-Control
  • Vercel-CDN-Cache-Control
  • x-vercel-cache
  • Set-Cookie

Ett ensamt x-vercel-cache: MISS bevisar inte att Vary: Cookie är orsaken. En vanlig miss kan uppstå när innehållet ännu inte finns i cachen och därefter lagras för kommande begäranden. Kontrollera därför Runtime Logs och leta efter vary_key_denied:cookie. Den orsaken visar att svaret serverades men inte skrevs till CDN-cachen.

Testa med utloggat läge, inloggat läge och separata testkonton. Om produkten har organisationer eller arbetsytor bör kontona tillhöra olika sådana. Jämför både innehåll och headers. Målet är att upptäcka om en route är personlig utan en tydlig privat cachepolicy eller om en publik route i onödan varierar med cookies.

Gå sedan igenom var headern sätts. Den kan komma från route-koden, ett ramverk, middleware, en auth-lösning, en proxy eller ett backend-API som Vercel vidarebefordrar. Kontrollera den färdiga responsen i produktion i stället för att enbart söka efter texten i kodbasen.

Följ även utvecklingen i Vercels observability och i din databas. Titta efter förändringar i funktionernas körningar, svarstider, databasfrågor, externa anrop och cacheutfall. Jämför representativa perioder och skilj på publika routes och inloggade routes. En ökning kan vara helt väntad för personligt innehåll men signalera en felaktig header på publika sidor.

En praktisk beslutsmodell

Använd innehållets verkliga beteende som utgångspunkt, inte önskemålet om snabbare caching.

  • Om svaret är identiskt oavsett cookies kan du ta bort Cookie från Vary och därefter kontrollera att övriga cachekrav är uppfyllda.
  • Om svaret innehåller användar-, konto- eller organisationsspecifik information ska det inte ligga i en delad CDN-cache. Behåll variationen och sätt en uttrycklig privat cachepolicy.
  • Om bara en mindre del är personlig kan du överväga en publik, cachebar grund och hämta den privata delen genom ett autentiserat API.
  • Om sidan sätter en cookie men annars är publik bör du kontrollera både Set-Cookie och övriga cacheheaders, eftersom även detta kan göra svaret olämpligt för CDN-lagring.
  • Om du inte vet varför Vary: Cookie finns ska du inte bara ta bort det. Spåra först vilken kod eller tjänst som satte headern och vilket beteende den försöker skydda.

Avsluta granskningen med en tydlig checklista:

  • Publika routes skickar inte Vary: Cookie utan ett verkligt behov.
  • Personliga routes har en uttrycklig privat cachepolicy.
  • Behörighet kontrolleras på servern och i databasen.
  • Runtime Logs har granskats efter vary_key_denied:cookie.
  • Separata konton kan inte få varandras data.
  • Funktioner, databas och externa API-anrop följs upp efter ändringen.
  • Statiska och publika delar hålls åtskilda från personlig data där det är praktiskt.

Om granskningen visar att prototypens caching, autentisering och dataåtkomst har vuxit ihop kan nästa steg vara att gå från prototyp till produkt med tydliga gränser mellan publikt och personligt innehåll.


Källa: Vercel changelog

Vill du veta vad just ditt bygge skulle kräva?

Tre frågor, sen får du en klickbar skiss gratis.

Berätta var du står
← Alla artiklar

Fler tjänster från Ketryon

Behöver du bara en sida eller en film?

Två fristående tjänster för dig som inte behöver ett helt abonnemang — en landningssida eller en lanseringsfilm, gjord av samma person.