From 4cd89353758fc82fff19047268f53b93dd97f4b6 Mon Sep 17 00:00:00 2001 From: Hariom Balhara Date: Tue, 8 Aug 2023 18:20:30 +0530 Subject: [PATCH] fix: SWR cache header on Vercel (#10624) --- packages/trpc/server/createNextApiHandler.ts | 30 +++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/trpc/server/createNextApiHandler.ts b/packages/trpc/server/createNextApiHandler.ts index f9a47a8c3f..a6ad997b3e 100644 --- a/packages/trpc/server/createNextApiHandler.ts +++ b/packages/trpc/server/createNextApiHandler.ts @@ -58,19 +58,35 @@ export function createNextApiHandler(router: AnyRouter, isPublic = false, namesp if (isPublic && paths) { const ONE_DAY_IN_SECONDS = 60 * 60 * 24; + const FIVE_MINUTES_IN_SECONDS = 5 * 60; const cacheRules = { - session: `no-cache`, - i18n: `no-cache`, - // Revalidation time here should be 1 second, per https://github.com/calcom/cal.com/pull/6823#issuecomment-1423215321 - "slots.getSchedule": `no-cache`, // FIXME - cityTimezones: `max-age=${ONE_DAY_IN_SECONDS}, stale-while-revalidate`, - "features.map": `max-age=${ONE_DAY_IN_SECONDS}, stale-while-revalidate`, // "map" - Feature Flag Map + session: "no-cache", + + // i18n data is user specific and thus should not be cached + i18n: "no-cache", + + // FIXME: Using `max-age=1, stale-while-revalidate=60` fails some booking tests. + "slots.getSchedule": `no-cache`, + + // Timezones are hardly updated. No need to burden the servers with requests for this by keeping low max-age. + // Keep it cached for a day and then give it 60 seconds more at most to be updated. + cityTimezones: `max-age=${ONE_DAY_IN_SECONDS}, stale-while-revalidate=60`, + + // Feature Flags change but it might be okay to have a 5 minute cache to avoid burdening the servers with requests for this. + // Note that feature flags can be used to quickly kill a feature if it's not working as expected. So, we have to keep fresh time lesser than the deployment time atleast + "features.map": `max-age=${FIVE_MINUTES_IN_SECONDS}, stale-while-revalidate=60`, // "map" - Feature Flag Map } as const; const prependNamespace = (key: string) => (namespace ? `${namespace}.${key}` : key) as keyof typeof cacheRules; const matchedPath = paths.find((v) => prependNamespace(v) in cacheRules); - if (matchedPath) defaultHeaders.headers["cache-control"] = cacheRules[prependNamespace(matchedPath)]; + if (matchedPath) { + const cacheRule = cacheRules[prependNamespace(matchedPath)]; + + // We must set cdn-cache-control as well to ensure that Vercel doesn't strip stale-while-revalidate + // https://vercel.com/docs/concepts/edge-network/caching#:~:text=If%20you%20set,in%20the%20response. + defaultHeaders.headers["cache-control"] = defaultHeaders.headers["cdn-cache-control"] = cacheRule; + } } return defaultHeaders;