A behaviour defines an interface a module can implement, nothing more. A good example of a behaviour that doesn’t involve any process is the SSL session cache:
If you implement your own cache module (backed by a file, DB, whatever) and it respects this interface, you can then pass it to the SSL functions and they’ll use it instead of the default cache.
It just happens that gen_server is both the name of a behaviour, and the name of a module, which can be a bit confusing. The gen_server module implements a generic server process, which is customized by passing it a module that implements the gen_server behaviour (as an argument of `start_link`).
http://erlang.org/doc/man/ssl_session_cache_api.html
If you implement your own cache module (backed by a file, DB, whatever) and it respects this interface, you can then pass it to the SSL functions and they’ll use it instead of the default cache.
It just happens that gen_server is both the name of a behaviour, and the name of a module, which can be a bit confusing. The gen_server module implements a generic server process, which is customized by passing it a module that implements the gen_server behaviour (as an argument of `start_link`).