If you run Adobe Commerce on Cloud, Fastly is already in the path for staging and production. Most of the time you touch cache settings in Admin and never look at VCL. That is fine until you need to lock /admin to office IPs, block a referrer spam wave, or force certain URLs to miss cache. Then someone mentions “custom VCL,” and the docs assume you know what a recv snippet is.
You do not need to become a Varnish expert. You need a mental model.
What VCL is
VCL stands for Varnish Configuration Language. Fastly runs a customized dialect on every edge node. The configuration is not one giant file you SSH-edit on a server. It is a compiled program made of subroutines (vcl_recv, vcl_hit, vcl_deliver, and others) plus hooks called snippets.

Each snippet is a small block of logic with a type and a priority. Type tells Fastly which subroutine it belongs to. Priority tells Fastly where it runs relative to other snippets in that same subroutine. Lower numbers run earlier unless the docs for your service say otherwise, so two snippets both named for blocking can still behave differently if their priorities differ.
On Commerce, the Fastly module already ships a stack of snippets: geo blocking, image optimization, Magento-specific cache rules, purge behavior, and more. Your custom code joins that queue. That is why a five-line allowlist snippet can still break checkout if it runs at the wrong priority or matches the wrong URL pattern.
Snippets vs dictionaries vs ACLs

Hard-coding IP addresses inside VCL works once. It ages badly.
Adobe’s docs push two companions:
Edge dictionaries hold key/value data you can reference from VCL and update from the network without publishing a new VCL version (for many use cases).
Edge ACLs hold IP addresses (and CIDRs) for allow or deny rules.
A typical allowlist flow on Commerce: create an ACL container in Stores > Configuration > Advanced > System > Full Page Cache > Fastly Configuration > Edge ACL, add IPs, then add a snippet in recv that returns 403 when /admin is requested and client.ip is not on the list. Adobe’s example looks roughly like this:
{
"name": "allowlist",
"dynamic": "0",
"type": "recv",
"priority": "5",
"content": "if ((req.url ~ \"^/admin\") && !(client.ip ~ allowlist) && !req.http.Fastly-FF) { error 403 \"Forbidden\"; }"
}The Fastly-FF check matters. Fastly uses internal requests; you usually do not want your block rule to catch those.
Regular snippets and dynamic snippets
Adobe documents two flavors:
Regular snippets belong to a specific VCL version. You create or edit them in Admin or via API, then activate that version.
Dynamic snippets are managed heavily through the Fastly API. You can change them without bumping the whole VCL version for the service, which helps when you are iterating under pressure.
For a first project, treat “regular + Admin UI” as the default. Reach for the API when the site is unhealthy and Admin will not load, or when you need to inspect an old VCL version line by line.
Where requests actually go
Commerce’s overview doc describes origin cloaking: customer traffic is meant to flow Fastly, then load balancer, then application. Direct origin access is blocked. Custom VCL runs at the Fastly layer, before your PHP workers see the request (unless you return(pass) and bypass cache for that URL).
So when you write VCL, you are deciding at the edge: cache this, pass it through, reject it, or rewrite it. You are not patching Magento controllers.
A few subroutines you will see in real configs
vcl_recv runs when a request arrives. Most custom Commerce examples use recv because that is where URL matching, ACL checks, and return(pass) live.
vcl_hit runs when Fastly finds an object in cache. TTL and grace logic often touch here.
vcl_deliver runs on the way out to the client. Debugging headers sometimes show up here.
You will see comment markers like # Snippet magentomodule_recv : 50 in exported VCL. The number is priority. When you add your own snippet, pick a priority that does not fight the module’s core logic unless you mean to override it.
Before you paste code from a blog post
Adobe is explicit: get Fastly working on the default configuration first. Then add one snippet, validate, activate, and hit a few real URLs (home, product, cart, admin, GraphQL if you use headless).
If you send snippets through the Fastly API as JSON, escape special characters in the content string. Admin uploads skip that annoyance.
Staging exists for a reason. A typo in VCL does not throw a PHP stack trace. It throws odd 403s, empty caches, or “why is Germany blocked?” at 2 a.m.
Where to read next
Adobe Commerce:
- Getting started with custom VCL
- Example walkthroughs under the same section: allowlist, blocking, bad referer, bypass to origin
Fastly (linked from Adobe):
VCL looks intimidating because the syntax is C-like and the failure modes are silent. For Commerce teams, it is mostly small guardrails at the edge: who can hit admin, which paths never cache, which bots get a 403. Start with one ACL and one recv snippet. Read the activated config export once so you see where your code sits in the pile. After that, the official cookbook pages stop feeling like a foreign language.
You May Also Like,
Fastly : How to set basic authentication for a specific pag



Fastly VCL for Adobe Commerce