How to improve the backend performance of your AEM application

Writing performant code for AEM is always a bit challenging, especially given the flexibility in the page composition. Even when performance testing clearly shows that the rendering should be improved, it's hard to almost impossible to find the right spot where to start with code improvements and what to change.

This presentation will outline the areas in which rendering time is typically spent, and show you common patterns, which impact performance and how you can avoid them. Also it will demonstrate ways to identify the code where you should invest your time to improve performance.

Henry Kuijpers

When adapting a Resource to a ValueMap (and that happens very very often, for the same resources), a ValueMap backed by a fresh JcrPropertyCache is created every time, which makes the cache not very useful - Is there any plan for improving this? (See: )

Henry Kuijpers

The ValueMap cache is *not* shared by all Resource objects for that path, check the ticket.

Isn't 1 ms = 10^6 ns?

Jörg Hoh

I think you are right ... It should have been µs (micro-seconds).

Henry Kuijpers

Are you planning to make an EditableTemplateManager (or similar) that can provide some caching for template (structure) access? If the right events are handled etc, it shouldn't be too hard to keep the cache up-to-date?

Jörg Hoh

in the making

Peter Puzanovs

How did we get the frequency of resource object creation?

Jörg Hoh

I extracted it directly from the logfiles containing all those stacktraces (using a mix of perl and shell)


What was the setup used during taking the measurements? What was the repository size? How would the usage of DocumentNodeStore change the results (timings)?

(see answer in talk video)

Henry Kuijpers

If we should not create new ResourceResolvers all the time (or at least not too many) and it is also not recommended to have long-open resourceresolvers (open in @Activate, close in @Deactivate) - how would you recommend backend services that need service resource resolvers to work? (Especially when accessing parts of the repository that the user's resource resolver cannot access)

Jörg Hoh

You can and should still create new ResourceResolvers whenever it's necessary. But not more frequent. I've seen often cases where a method to read from a "protected area" was opening a new ServiceResourceResolver and closing it afterwards. Which is fine unless you call this method many times. Then it would make sense to reuse this RR across all invocations.

Henry Kuijpers

Would you recommend in-memory caches (or something similar) to avoid the often not-successful lookups to finally get to the right Resource?

Jörg Hoh

In memory-caches are helpful, but aware of the scope. So resource objects are bound to a ResourceResolver, and if you close the RR the resource is invalid. Then you need to think about permissions etc. I recommend to start with caching on a request level, and just share a cache across multiple requests if there's no other choice.


I am not very adept at Sling but doesn't the ResourceResolver provides caching (like JPA EntityManagers) by default so that requests to the same paths do not end up in repeated repository access?

Jörg Hoh

No, that's not the case. It was discussed once, but then rejected.


Should Sling Models just support a "lazy" injection then?


They would have to bind the session and resource for the whole lifecycle of the model - which kills the cache reuse.

Yegor Kozlov

Is it a good idea to avoid adapting resources ? for example, resource.adaptTo(Asset.class).getMetadata(....) is more expensive than direct accessing the metadata ValueMap.


I guess so, because it was always better (faster) to use resource.getValueMap() instead of for example resource.adaptTo(ValueMap.class)...

Radu Cotescu

You're breaking the contract by directly reading the content via a ValueMap, rather than reading the Asset's metadata via its own Java API.

Roy Teeuwen

Are there any plans to make the performance of the AEM Cloud author system better in handling operations on nodes with a lot of (grand)children? Deleting a page with children sometimes even fails with timeouts

Jörg Hoh

Deleting subtrees in AEM is normally more than just deleting a few resources, it includes checking and adapting references, de-activating pages/assets, ... But I cannot speak for the AEM implementations, I am too far away for it.

Does it make a difference to use field injections vs constructor injections?

Jörg Hoh

that should not make any difference