We recently underwent a major refactor of the way we handle sessions. In simple terms, a session is an active user presence on the site and a connection between your client (browser) and our our servers.
PHP sessions are very inefficient. For every request made to the site, both reads and writes are made to the sessions store on the database. Another quirk of PHP sessions is the fact that they are serialized in a non-standardized way that only PHP can understand. Also a cookie is sent on all page requests due to ‘session_start()’. For the majority of use cases this is simply not needed; already created sessions should not need to be redefined on every request, nor should you need to talk back to database unless there is significant state change and nginx workarounds for bypassing the caches simply due to PHP session practices should not be required.
When implementing additional authentication systems such as OAuth, which do not use sessions, this can cause additional issues and unnecessary overhead and complications.
Further, there is also high complexity when it comes to caching or ‘denormalizing’ the user object on the sessions. Previously, we denormalized the user object for performance, but this meant sessions were highly fragmented and bugs arose because the data became out of sync. If you edited your channel in one browser, it would still have the stale channel data on the other browsers you were logged into.
We introduced JWT tokens which are created once, at the authentication stage. When you login to Minds, we create a cookie with a signed token, which contains information such as your user id. JWT (JSON Web Tokens) are signed and verified by key-pairs. We also verify the cookie ID on each request to deal with stale or revoked sessions that need to be deauthorized.
Another benefit of JWT tokens is that any service can potentially read them. This reduces the computational and performance overheads required in shared systems.
Even though we approached this project with the sole aim of cleaning up the code to be more manageable, we have noticed a 25% reduction in memory AND a further 25% reduction in CPU from our front end servers.
We also refactored our OAuth2 system to be more efficient and scalable for future expansion of our APIs. More to follow on this in a later blog.