A recurring conversation: someone proposes a CDN to fix a slow store, someone else says Varnish, and the discussion becomes a preference rather than a diagnosis. They are not competing options.
What Varnish does
Varnish sits in front of Magento and keeps finished pages in memory. When a request comes in for a page it already has, Magento is not involved at all. The saving is not marginal: a cached page is served without the application doing any work.
That helps most with time to first byte, which is the part of the load that happens before the browser can start rendering anything. If your server is slow to respond, this is the lever.
What a CDN does
A CDN keeps copies of your static files, mainly images, stylesheets and scripts, on servers around the world. A visitor gets them from somewhere physically close instead of from your origin.
That helps most with everything after the first byte, and it helps disproportionately for visitors far from your server. If your customers are international and your server is in one country, this is the lever.
Which one you are missing
- Slow time to first byte, visitors nearby: you need page caching. Varnish.
- Fast first byte, slow full load, international visitors: you need a CDN.
- Both slow: Varnish first, because it also reduces the load that makes everything else slow.
- Fast on repeat visits, slow on the first: your cache is being missed or purged too aggressively, which is a configuration problem rather than a missing component.
The part that goes wrong
Cache invalidation. When a price changes, the cached page has to be replaced, and getting that wrong is worse than having no cache: customers see stale prices, or every change flushes everything and you effectively have no cache at all.
Magento has built-in support for this and it needs configuring rather than assuming. It is also the first thing we check when a store has caching that appears to be working and is not.