I have a graphql persisted query that pulls the content from AEM via graphql. When I change a content and publish, the updated content is shown in response body but the last-modified response header isn't updated reflect the content modified date
Topics
Topics help categorize Community content and increase your ability to discover relevant content.
The Last-Modified HTTP header is set by the GraphQL servlet / dispatcher cache layer, not by the actual content’s JCR modified date.
By default, AEM’s persisted GraphQL queries use the query definition / persisted query file as the basis for cache metadata, not the underlying content nodes.
When you publish new content:
The response body updates correctly (because the query result is re-evaluated).
But the Last-Modified header doesn’t reflect your content update, because AEM doesn’t automatically rebind that header to every JCR node’s lastModified property.
Here are what options/workarounds you have:
Enable ETag on the dispatcher/CDN layer so cache invalidation is based on the response body fingerprint, not JCR metadata.
Custom header with content metadata
Extend your persisted query endpoint to return a custom header (e.g., X-Content-LastModified) by looking up the max cq:lastModified (or your model’s date field) across the queried nodes.
This requires a Sling Filter or custom servlet wrapper.
Dispatcher/CDN cache invalidation
Instead of relying on Last-Modified, configure your publish/flush agents or GraphQL endpoint caching so that replication events invalidate cached responses.
This is the most common Adobe-recommended approach.
GraphQL response field
Add the lastModified property directly into your GraphQL schema model (using cq:lastModified from the fragment/page).
Then consumers can handle freshness inside the JSON body, rather than at the HTTP header level.