I use a context. I.e.:
f`x = 0;
f[inc_] := f`x += inc
It is a global (though not in the Global context), using a namespace to protect it from inadvertent change.
You can also protect it inside a
x = 0;
f[inc_] := x += inc;
It's still a global though:
I don't know if there's a way to make a completely private, invisible static variable, like in C. I tried
BeginPackage, and it doesn't do anything magical either. Everything made in the package is accessible from outside.
This is kind of an issue in my mind. If I distribute a package, users of the package can make use of internal states that I do not intend to be used. If I distribute a new version with different internal states, it will break the code of those users. Yes, we can say that they were asking for it. However in other languages, this can be prevented entirely. Unless I've missed how to make invisible internal states in Mathematica.