Addressing the memory footprint while pitching Clojure

I have the opportunity to pitch Clojure to our CTO for use by our small team. One of the biggest concerns from DevOps in general is resource usage. We currently use Scala, but there’s a push to try Go for new projects because it seems less resource hungry.

How can the memory usage of Clojure be mitigated or justified? Perhaps live debugging at the REPL, etc?

1 Like

Of course it depends on what you are doing, but memory is generally cheap. If you are running server-side processes, the “monitorability” of the JVM gives you a level of insight you cannot even dream of in Go.
But of course YMMV and it depends on what you are doing…

1 Like

Can I ask what your company does, and at what scale it operates?

Sure, Clojure will generally need more memory than go, but that’s because it makes different trade-offs. Go is laughably low level compared to Clojure or Scala, so you’re trading in developer productivity to save a few megabytes. Memory is cheaper than it’s ever been, you can’t say the same of developers.

Clojure also has a general philosophy of trading memory usage for performance. If you want fast functional data structures than that will cost you in terms of memory.

In the end it does depend though on what your organization is doing. If you have a comparatively small team but running a massive fleet of servers than maybe those saved megabytes do add up…

Hi Arne,

we develop web applications for travel businesses, mostly written in Scala.
We moved from Linode to AWS with Rancher/Kubernetes in the past year.

We have a few instances of each application, but they are not under heavy
load. I’m pushing hard for our small team to begin experimenting with
Clojure, especially after dealing with some of the opaque Scala type
notations and the eternal compilation times.

I have similar concerns lately, although not exactly on topic with this thread. I use Wildfly as the best Clojure deployment method I’ve found, but I find that hosting 7 apps is consuming about 12 gigs of ram. My traffic isn’t tremendously high, so I’m still on the hunt for ways to optimize this. I happen to be both the developer and dev-ops man for our little organization, so I don’t answer to anyone really but I have problems when deployments are failing because of unexpected memory scarcity.

I’d like to point out that peeking at the RAM usage of a Clojure JVM instance is not a good way to know how much memory it needs. The JVM GC will not reclaim memory unless it needs too. So you can’t use that as a data point. The only way is to perform load testing on your app, and measure the latency and throughput. In my experience, I’ve had similar performance from Clojure services to Java based ones, the memory is fuller, in that you will see it consuming more, but most is reclaimable, and the JVM GC is good enough that I’ve noticed little impact on latency and throughput.

1 Like

If these are 7 separate JVM processes on a single service you might want to look into using a single JVM instance instead:

I think this might also be possible in lein based builds through the use a separate library.