We use Openfire in production (around 15k concurrent users) with the hazelcast cluster. We have disabled JVM cache for User and Roster.
While presence stanza with available=null is processed on user login, rosters are being fetched twice - one for broadcasting user’s presence to its rosters [PresenceUpdateHandler. broadcastUpdate(Presence update)] and again for probing roster’s presence to logged-in user [PresenceUpdateHandler.initSession(ClientSession session)].
As we have disabled Roster cache, we have to fetch rosters from DB twice. So, there is a scope for optimisation here. Please consider the same.