In my day to day work I don't write many GenServers either and I think that's a good thing. Like any tool, they can be overused and abused. It is best to stick to modules and pure functions until you really need to pull the stateful lever.
To that point, GenServers as an abstraction are super powerful and when applicable, are an amazing tool. For example, being able to control the initialization of a supervision trees using :ignore in the init callback can be handy to run DB migrations as part of the application startup. Or when used in combination with a registry it can be useful to hold on to user data in a GenServer and access it atomically across your cluster.
To that point, GenServers as an abstraction are super powerful and when applicable, are an amazing tool. For example, being able to control the initialization of a supervision trees using :ignore in the init callback can be handy to run DB migrations as part of the application startup. Or when used in combination with a registry it can be useful to hold on to user data in a GenServer and access it atomically across your cluster.