Defining cache settings in application.cfc?

Is it inefficient to define caches in application.cfc, and should I move them to .CFConfig.json? I’ve got about 10 of them defined.

Google tells me that I should define them in onApplicationStart() to avoid the extra overhead of defining them on every request via pseudo constructors, but this doesn’t work (ai slop?) I currently a bunch of them defined in application.cfc because I like having my caches in sync with my code and not having to change things in .CFConfig.json whenever a cache is added/changed.


OS: Ubuntu 24.04 (Noble)
Java: OpenJDK 21
Tomcat Version: 11.0.6
Lucee Version: 6.2.6.19

@Redtopia, Defining caches in Application.cfc is perfectly fine. If the caches are specific to your application, keeping them there is a good approach because your cache configuration stays together with your code. .CFConfig.json is useful when cache settings need to be managed separately or shared across multiple applications. Keeping a single source of configuration and avoiding duplicate cache definitions in both places helps prevent configuration mismatch.

Thank you, and yes I’ve been doing it this way for years. But as far as performance is concerned, it seems like a lot of work is being done on every request because the caches have to be defined as pseudo-constructors. With 10 of them, there’s a lot of code that defines them. So my question is more about performance than whether or not you “can” do it this way.

When you say it doesn’t work when done in onapplicationstart, just what is it that fails?

Of course, doing it there means they’re only defined once, on startup of the app (or if you call that method directly, for an app reload request–which has its own risks).

But you say you’ve done it for years otherwise, but somehow in a way that runs on each request, it seems. Are you not using logic that only creates them if they’re not yet defined? If you are, then it’s unclear what problem you’re trying to solve.

That’s not an attack or a call for a duel. :slight_smile: We can only go on what you’ve said so far. Hopefully we can better help with just a bit more clarification.

Unless I define these caches as psuedo constructors, the caches simply are not defined when they are being used. And because they’re defined as psuedo constructors, I am questioning how performant this method of defining them really is. If people are defining them only in onApplicationStart(), then I’m doing something wrong because this doesn’t work for me.

What I want to do is follow the best practice for defining caches on a high traffic site. I want to squeeze as much performance out of Lucee that I can, and this is one area that I am questioning. What if anything is Lucee doing to make these cache definitions performant? And does it make sense to refactor these cache definitions by moving them into .CFConfig.json.

Does anybody have anything to add to this? My question hasn’t been answered yet. @cfmitrah @carehart

Defining caches in Application.cfc is a supported approach. Whether they live there or in .CFConfig.json is primarily a configuration and deployment decision, not a performance one.
Since you mentioned the definitions don’t work from onApplicationStart(), could you share that code? That part is the key to understanding what’s happening, because caches defined there should normally be available for the lifetime of the application.

@cfmitrah - To clarify, I have been defining caches in application.cfc for a years, and I’ve been doing in the psuedo constructor code inside application.cfc, like so:

component output=false {
    this.cache.connections["clientCache"] = {
		class: 'org.lucee.extension.cache.eh.EHCache'
		, bundleName: 'ehcache.extension'
		, storage: true
		, custom: {
			"bootstrapAsynchronously":"true",
			"replicatePuts":"true",
			"automatic_hostName":"",
			"bootstrapType":"on",
			"maxelementsinmemory":"10000",
			"manual_rmiUrls":"",
			"distributed":"off",
			"automatic_multicastGroupAddress":"230.0.0.1",
			...
		}
		, default: ''
	};
    function onApplicationStart() {...}
    ...
}

If I move my cache definitions inside the onApplicationStart() method, the caches are not defined when I run a request that uses one or more of the caches.

Since a new application.cfc is created on each request, and I’ve got 10 caches defined, wouldn’t it be more efficient to define these caches in .CFConfig.json?

@cfmitrah @carehart can you comment?

@Redtopia, since you’re asking me directly, I’ll say that I’ve never researched the performance difference between those two alternatives.

You seem to be most concerned that doing it in the pseudo constructor is potentially less performant than in the config file. I have no experience to affirm that (nor familiarity with the underlying code).

I’d not think that the mere defining of the caches would be costly, but you imply that it may be. Have you done any testing to confirm?

Separately, if no one else here can confirm, this seems a question for someone on the Lucee team to address. (I am not, to be clear,though I do help solve problems when I can.)

1 Like

No I have not tested performance but I could put a timer around the pseudo constructor code - good idea. Yes, my concern is that these caches are being defined for each request and even though it’s supported, maybe this isn’t a good idea in production. I think it is a good question for the Lucee team and I haven’t been able to find any documentation that addresses the performance question.

@Redtopia Defining those caches in Application.cfc does not create new cache instances per request.

Lucee fingerprints the definition (name, class, custom settings) and reuses the existing connection from a static map when nothing has changed. The EHCache instance itself is created only once. So the per-request cost is just building the structs plus a hash and a map lookup, which is fine even with 10 caches. Moving them to .CFConfig.json is a deployment choice, not a performance one.

On Lucee 7 you can also set LUCEE_LISTENER_SINGLETON=true (or -Dlucee.listener.singleton=true). Then Application.cfc is loaded once at startup (or when the file changes), instead of on every request, so the pseudo-constructor doesn’t run each time either. You’re on 6.2, so that option isn’t available yet.

onApplicationStart() isn’t the right place for this.cache definitions. Those settings are read from the pseudo-constructor.

Code, if useful: Lucee/core/src/main/java/lucee/runtime/listener/ModernApplicationContext.java at 6.2 · lucee/Lucee · GitHub

2 Likes

Thank you for the clarification. I also ran a profile on that code and it took 0 ms.

@Redtopia thanks for checking and for sharing the result. 0 ms is good to know, and it will help the next person who finds this thread with the same question.