For how long is data stored in localStorage (as part of DOM Storage in HTML5) available? Can I set an expiration time for the data which I put into local storage?
- 9don't use localStorage if possible because is never expire automatically, there you can use sessionStorage it is more preferrableDharmendrasinh Chudasama– Dharmendrasinh Chudasama2017-10-25 05:16:46 +00:00Commented Oct 25, 2017 at 5:16
- 1@DharmendrasinhChudasama there is a reason why both exist: they are used in different cases. Given that the OP doesn't make any distinction between them, one assumes that they know which one they want/need 🤓Gwyneth Llewelyn– Gwyneth Llewelyn2024-04-15 09:55:38 +00:00Commented Apr 15, 2024 at 9:55
- It may be worth noting that if a website creates localStorage (or IndexedDB) data on the first visit, that data may persist on disk for a very long time if that site is never visited again, since there is no automatic expiration mechanism in most browsers. This makes disk use "leak" and continually increase, and deserves to be reconsidered as a design decision.David Spector– David Spector2024-09-11 10:07:15 +00:00Commented Sep 11, 2024 at 10:07
- @GwynethLlewelyn agree, but here I want to say that by DEFAULT use sessionStorage if you don't have idea about difference between these, if any iser issue occurs sessionStorage can reset on just browser restart while in case of localStorage developer may have to debug/clear explicitly, also there is chance to data overlap if you are using server side sessions like loggingDharmendrasinh Chudasama– Dharmendrasinh Chudasama2024-09-20 18:01:02 +00:00Commented Sep 20, 2024 at 18:01
18 Answers
I would suggest to store timestamp in the object you store in the localStorage
var object = {value: "value", timestamp: new Date().getTime()} localStorage.setItem("key", JSON.stringify(object)); You can parse the object, get the timestamp and compare with the current Date, and if necessary, update the value of the object.
var object = JSON.parse(localStorage.getItem("key")), dateString = object.timestamp, now = new Date().getTime().toString(); compareTime(dateString, now); //to implement Alternatively, you could use a light-weight wrapper like localstorage-slim.js which handles this for you.
4 Comments
settimout for every 5 second) or for each request that client sends to server?Date.now() instead of new Date().getTime().It's not possible to specify expiration. It's completely up to the user.
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
Of course, it's possible that something your application stores on the client may not be there later. The user can explicitly get rid of local storage, or the browser may run into space considerations. It's good to program defensively. Generally however things remain "forever" based on some practical definition of that word.
edit — obviously, your own application can actively remove stuff if it decides it's too old. That is, you can explicitly include some sort of timestamp in what you've got saved, and then use that later to decide whether or not information should be flushed.
5 Comments
Brynner Ferreira, has brought a good point: storing a sibling key where expiration info resides. This way, if you have a large amount of keys, or if your values are large Json objects, you don't need to parse them to access the timestamp.
here follows an improved version:
/* removeStorage: removes a key from localStorage and its sibling expiracy key params: key <string> : localStorage key to remove returns: <boolean> : telling if operation succeeded */ function removeStorage(name) { try { localStorage.removeItem(name); localStorage.removeItem(name + '_expiresIn'); } catch(e) { console.log('removeStorage: Error removing key ['+ key + '] from localStorage: ' + JSON.stringify(e) ); return false; } return true; } /* getStorage: retrieves a key from localStorage previously set with setStorage(). params: key <string> : localStorage key returns: <string> : value of localStorage key null : in case of expired key or failure */ function getStorage(key) { var now = Date.now(); //epoch time, lets deal only with integer // set expiration for storage var expiresIn = localStorage.getItem(key+'_expiresIn'); if (expiresIn===undefined || expiresIn===null) { expiresIn = 0; } if (expiresIn < now) {// Expired removeStorage(key); return null; } else { try { var value = localStorage.getItem(key); return value; } catch(e) { console.log('getStorage: Error reading key ['+ key + '] from localStorage: ' + JSON.stringify(e) ); return null; } } } /* setStorage: writes a key into localStorage setting a expire time params: key <string> : localStorage key value <string> : localStorage value expires <number> : number of seconds from now to expire the key returns: <boolean> : telling if operation succeeded */ function setStorage(key, value, expires) { if (expires===undefined || expires===null) { expires = (24*60*60); // default: seconds for 1 day } else { expires = Math.abs(expires); //make sure it's positive } var now = Date.now(); //millisecs since epoch time, lets deal only with integer var schedule = now + expires*1000; try { localStorage.setItem(key, value); localStorage.setItem(key + '_expiresIn', schedule); } catch(e) { console.log('setStorage: Error setting key ['+ key + '] in localStorage: ' + JSON.stringify(e) ); return false; } return true; } 2 Comments
else line be expires = Math.abs(1000*expires); //make sure it's positive ?getStorage call. If you try to access the _expiresIn version of the key directly, the key then becomes ..._expiresIn_expiresIn which of course doesn't exist so it removes the original ..._expiresIn key, then the next time you access the original key, the ..._expiresIn doesn't exist and it deletes the original key. I would suggest trapping for that as I ran into this in one of my projects. if(key.indexOf('_expiresIn') > -1) { return localStorage.getItem(key); }You can use lscache. It handles this for you automatically, including instances where the storage size exceeds the limit. If that happens, it begins pruning items that are the closest to their specified expiration.
From the readme:
lscache.set Stores the value in localStorage. Expires after specified number of minutes. Arguments key (string) value (Object|string) time (number: optional) This is the only real difference between the regular storage methods. Get, remove, etc work the same.
If you don't need that much functionality, you can simply store a time stamp with the value (via JSON) and check it for expiry.
Noteworthy, there's a good reason why local storage is left up to the user. But, things like lscache do come in handy when you need to store extremely temporary data.
1 Comment
Here highly recommended to use sessionStorage
- it is same as localStorage but destroy when session destroyed / browser close
- also localStorage can share between tabs while sessionStorage can use in current tab only, but value does not change on refresh page or change the page
- sessionStorage is also useful to reduce network traffic against cookie
for set value use
sessionStorage.setItem("key","my value"); for get value use
var value = sessionStorage.getItem("key"); all ways for set are
sessionStorage.key = "my val"; sessionStorage["key"] = "my val"; sessionStorage.setItem("key","my value"); all ways for get are
var value = sessionStorage.key; var value = sessionStorage["key"]; var value = sessionStorage.getItem("key"); 2 Comments
sessionStorage does not work to share data between tabsWhile local storage does not supply an expiration mechanism, cookies do. Simply pairing a local storage key with a cookie provides an easy way to ensure that local storage can be updated with the same expiration parameters as a cookie.
Example in jQuery:
if (!$.cookie('your_key') || !localStorage.getItem('your_key')) { //get your_data from server, then... localStorage.setItem('your_key', 'your_data' ); $.cookie('your_key', 1); } else { var your_data = localStorage.getItem('your_key'); } // do stuff with your_data This example sets a cookie with the default parameter to expire when the browser is closed. Thus, when the browser is closed and re-opened, the local data store for your_data gets refreshed by a server-side call.
Note that this is not exactly the same as removing the local data store, it is instead updating the local data store whenever the cookie expires. However, if your main goal is to be able to store more than 4K client-side (the limitation for cookie size), this pairing of cookie and local storage will help you to accomplish a larger storage size using the same expiration parameters as a cookie.
3 Comments
The lifecycle is controlled by the application/user.
From the standard:
User agents should expire data from the local storage areas only for security reasons or when requested to do so by the user. User agents should always avoid deleting data while a script that could access that data is running.
Comments
From the W3C draft:
User agents should expire data from the local storage areas only for security reasons or when requested to do so by the user. User agents should always avoid deleting data while a script that could access that data is running.
You'll want to do your updates on your schedule using setItem(key, value); that will either add or update the given key with the new data.
1 Comment
// Functions function removeHtmlStorage(name) { localStorage.removeItem(name); localStorage.removeItem(name+'_time'); } function setHtmlStorage(name, value, expires) { if (expires==undefined || expires=='null') { var expires = 3600; } // default: 1h var date = new Date(); var schedule = Math.round((date.setSeconds(date.getSeconds()+expires))/1000); localStorage.setItem(name, value); localStorage.setItem(name+'_time', schedule); } function statusHtmlStorage(name) { var date = new Date(); var current = Math.round(+date/1000); // Get Schedule var stored_time = localStorage.getItem(name+'_time'); if (stored_time==undefined || stored_time=='null') { var stored_time = 0; } // Expired if (stored_time < current) { // Remove removeHtmlStorage(name); return 0; } else { return 1; } } // Status var cache_status = statusHtmlStorage('cache_name'); // Has Data if (cache_status == 1) { // Get Cache var data = localStorage.getItem('cache_name'); alert(data); // Expired or Empty Cache } else { // Get Data var data = 'Pay in cash :)'; alert(data); // Set Cache (30 seconds) if (cache) { setHtmlStorage('cache_name', data, 30); } } 2 Comments
If you’re familiar with the browsers locaStorage object, you know that there’s no provision for providing an expiry time. However, we can use Javascript to add a TTL (Time to live) to invalidate items in locaStorage after a certain period of time elapses.
function setLocalStorageItem(key, value, ttl) { // `item` is an object which contains the original value // as well as the time when it's supposed to expire let item = { value: value, expiry: ttl ? Date.now() + ttl : null }; localStorage.setItem(key, JSON.stringify(item)); } function getLocalStorageItem(key) { let item = localStorage.getItem(key); // if the item doesn't exist, return null if (!item) return null; item = JSON.parse(item); // compare the expiry time of the item with the current time if (item.expiry && Date.now() > item.expiry) { // If the item is expired, delete the item from storage and return null localStorage.removeItem(key); return null; } return item.value; } Comments
You can try this one.
var hours = 24; // Reset when storage is more than 24hours var now = Date.now(); var setupTime = localStorage.getItem('setupTime'); if (setupTime == null) { localStorage.setItem('setupTime', now) } else if (now - setupTime > hours*60*60*1000) { localStorage.clear() localStorage.setItem('setupTime', now); } Comments
If anyone still looking for a quick solution and don't want dependencies like jquery etc I wrote a mini lib that add expiration to local / session / custom storage, you can find it with source here:
Comments
Javascript localStorage do not have any options to set expire time
Then i use these functions to check supports, Set and Get
function ls_support(){ return "localStorage" in window&&window["localStorage"]!==null; } function lsset(key,val,exp){ if(ls_support()){ if(!exp) exp=600;// = 10 minutes Default localStorage[key]= JSON.stringify({ "val":val, "exp":~~((new Date()).getTime()/1000)+exp }); } } function lsget(key){ if(ls_support()){ str=localStorage[key]; if("undefined"!=typeof(str)&&str.length){ try{// is json or not json=JSON.parse(str); }catch(e){// if variable not set via lsset func //json.exp=false;// will return null return str;// will return original variable } if(json.exp){// variable setted via lsset func if(~~((new Date()).getTime()/1000)>json.exp){// expired delete localStorage[key]; }else{ return json.val; } } } } return null; } And it seems works fine :
2 Comments
Workaround using angular and localforage:
angular.module('app').service('cacheService', function() { return { set: function(key, value, expireTimeInSeconds) { return localforage.setItem(key, { data: value, timestamp: new Date().getTime(), expireTimeInMilliseconds: expireTimeInSeconds * 1000 }) }, get: function(key) { return localforage.getItem(key).then(function(item) { if(!item || new Date().getTime() > (item.timestamp + item.expireTimeInMilliseconds)) { return null } else { return item.data } }) } } }) 3 Comments
localforage. expireTimeInMilliseconds is not some localforage attribute, but a variable I've used to check if the stored data needs to be expired. Check get function definition on my example.localforage is not the lightweight little helper class I was expecting@sebarmeli's approach is the best in my opinion, but if you only want data to persist for the life of a session then sessionStorage is probably a better option:
This is a global object (sessionStorage) that maintains a storage area that's available for the duration of the page session. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window will cause a new session to be initiated.
Comments
For the benefit of searchers:
Like Fernando, I didn't want to add a load of json when the values stored were simple. I just needed to track some UI interaction and keep the data relevant (e.g. how a user used an ecommerce site before checking out).
This will not meet everyones criteria, but will hopefully be a quick copy+paste starter for someone and save adding another lib.
NOTE: This would not be good if you need to retrieve the items individually.
// Addition if(window.localStorage){ localStorage.setItem('myapp-' + new Date().getTime(), 'my value'); } // Removal of all expired items if(window.localStorage){ // two mins - (1000 * 60 * 20) would be 20 mins var expiryTime = new Date().getTime() - (1000 * 60 * 2); var deleteRows = []; for(var i=0; i < localStorage.length; i++){ var key = localStorage.key(i); var partsArray = key.split('-'); // The last value will be a timestamp var lastRow = partsArray[partsArray.length - 1]; if(lastRow && parseInt(lastRow) < expiryTime){ deleteRows.push(key); } } // delete old data for(var j=0; j < deleteRows.length; j++){ localStorage.removeItem(deleteRows[j]); } } 2 Comments
Date.now() instead of the much more complex new Date().getTime(). It's the currently preferred method, using ECMAScript 2025, the sixteenth edition of the ECMAScript Language Specification — and is supported by all contemporary browsers on all devices.function setStorage(name,value){ return localStorage.setItem(name,JSON.stringify({value:value,timestamp:Math.round((new Date()).getTime()/1000)})); } function getStorage(name,timeout){ var object = JSON.parse(localStorage.getItem(name)); if(object){ if(Math.round((new Date()).getTime()/1000) < (object.timestamp+timeout)){ return object.value; }else{ localStorage.removeItem(name); } } return false; } 1 Comment
Date.now() — the timeout can also be given in milliseconds, after all.