Hi Team,
I have followed the documentation and set up SDI (Sling Dynamic Include) for one of the components on a page in my environment. TTL-based caching is enabled, and the page — which includes the dynamic component — is being successfully cached at the dispatcher. I have set the TTL value to 15 minutes.
When I accessed the page through the dispatcher, it was cached as expected. However, after 20 minutes, I logged into the dispatcher and navigated to the cached folder path — the cached page was still present.
Is this the expected behavior? That is, will the cached page remain on the dispatcher and only be refreshed with new data when a new request comes in? Also, should the timestamp of the cached file change after TTL expiry? In my case, the timestamp does not update.
Could this indicate an issue with my environment?
I'm also unable to verify if the latest content is being served because the data is coming from a third-party API.
Reference: Sling Dynamic Include Setup Guide
Can anyone please suggest?
Thanks in Advance
Veera
Views
Replies
Total Likes
Hi @veerareddyc1015,
Yes - this is expected.
Dispatcher does not automatically delete or refresh cached files when TTL expires.
Instead, TTL works like an expiration hint, telling Dispatcher that:
After TTL, the cached file is stale.
On the next request, Dispatcher will:
Check with AEM (via a HEAD
request).
If the content is unchanged, it continues serving the old file.
If the content has changed (based on headers like Last-Modified
or ETags), it fetches and caches the new version.
The timestamp of the cached file will not automatically change after TTL expiry.
It only changes when the file is replaced or rewritten after an actual cache miss or invalidation.
If your component pulls content from a third-party API:
SDI can help separate that block into its own request.
That dynamic include will then follow its own TTL and cache behavior.
To verify, check the response header of the SDI fragment itself (e.g., from /sling/dynamic/include...
).
Enable debug logging on Dispatcher to inspect what’s happening post-TTL (mod_cache
, mod_rewrite
, or custom headers).
Consider appending a version or hash param in your SDI fragment to force-refresh when API content changes.
Use curl -I
to check cache headers like X-Cache
or Age
to confirm whether a file is being served from cache or refreshed.
Dispatcher does not support partial use of TTL, if you enabled TTL based caching then it will be applied for all the caching.
The best way to achieve TTL based caching for SDI, is to disable SDI content cached at dispatcher and enable TTL based caching at CDN.
Hi @veerareddyc1015 ,
Dispatcher DOES NOT delete or refresh the cached file immediately after TTL expires.
Dispatcher waits for the next request to that cached file (HTML page or SDI fragment).
On that request:
- It makes a conditional request to AEM (HEAD or GET).
- If AEM says content is still valid (based on ETag or Last-Modified), the cache is retained.
- If AEM returns updated content, the cache is overwritten and the timestamp is updated.
Timestamp of file:
- It updates only if the file is rewritten (i.e., cache miss or revalidation leads to new content).
- It does NOT auto-update after TTL expiry if no one accesses the file.
SDI Fragment with TTL Caching
1. Enable SDI in your AEM component:
<!-- Add include in your HTL -->
<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"
data-sly-call="${clientlib.js @ categories='your.site'}"/>
<!-- SDI include -->
<!--#include virtual="/sling/dynamic/include/your/component/path.html" -->
2.Dispatcher Config: /enableTTL and /headers
/cache {
/enableTTL "1"
/statfileslevel "2"
/rules {
...
}
/headers {
"Cache-Control"
"Expires"
"Last-Modified"
"ETag"
}
}
3. Set TTL headers in your SDI component
In the component model or servlet (e.g., /apps/your-site/components/sdi/content):
response.setHeader("Cache-Control", "max-age=900, public"); // 15 minutes
response.setDateHeader("Expires", System.currentTimeMillis() + 900 * 1000);
4. Ensure fragment is cacheable separately
Access the fragment path like /sling/dynamic/include/your/component/path.html
Use curl -I or browser dev tools to check:
Cache-Control: max-age=900, public
Age: 480
X-Cache: HIT from dispatcher
Validate from Dispatcher
The fragment file under /var/www/html/... will remain until requested again.
Only upon the next hit after 15 mins, it gets revalidated (timestamp will update if content changed).
Check TTL headers:
curl -I https://your-site.com/sling/dynamic/include/your/component.html
Enable dispatcher debug logging for cache hits:
LogLevel debug
Manually delete cached fragment to confirm re-fetching
Regards,
Amit
Views
Replies
Total Likes
@veerareddyc1015 Did you find the suggestions helpful? If you need more information, please let us know. If a response resolved your issue, kindly mark it as correct to help others in the future. Alternatively, if you discovered a solution on your own, we'd appreciate it if you could share it with the community. Thank you.
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies