There is a slight difference between Godot autoloads and C# static variables.
Autoloads are just nodes in the scene tree, like every other node. What makes them "autoload" is that they are created when the game starts, and are not wiped out when you use
change_scene(), because they live under the scene tree root:
- root (Viewport)
They can be accessed using
GetNode("/root/AutoloadName") as well, and as such, they are available to any script language. And because they are nodes, they will be automatically freed on game quit, and it is possible to know when they are about to be removed, by implementing
GDScript has a feature that makes autoloads available as if they were globals, allowing them to be accessed even when you don't have a reference to the scene tree.
C# static variables, on the other hand, are specific to C#. They mostly behave the same in terms of "global variables", however they don't natively have access to the scene tree, and are only created when you access them the first time, not when the game starts. Also, C# has different kinds of destructors which might not get called in a good time (I don't know much about the specifics of that in Godot). And if you have Godot objects within a static variable, you have to make sure you don't leak them because of that.
Now wich one should you use?
Personally, I avoid
static as much as I can to keep code self-contained (so easier to test or re-use), and not have states hanging around having to manage everywhere, but they have their use cases. If you use them to hold Godot objects, make sure you properly manage their lifetime.