When should server side sessions be used instead of client side sessions?

For example, is it safe to put a csrf-token in a client side cookie, whether it is encrypted or not?

Yes. OWASP calls this method Double Submit Cookies. I have never seen it in practice though.

The reason this is safe is that CSRF tokens are temporary values. For example, if you would store an encrypted password in a client side session, that would be pretty bad (depending on the key and encryption algo). An attacker may be able to steal it, decrypt it, and then have the users password. For the CSRF token, an attacker gains nothing. Additionally, it doesn't affect server security if an attacker or user changes the cookie, all that will happen is that the token doesn't work.

in what circumstances would it not be safe to store session data in the cookie?

There are two things to worry about here:

  • A user or attacker may change data in the cookie and the server would have no idea that this happened, accepting the changed data (for example, it may contain a value such as isAdmin:0, which may be changed to isAdmin:1).
  • The cookie could contain sensitive information which a user or attacker may read out

To solve the first point, a MAC could be used, to solve the second point, the cookie data should be encrypted.

Before you create client side sessions, you should ask yourself if you really need it (which may be the case if you have multiple servers which need to share the same session state, eg for scalability reasons). Session data is traditionally handled server side for a reason: It contains data that the client should not be able to read or change. That's easiest to do by just not sending it to the client.

Setting up a complex system to store session data client side is difficult, and a lot may go wrong doing it. If it's not necessary, just store the data server side.