---
title: Avoid request proxies
description: >-
  Request proxies add a network hop between the browser and Shopify, increasing
  latency for every resource. Shopify's CDN and edge network already optimize
  delivery, so an additional proxy layer usually adds cost without benefit.
source_url:
  html: >-
    https://shopify.dev/docs/storefronts/themes/best-practices/performance/avoid-request-proxies
  md: >-
    https://shopify.dev/docs/storefronts/themes/best-practices/performance/avoid-request-proxies.md
api_name: liquid
---

# Avoid request proxies

Point your storefront domain straight at Shopify instead of routing requests through a CDN, a web application firewall, or custom middleware. Each layer in front of Shopify's edge is another hop the browser pays for on work that Shopify already does close to the shopper.

***

## Why

A request proxy sits between the browser and Shopify's servers. Every request from the browser goes to the proxy, which makes its own request to Shopify, receives the response, and forwards it back. This extra hop adds latency to every resource on the page, including the HTML document, API calls, and any assets routed through the proxy.

The added latency directly affects [TTFB](https://web.dev/ttfb/), the time until the browser receives the first byte of HTML, and [LCP](https://web.dev/lcp/), because the LCP image or text can't render until the document arrives. If the proxy also handles asset requests, then [FCP](https://web.dev/fcp/) is delayed as well.

Proxies are sometimes used to cache responses, but this creates its own problems. Cached HTML can show stale product data, incorrect inventory, or outdated prices. Cache invalidation is hard to get right, and failures are often silent. RUM data from cached responses doesn't reflect the performance that customers get when the cache misses.

Shopify already runs a global CDN and edge network that handles caching, compression, TLS termination, and geographic distribution. Adding another proxy layer in front of this duplicates work that Shopify already does.

***

## How

### Identify whether a proxy is in use

A proxy sits between the browser and Shopify's origin servers. Here's how to detect one.

Check DNS resolution. Run `dig` or `nslookup` on your storefront domain. Shopify's documented setup points the apex record at a Shopify IP address and the `www` record at `shops.myshopify.com`, so anything else in the chain is a third party. Follow the `CNAME` chain rather than only reading the final address:

```bash
# Show the full CNAME chain and final answer
dig +noall +answer www.example.com


# Check the nameservers, which reveal a CDN managing the zone
dig +short NS example.com
```

If the nameservers belong to a CDN or the `CNAME` points at a proxy service's hostname instead of `shops.myshopify.com`, then requests are passing through that service before they reach Shopify.

Compare response headers between your domain and the origin. Open Chrome DevTools, go to the **Network** panel, and select the initial document request, or use `curl -sSI` against both hostnames. Compare the headers on your custom domain against the same page on the `.myshopify.com` domain, because the difference is the signal, not the presence of any single header:

* A `server` header naming a proxy service rather than the value Shopify returns.
* A `via` header, which names an intermediary explicitly.
* `x-served-by`, `x-cache`, `x-proxy-cache`, or `age` headers that appear only on the custom domain.
* Two layers of the same header, such as a duplicated `x-cache` or nested `via` entries, which means the request traversed two caching layers.

Compare TTFB with and without the proxy. If you can access the store directly through Shopify's URL, which is the `.myshopify.com` domain, then compare the TTFB of the proxied domain against the direct domain. Request the same path several times from the same network and compare medians rather than single runs, because cold connections and cache state both add noise. A consistent difference in TTFB points to proxy overhead. Measure this yourself for your own store rather than relying on a general figure, because the overhead depends on the proxy's location relative to both the visitor and Shopify's edge.

### Understand common proxy setups

Proxies appear in several configurations:

* **Custom domain routing through a CDN**: the domain points to a CDN service, such as Cloudflare, Fastly, or Akamai, which forwards requests to Shopify. This adds a hop even when the CDN has no cache hit.
* **Security or WAF services**: a web application firewall inspects traffic before forwarding it to Shopify. This adds processing time on every request.
* **Custom middleware**: a server-side application that intercepts requests to modify headers, inject content, or apply redirects before passing the request to Shopify.

### Recognize a Cloudflare proxy

Cloudflare is the most common proxy placed in front of Shopify, and it's also the hardest to detect by reading headers, because [Shopify's own CDN is Cloudflare-backed](https://shopify.dev/docs/storefronts/themes/best-practices/performance/platform). A `cf-ray`, `cf-cache-status`, or `server: cloudflare` header is present on a normal Shopify response and proves nothing on its own.

Distinguish the two cases like this:

* Compare against the origin. Request the same path on the `.myshopify.com` domain and on your custom domain, then compare headers. A merchant-owned Cloudflare zone in front of Shopify typically produces two `cf-ray` values, a duplicated `cf-cache-status`, or an additional `age` or `via` entry that the origin response doesn't have.
* Check who controls the zone. Run `dig +short NS` on the domain. Cloudflare nameservers mean the zone is managed in a Cloudflare account, which is the prerequisite for proxying.
* Check whether the record is proxied. In the Cloudflare dashboard, a record routed through Cloudflare's network is marked **Proxied**, and one that only resolves DNS is marked **DNS only**. For a Shopify storefront, **DNS only** is the configuration that sends traffic straight to Shopify's edge.

If the zone is proxied, then also review Cloudflare's content-modification features, which duplicate or conflict with work Shopify already does. Shopify already minifies and compresses theme assets with Brotli and gzip and serves images through its own CDN, so asset minification and image optimization features add processing without a corresponding benefit. Script-rewriting features are the higher risk: they change how and when theme JavaScript executes, which can break module loading and delay interactivity even when every metric on the document request looks unchanged.

**Caution:**

Cache hit rate is usually the wrong thing to optimize here. Improving the hit rate on cacheable pages doesn't help the requests that matter most, because cart, session, and checkout traffic carries cookies and can't be served from a shared cache. Every `/cart` update, Section Rendering API call, and add-to-cart request bypasses the proxy cache and pays the full extra hop, and these are the interactions where shoppers notice latency. A high hit rate on collection and product HTML can coexist with slow cart interactions, so measure the cart and session paths separately before concluding the proxy is harmless.

### Remove unnecessary proxies

If the proxy exists only for caching or CDN purposes, then it's redundant. Shopify's edge network already provides these. Remove the proxy by pointing your domain's DNS directly to Shopify.

If the proxy exists for a specific function, such as WAF rules, header manipulation, or A/B testing, then evaluate whether that function is worth the latency cost on every request. In many cases, the same functionality is available through Shopify apps, theme code, or Shopify's built-in features without adding a network hop.

### If you must keep a proxy

Some setups require a proxy for compliance or security reasons. If you keep one:

* Route only HTML document requests through the proxy. Let assets, such as images, CSS, and JavaScript, load directly from Shopify's CDN.
* Set HTML cache TTL to five minutes or less.
* Monitor cache hit rates and invalidation failures.
* Compare RUM metrics for cached and uncached page loads so that you know what real performance looks like.

### Fix the real performance problems

Proxies are often adopted to mask slow page loads rather than fix them. Address the root causes:

* **Slow TTFB**: simplify Liquid rendering. See [Avoid deeply nested Liquid loops](https://shopify.dev/docs/storefronts/themes/best-practices/performance/avoid-deeply-nested-liquid-loops).
* **Large JavaScript bundles**: remove or defer third-party scripts. See [Audit and remove third-party scripts](https://shopify.dev/docs/storefronts/themes/best-practices/performance/audit-remove-third-party-scripts).
* **Slow images**: use responsive images served from Shopify's CDN. See [Use responsive images](https://shopify.dev/docs/storefronts/themes/best-practices/performance/use-responsive-images).
* **Multiple asset domains**: serve everything from Shopify's CDN to reduce DNS lookups and connection overhead. See [Serve assets from Shopify CDN](https://shopify.dev/docs/storefronts/themes/best-practices/performance/use-shopify-cdn).

***

## Examples

### Confirm a proxy from the command line

Run the same three checks against your custom domain and against the `.myshopify.com` origin, and compare the pairs. Start with DNS, which tells you who's in the path before any request is made:

## Resolve the chain

## Terminal

```bash
# The full CNAME chain for the storefront hostname
dig +noall +answer www.example.com


# Who runs the zone
dig +short NS example.com
```

A `CNAME` that ends at `shops.myshopify.com` is the documented Shopify setup. A `CNAME` into a proxy service's hostname, or nameservers belonging to a CDN, means requests reach that service first.

Next, compare response headers on the same path:

## Compare headers

## Terminal

```bash
curl -sSI https://www.example.com/collections/all > proxied.txt
curl -sSI https://example.myshopify.com/collections/all > origin.txt


diff origin.txt proxied.txt
```

Read the `diff`, not either file on its own. A `via` entry, a second `cf-ray`, a duplicated `x-cache` or `cf-cache-status`, or an `age` header that appears only in `proxied.txt` are each a caching layer that the origin response doesn't have.

Finally, measure the latency the extra hop costs. Take several samples from one network and compare medians, because a single request tells you about connection state, not about the proxy:

## Sample TTFB

## Terminal

```bash
for host in www.example.com example.myshopify.com; do
  echo "$host"
  for i in $(seq 1 10); do
    curl -sS -o /dev/null \
      -w '%{time_starttransfer}\n' \
      "https://$host/collections/all"
  done | sort -n | awk 'NR == 5 {print "  median", $1}'
done
```

### Interpret the result

The three checks answer different questions, and you need all three before you act:

* DNS resolves through a third party, headers are identical, and median TTFB matches. The zone is hosted elsewhere but the record isn't proxied, which is the **DNS only** configuration. Nothing to remove.
* DNS resolves through a third party, headers show a second caching layer, and median TTFB is consistently higher on the custom domain. The proxy is in the request path and it's costing you that difference on every document request.
* Headers show a second caching layer, but median TTFB is close. The proxy is still in the path. Measure the cart and Section Rendering API requests before concluding it's harmless, because those can't be served from a shared cache and pay the full hop every time.

***

## Testing

* Open the **Network** panel in Chrome DevTools and select the document request. Check the **Timing** tab to see DNS lookup, connection, TLS, and waiting (TTFB) broken out separately. A proxy adds visible time to DNS, connection, or waiting.
* Compare the **Timing** breakdown for the same page loaded through the proxy domain and through the `.myshopify.com` domain. The difference in the **Waiting (TTFB)** row shows the proxy overhead.
* Use the **Network** panel **Waterfall** column to check whether assets are also routed through the proxy. Assets should load directly from `cdn.shopify.com`, not through an intermediary.
* Run a [WebPageTest](https://www.webpagetest.org/) test from a geographic location near your target audience. Compare runs with and without the proxy to measure the latency difference under realistic network conditions.
* Check the **Console** panel for mixed-content warnings or CORS errors that proxies sometimes introduce by modifying response headers.
* Time the cart and session paths, not just the document. Add an item to the cart with the **Network** panel open and check the **Timing** breakdown for the `/cart` requests and any Section Rendering API calls. These bypass the proxy cache, so they show the proxy's uncached overhead.

***

## References

* [The Shopify platform](https://shopify.dev/docs/storefronts/themes/best-practices/performance/platform)
* [Avoid deeply nested Liquid loops](https://shopify.dev/docs/storefronts/themes/best-practices/performance/avoid-deeply-nested-liquid-loops)
* [Audit and remove third-party scripts](https://shopify.dev/docs/storefronts/themes/best-practices/performance/audit-remove-third-party-scripts)
* [Use responsive images](https://shopify.dev/docs/storefronts/themes/best-practices/performance/use-responsive-images)
* [Serve assets from Shopify CDN](https://shopify.dev/docs/storefronts/themes/best-practices/performance/use-shopify-cdn)

***
