Serving localized pricing at the edge: geo-based currency and price books without the origin round trip
Every storefront that sells across borders faces the same tension. Shoppers expect prices in their own currency, with their own taxes, and often their own regional discounts, but every price variant is a cache key. Serve one cached page and the Brazilian shopper sees dollars; serve a hundred variants and your cache hit ratio collapses. The edge is the one place where you can have both: one origin template, many localized prices, all served without a round trip.
Why localized pricing kills caches
Price is the most personalized element on a product page that is not actually personal. Two shoppers in different countries can look at the same SKU and need different numbers: converted currency, VAT-inclusive versus exclusive display, regional promotions, and sometimes entirely different price books negotiated by market. If the page is rendered at the origin with the price baked in, each combination is a distinct cache entry, and the long tail of country-currency combinations means most of those entries are rarely hit. You end up with a cache full of cold variants and an origin doing nearly as much work as if there were no cache at all.
The naive fixes all have costs. Rendering prices client-side with JavaScript keeps the cache warm, but it delays the most important number on the page and creates a visible price flash that erodes trust. Edge-side includes (ESI) for the price fragment work, but they add an origin fetch per fragment on cache miss and complicate the cache topology. The cleaner approach is to treat price as data the edge already knows how to localize, applied at serve time from a compact price map.
The price map pattern
The pattern is simple in concept. The origin renders the product page once, with price placeholders instead of prices: a token carrying the SKU, the list price in a base currency, and the pricing context (which price book, which tax treatment). The edge holds a price map, a compact table refreshed every few minutes, mapping each SKU and region to a resolved price: final amount, currency, tax treatment, and any active regional promotion.
On each request, the edge resolves the shopper's region from the usual signals, looks up the SKU in the price map, and rewrites the placeholders with the localized price before serving. The page body stays a single cache entry per region group, and region groups can be coarse, since the price substitution handles the fine-grained differences. A storefront selling in forty countries might keep six cached page variants while serving forty localized price experiences.
Keeping the map fresh without origin round trips
The price map has to be fresh, because a stale price is worse than a slow price. The good news is that price data is tiny compared to page data. A full price map for a catalog of fifty thousand SKUs across forty regions is a few megabytes, small enough to push to every edge POP on a schedule or via a lightweight subscription channel. Refreshing every five minutes keeps flash-sale pricing accurate while the page cache itself can live for hours, because the volatile part of the page has been factored out of the cache key.
Currency conversion adds a second freshness axis: exchange rates move throughout the day. The standard approach is to convert at publish time into each target currency rather than converting at serve time with a live rate. Published prices change less often than rates move, which is a feature, not a bug. Shoppers see stable prices; the business absorbs the rate noise inside its pricing margins. When rates move enough to matter, the next price map refresh carries the new converted prices, and no page cache is invalidated.
Taxes and the display problem
Tax display rules are where localization gets genuinely tricky, because they change what the number means, not just its size. European shoppers expect VAT-inclusive prices; US shoppers expect tax added at checkout; some markets require the tax breakdown displayed inline. The price map should carry the tax treatment per region, not just the amount, and the edge template logic should render the right display format: inclusive price with a small "incl. VAT" note, or exclusive price with the tax added later.
The key discipline is to keep tax logic out of the page cache. Tax rules change rarely, but when they do, a cached page with the old treatment baked in serves wrong numbers until it expires. Treating the tax display as another substitution, driven by the same region resolution, keeps the cached page tax-agnostic.
What stays on the origin
Not everything belongs at the edge. Promotional pricing with complex eligibility, cart-level discounts, loyalty pricing, and anything tied to an individual account should stay on the origin or render client-side after authentication. The edge price map covers public prices: list prices, regional price books, currency conversion, and tax display. That is the bulk of what shoppers see on product and category pages, and it is exactly the part where cache efficiency matters most.
The rule of thumb: if the price is the same for every anonymous shopper in a region, the edge can serve it. If it depends on who the shopper is, it does not belong in the shared cache. Draw that line cleanly and you get localized pricing at edge speed without the origin round trip, and a cache hit ratio that survives international expansion.