---
title: esi
summary: null
url: https://www.fastly.com/documentation/reference/vcl/statements/esi
---

```
esi();
```

**Available in:** all subroutines

Flags a request for parsing [Edge Side Includes](https://www.w3.org/TR/esi-lang/). Parsing occurs after the `vcl_deliver` subroutine has finished, and while this statement is available in all subroutines, it is only effective if executed in `vcl_fetch`.

Fastly only supports the following ESI directives:

- include
- comment
- remove

When specifying the src URL with `<esi:include src=... />`, the URL can be either an absolute or relative URL. If you specify an absolute URL, you must prefix it with `http://` or `https://`.

```html
<esi:include src="https://example.com/index.html" />
```

ESI requests are made to your Fastly service as new client requests, with a copy of the HTTP header information from the original client request. If a hostname is specified in the ESI `src` attribute, the `Host` header of the new request will be set to the value of that hostname, otherwise the `Host` header of the ESI request will be the same as for the parent request.

In the above example, the ESI parser takes `example.com` in the URL as the `Host` request header value (i.e., `req.http.host`) and creates a new request to your service. Although you can specify any URL in an ESI include, and the hostname does not have to be one of your service's configured [domains](https://www.fastly.com/documentation/reference/glossary#term-domain) you can only forward that request to one of your configured [backends](https://www.fastly.com/documentation/reference/glossary#term-backend). In general, it is often better to use relative links for ESI includes to avoid confusion.

In ESI child requests, the `req.topurl` variable is set to the value of `req.url` from the parent request.

## Best practice

Consider only applying ESI to response types likely to contain ESI directives. For example, `text/html` is often used with ESI, but `image/png` is unlikely to have ESI directives.

## Interaction with compression

In order for the ESI parser to detect `<esi:...` tags in the response stream, the response must not be compressed. Compressed responses will obfuscate the ESI tags and they will be delivered unprocessed to the client. This means that ESI cannot be performed on content compressed at origin, since it's not possible to decompress content in VCL services. However, it is usually possible to prevent origin servers from applying compression by removing the `Accept-Encoding` header from requests before forwarding them:

```vcl context="sub vcl_miss { ... }"
unset bereq.http.accept-encoding;
```

If content is received from origin uncompressed but statically compressed at the edge using `beresp.gzip` or `beresp.brotli`, ESI will also fail, since the ESI processing occurs after the `vcl_deliver` stage. However, dynamic compression, which occurs at the moment of delivery, allows for compression of responses _after_ ESI processing has occurred. [Learn more about compression options](https://www.fastly.com/documentation/guides/concepts/compression).

## Other limitations and constraints

Be aware of the following limitations when using ESI:

- **Sequential processing:** ESI tags are processed sequentially, not concurrently, because when the parser encounters an ESI include tag, it will make the child request, wait for the HTTP response from the child request to complete, splice that response into the response stream, and then continue parsing the parent response. It's therefore often a performance bottleneck to have a large number of ESI tags in a single document.
- **No shared state:** It is not possible for edge logic within a child request to pass data back to the parent. However, it is possible to know whether a request is an ESI child request by checking the value of `req.topurl`.
- **CDATA is disabled by default:** Parsing ESI tags within [CDATA](https://www.w3.org/TR/xml/#sec-cdata-sect) is not enabled by default. You can set `esi.allow_inside_cdata` variable to `true` if needed.

We also impose limits on the number of ESI directives that can be processed on each request:

- The maximum depth of `esi:include` processing is `5`
- The maximum total `esi:include` processing fragments is `256`
