Thank you for the real-world feedback!
It sounds like you’re running on substantial dedicated machines, and available memory isn’t a problem. In that case, there’s scant downside to inc gc.
Because it can let dead cycles go underclaimed for a longer time, they can pile up and increase max RAM use. That’s the downside to inc gc, which can kill programs dead in memory-constrained environments. So it would be interesting to know know how max RAM use in your app is affected.
Also interesting to know whether you have significant trash in cycles. The easiest quick way to check is to look at the return value from a gc.collect() call. If it’s 0, running cyclic gc at all was a waste of time: it found nothing to collect.
A number of my own apps create no cycles. I start them with gc.disable(), and so spend no time in cyclic gc (inc gc or the old way). Some of these have run for months with max RAM staying steady,.
Best guess from your graphs is that you have few trash cycles, but no way to know from here. It’s not trash cycles that slow gc, but the total number of container objects (objects that point to other objects). They all have to be crawled over to detect whether cyclic trash exists. Traversing the entire object graph multiple times is expensive, and more so the more objects and edges in the object graph.
There’s a different topic for discussing ways inc gc could be improved:
Looks promising to me, but it’s too late to change what’s already reverted in 3.14, and the sense I get from the Powers that Be is that it’s also too late to make the gc method switchable for the upcoming 3.15.
The switch to inc gc was made to begin with in the absence of a PEP, or major battle testing, so “once bitten, twice shy” seems to apply.
None of which solves your current problems, alas. Best I can suggest is staying with 3.14.4 (the last version with inc gc) until a better approach is implemented.