The way I've gone about it in Nim so far, the refcounts are actually rare, especially copies (which is where increments occur). You can also look at the generated C and it's pretty clear where the overhead is happening, and I've found that in practice it happens rarely enough that this makes a lot of sense. It's pretty different from how things go in Python. In my project I also actually just use ARC and for sure don't have cycles, and the destructor calls are deterministic.
Here's a talk that's somewhat related (refcounts in the "Lobster" programming language, and how it also elides refcount calls using compile-time logic (which ends up being equivalent-ish to a framing in terms of move semantics)): https://www.youtube.com/watch?v=WUkYIdv9B8c