Many of us have heard of Session Storage, Local Storage, and Cookies. But what exactly are they, what problems are they solving, and how are they different?
Cookies
In the beginning, the web used HTTP protocols to send messages (btw, SSL is more secure, you should use HTTPS instead of HTTP). These protocols are stateless protocols. In a stateless protocol, each request doesn't store any states, or "persisting information"; each request is its own island and it doesn't have idea about the other requests.
Having a stateless protocol optimizes performance, but it also comes with a problem: what if you need to remember a user session? If you have darkMode: true
or user_uuid: 12345abc
, how can a server remember that if you're using a stateless protocol? With Cookies!
A Cookie can be set from a HTTP header. Usually the server that you're trying to reach, if it has cookies, will send an HTTP header like this:
Set-Cookie: choco_chip_cookie=its_delicious
When your browser receives this header, it saves the choco_chip_cookie
Cookie.
Cookies are associated with websites. If websitea.com
has cookie_a
, you can't see cookie_a
while you're in websiteb.com
. You need to be in websitea.com
.
To see the Cookies you have, if you have Firefox, from your devtools, go to storage -> Cookies; if you have Chrome, from your devtools, go to Application -> storage -> Cookies. Most websites use Cookies, you should find some there (if not, go to a different site).
Cookies can have an expiration date. Of course, you can set it to last effectively forever if you set it to a far future date:
Set-Cookie: choco_chip_cookie=its_delicious; Expires=Mon, 28 Feb 2100 23:59:59GMT;
One more Cookie behavior that you might need to know: your browser sends cookies on each request. When you visit https://example.com
and you have to make 30 requests to download the HTML page and its 29 asset files, your browser will send your cookies (for https://example.com
domain name) 30 times, one for each request.
This only applies if you store your assets under the same domain name, like example.com/assets/images/cute-cats.svg
, example.com/assets/stylesheets/widgets.css
, etc. If you store your assets under a different domain / subdomain, like exampleassets.com/assets/stylesheets/widgets.css
or static.example.com/assets/stylesheets/widgets.css
, then your browser won't send the Cookies there. FYI, storing your assets in a different domain is a good strategy to improve your speed!
The max size for Cookies are 4kb. This makes sense, because Cookies are being sent all the time. You don't want to send 3mb Cookie data to all 30 different requests when visiting a page. Even with this size cap, you should minimize Cookies as much as possible to reduce traffic.
A popular usage for Cookie is to use a UUID for your website and run a separate server to store all the UUIDs to hold session information. A separate Redis server is a good alternative because it is fast. So when a user tries to go to example.com/user_settings
, the user sends its Cookie for example.com
, something like example_site_uuid=user_iggy_uuid
, which then is read by your server, then your server can match it with the key in Redis to fetch the user session information for the server to use. Inside your Redis server, you would have something like: user_iggy_uuid: {darkMode: false, lastVisit: 01 January 2010, autoPayment: false, ...}
.
I highly encourage you to see it in action. Go to any web page (make sure it uses Cookies) using a Chrome / Firefox / any modern browser.
- Look at the cookies that you currently have.
- Now look at the Network tab and check out the request headers. You should see the same Cookies being sent.
You can use Javascript to create cookies with document.cookie
.
document.cookie = "choco_chip_cookie=its_delicious";
document.cookie = "choco_donut=its_awesome";
console.log(document.cookie);
In addition to Expires
, Cookies have many more attribute you can give to do all sorts of things. If you want to learn more, check out the mozilla cookie page.
Cookies can be accessed by third parties (if the site uses HTTP instead of HTTPs for example), so you need to use the Secure
attribute to ensure that your Cookies are sent only if the request uses HTTPS protocol. Additionally, using the HttpOnly
attribute makes your Cookies inaccessible to document.cookie
to prevent XSS attacks.
Set-Cookie: awesome_uuid=abc12345; Expires=Thu, 21 Oct 2100 11:59:59 GMT; Secure; HttpOnly
In general, if you're in doubt, use the Secure
and HttpOnly
Cookie attributes.
Local Storage and Session Storage
Local Storage and Session Storage are more similar than different. Most modern browsers should support Local Storage and Session Storage features. They are used to store data in the browser. They are accessible from the client-side only (web servers can't access them directly). Also since they are a front-end tool, they have no SSL support.
Unlike Cookies where all Cookies (for that domain) are sent on each request, Local and Session Storage data aren't sent on each HTTP request. They just sit in your browser until someone requests it.
Each browser has a different specifications on how much data can be stored inside Local and Session Storage. Many popular literatures claim about 5mb limit for Local Storage and 5-10mb limit (to be safe, check with each browser).
The main difference between Local and Session storage is that Local Storage has no expiration date while Session Storage data are gone when you close the browser tab - hence the name "session".
Both storages are accessible via Javascript DOM. To set, get, and delete Local Storage data:
localStorage.setItem('strawberry', 'pancake');
localStorage.getItems('strawberry'); // pancake`
localStorage.chocolate = 'waffle';
localStorage.chocolate; // waffle
localStorage['blueberry'] = 'donut';
localStorage['blueberry']; // donut;
delete localStorage.strawberry;
You can also store JSON-like object inside a Local Storage. Keep in mind that you need to pass them a JSON string (use JSON.stringify
). Also since you are passing it a JSON string, don't forget to run JSON.parse
to get the value.
localStorage.desserts = JSON.stringify({choco: "waffle", fruit: "pancake", sweet: "donut"});
const favDessert = JSON.parse(localStorage.desserts)['choco']; // waffle
If you have Chrome, you can see the localStorage values you just entered in the devtool Application tab -> Storage -> Local Storage. If you have Firefox, in the devtool, you can find it in the Storage tab, under Local Storage.
Accessing the Session Storage with Javascript is similar to Local Storage:
sessionStorage.setItem('strawberry', 'pancake');
sessionStorage.getItems('strawberry'); // pancake`
sessionStorage.chocolate = 'waffle';
sessionStorage.chocolate; // waffle
sessionStorage['blueberry'] = 'donut';
sessionStorage['blueberry']; // donut;
delete sessionStorage.strawberry;
Both storages are scoped to the domain name, just like Cookies. If you run localStorage.setItem('choco', 'donut');
in https://example.com
and you run localStorage.setItem('choco', 'bo');
in https://whatever.com
, the Local Storage item choco donut
is stored only in example.com
while choco bo
is stored in whatever.com
.
Both Local and Session Storage are scoped by browser vendors. If you store it using Chrome, you can't read it from Firefox.
Cookies vs Local Storage vs Session Storage
To summarize:
Cookies
- Has different expiration dates (both the server or client can set up expiration date)
- The Client can't access the Cookies if the
HttpOnly
flag is true - Has SSL Support
- Data are transferred on each HTTP request
- 4kb limit
Local Storage
- Has no expiration date
- Client only
- Has no SSL support
- Data are not transferred on each HTTP request
- 5 mb limit (check with the browser)
Session Storage
- Data is gone when you close the browser tab
- Client only
- Has no SSL support
- Data are not transferred on each HTTP request
- 5-10 mb limit (check with the browser)