Platform

How we reduced 75% of Prismic billing with a cache layer

A pragmatic cache layer and webhook-driven invalidation flow cut CMS costs by 75 percent and made frequent shipping viable again.

When I joined Indiahikes, one of the first business problems attached to engineering was simple: the CMS bill was too high and it was actively shaping delivery behavior.

Prismic sat at the center of a large content operation. That meant every build, preview, and local workflow kept leaning on the same external API. The team had started optimizing around vendor limits instead of product speed.

What was breaking down

  1. Build-time API traffic was far higher than the pages being rebuilt justified.
  2. Preview deployments amplified the problem because every push generated more upstream calls.
  3. Local development still depended on the production CMS API.
  4. Shipping less often had become a cost-control tactic, which is usually a smell.

The design principle

The goal was not to cache blindly. The goal was to make upstream content access predictable without introducing stale-content chaos.

Prismic changes its masterRef whenever content updates. If you cache full request URLs including masterRef, the cache churn is constant. If you ignore the ref without an invalidation story, you risk serving stale data forever.

The useful move was to normalize the cache key and pair it with explicit invalidation.

function normalizePrismicCacheKey(url: string) {
  const parsed = new URL(url);
  parsed.searchParams.delete("ref");
  return parsed.toString();
}

What we built

We introduced a cache service in front of Prismic.

  1. Incoming CMS requests were normalized before lookup so masterRef did not explode the cache key space.
  2. Cached payloads became the default read path.
  3. Prismic webhooks triggered revalidation whenever content changed.
  4. Revalidation refreshed cached content so readers still got the latest version without the application constantly hammering Prismic.

That changed the shape of the system:

  • application traffic stopped mapping directly to Prismic traffic
  • developers gained room for preview environments and local work
  • deployment frequency no longer had a direct billing penalty

Why this worked

The important insight was operational, not academic. We did not need a perfect theoretical model of every content mutation. We needed a system that respected how the team actually shipped.

Webhook-driven invalidation gave us that middle ground:

  • stable cache keys
  • cheap reads
  • controlled refresh points
  • enough confidence to deploy often

Outcome

The cost reduction was the visible win, but the more important result was behavioral:

  • CMS spend dropped by about 75 percent
  • the team became more comfortable shipping frequently
  • preview workflows stopped feeling expensive
  • platform decisions started supporting product velocity again

What I took from it

Platform work is valuable when it changes the economics of shipping. This was one of those cases. The cache layer was not flashy, but it removed a recurring tax on every engineer touching the system.

That is the kind of infrastructure work I care about most: small enough to reason about, boring enough to trust, and meaningful enough to change team behavior.