Speed up your sessions, part 1 – Best practices
This entry is the first part of two posts which will cover session performance in PHP, in a software point of view.
So today, you will learn what to do and not do with sessions and how to optimize their setup with some simple best practices.
Session, what is it for ?
In a few words, the session is used to keep track of a visitor and store data about it across requests to your server. A token is sent to the visitor in a cookie and the user will return it at each of its requests. Then the session allows you to register data to be preserved.
From here, you are able to store the user id for example, which may be used to retrieve its related data through some SQL queries. Also, you may store its access rights, names, last visited URL, shopping cart etc… Everything that helps defining its application environnement and avoid unneedful SQL queries.
What you shouldn’t do
As seen above, the session must be used to store data concerning an authenticated user.
You should not use it as a data cache or store template part in it.
For example, HTML elements such as navigation menu or footer, is surely not specific to an user, so if you store these pieces of code in sessions, the contents will be duplicated in each session file…
As well, if you store SQL queries results in the session, this will increase significantly their file size and degrading performance. Moreover, retrieve query results from a session is not necessarily faster than calling the database.
Even if, at first sight, the session setup is not the most expensive part of a HTML page generation, it’s useful to work on it to avoid big performance hits.
The most you keep your session files small and less numerous, the most your website will be fast.
Now that you know how to properly use sessions, we can start to optimize our PHP configuration and code
First, keep in mind that when a session is started in your script, PHP :
- tries to read the token contained in the cookie
- opens or creates a file on-disk
- locks it, so you can write in it
- reads its contents
- puts the data in the global array $_SESSION
- sets caching headers
- returns a cookie to the client
All these actions are just a summary of what PHP does, I don’t know the exact internal mechanisms…
But they set out one thing, the setup of a session have a cost in terms of performance.
So you should always keep the control of the session initialization.
For that purpose, the php flag session.auto_start in your php.ini must be set to 0. Otherwise, a session will be mount at the begining of each request for each user and even when it’s not necessarily. If a visitor has no need to be logged, why setting a session for him ?
I admit that for 1 or 2 visitors per day it’s surely not significant but what if your website must handle thousands visits at the same time ?
You have to determine where and when a session has to be set up. Then you may start it explicitly with :
$boolean = session_start();
At that point, the session is running. That means its file is locked to prevent concurrent writes and only your current script may make operations on it. Other access tries will be denied, resulting in your other scripts to stall, waiting for the session file to be available.
So, if you don’t need to save data into the session, close it as soon as possible. Then data you set in the $_SESSION array is written in the storage and all of the global $_SESSION array contents are still avalaible in read-only mode :
session_start(); $_SESSION['foo'] = 'This will be stored in the session'; session_write_close(); echo $_SESSION['foo']; // Other data that has been stored before the current script // are still available in read mode echo $_SESSION['bar'];
Applying these few best practices is a good start to not slow your web applications when implementing session support.
In the second part of this serie, we will see how to increase even more performance by using others session handler instead of files.
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.