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
- Build-time API traffic was far higher than the pages being rebuilt justified.
- Preview deployments amplified the problem because every push generated more upstream calls.
- Local development still depended on the production CMS API.
- 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.
- Incoming CMS requests were normalized before lookup so
masterRefdid not explode the cache key space. - Cached payloads became the default read path.
- Prismic webhooks triggered revalidation whenever content changed.
- 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.