Gauge and Counter allocate alot of memory
Hey, I've noticed that a prometheus Gauge or Counter object needs alot of memory. Is this a normal/expected behaviour?
import prometheus_client
import objsize
labels={}
labels['test']='test'
print("Memory Registry at Start: " +str(objsize.get_deep_size(prometheus_client.REGISTRY)))
print("Memory Labels as dict: "+ str(objsize.get_deep_size(labels)))
gauge = prometheus_client.Gauge("test", "", list(sorted(labels.keys())))
gauge.labels(**labels).set(10)
print("Memory Gauge object: "+ str(objsize.get_deep_size(gauge)))
print("Memory Registry after one Gauge: "+str(objsize.get_deep_size(prometheus_client.REGISTRY)))
gauge2 = prometheus_client.Gauge("test2", "")
gauge2.set(10)
print("Memory Gauge object: "+ str(objsize.get_deep_size(gauge2)))
print("Memory Registry after second Gauge: "+str(objsize.get_deep_size(prometheus_client.REGISTRY)))
counter = prometheus_client.Counter("test3", "", list(sorted(labels.keys())))
counter.labels(**labels).inc(10)
print("Memory counter object: "+str(objsize.get_deep_size(counter)))
print("Memory Registry after Counter: "+str(objsize.get_deep_size(prometheus_client.REGISTRY)))
labels={}
labels['test']='test2'
gauge.labels(**labels).set(10)
print("Memory Gauge second label: "+str(objsize.get_deep_size(gauge)))
print("Memory Registry end: "+str(objsize.get_deep_size(prometheus_client.REGISTRY)))
results in this memory usage:
Memory Registry at Start: 3988
Memory Labels as dict: 285
Memory Gauge object: 2418
Memory Registry after one Gauge: 6725
Memory Gauge object: 1051
Memory Registry after second Gauge: 7723
Memory counter object: 2108
Memory Registry after Counter: 10027
Memory Gauge second label: 3376
Memory Registry end: 10931
In this Blog Post https://www.robustperception.io/memory-usage-of-prometheus-client-libraries/ ( I know it's old) a counter needed way less memory than in my usecase. I'm using python 3.9, on windows(but i've got the same problem in a docker container) and prometheus-client 0.17.0
Are you having issues where metrics are causing too much memory usage compared to the rest of your service? "A lot" is rather subjective as to if it is actually too much memory or not. There have been a lot of changes since 2017, but even so if I run your code against v0.1.0 I get
Memory Registry at Start: 2272
Memory Labels as dict: 237
Memory Gauge object: 795
Memory Registry after one Gauge: 3101
Memory Gauge object: 192
Memory Registry after second Gauge: 3435
Memory counter object: 851
Memory Registry after Counter: 4321
Memory Gauge second label: 1089
Memory Registry end: 4561
vs
Memory Registry at Start: 3364
Memory Labels as dict: 237
Memory Gauge object: 1186
Memory Registry after one Gauge: 4781
Memory Gauge object: 571
Memory Registry after second Gauge: 5299
Memory counter object: 972
Memory Registry after Counter: 6467
Memory Gauge second label: 1664
Memory Registry end: 6891
today. So maybe a 50% increase in memory but still fairly small.
I've just noticed it on a small local machine that in my use case the memory consumption was much highger than expected. But do you know why your memory consumption differs from mine with the same prometheus_client version?
Probably python version. In my last test I used 3.11, with 3.9 I get:
Memory Registry at Start: 3994
Memory Labels as dict: 285
Memory Gauge object: 2418
Memory Registry after one Gauge: 6731
Memory Gauge object: 1051
Memory Registry after second Gauge: 7729
Memory counter object: 2108
Memory Registry after Counter: 10033
Memory Gauge second label: 3376
Memory Registry end: 10937
which is much closer to yours.