vcl_deliver subroutine is executed before the first byte of the response is emitted to the client. Deliver happens on every response individually, including responses delivered from cache and those received from a backend, making it an ideal place to add debugging information or user-specific session data that cannot be shared with other users.
Common uses for the deliver subroutine are:
- making changes for each specific user, such as adding a
- adding CORS or other performance or security related HTTP headers
- performing changes to the TCP connection, such as enabling BBR and/or manipulating
- if required, restarting to jump back to
To support caching at Fastly's scale, objects are stored across numerous physical servers and each individual VCL flow is processed by up to two machines. The (random) server that initially handles the client request (in
vcl_recv) and ultimately delivers the response (here in
vcl_deliver) is the delivery node. However, if clustering is enabled, the server that is responsible for fetching the object from the backend and storing it is a different machine known as the fetch node. When a request is eligible for clustering, it is handed off from the delivery node to the fetch node immediately after
hash (provided there is no local cache hit on the delivery node). The request is passed back to the delivery node immediately before
deliver. Because the fetch node is not responsible for the client request, any changes made to the
req object while a request is on the fetch node will not be retained when control moves into the
Clustering is disabled automatically if there is a hit on the delivery node, after a
restart, or if you
vcl_recv. It can also be disabled manually by setting the
Fastly-No-Shield HTTP header to
vcl_recv. Where clustering is disabled, all VCL flow stages happen on the delivery node and share state.
To see this subroutine in the context of the full VCL flow, see using VCL.
The code example Enable modern web security headers to all responses is a good example of the
vcl_deliver subroutine in use:
The following limited-scope VCL functions and variables are available for use in this subroutine (those in bold are available only in this subroutine, those available in *all* subroutines are not listed):