What is a good session store for a single-task Node.js application?

I am using Node Express w / Connect middleware. The memory session store is not suitable for production:

Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and obviously only work within a single process. 

For large deployments, mongo or redis makes sense.

But what is a good solution for a single host application in production?

+63
express connect
Jan 05 2018-12-21T00:
source share
7 answers

Spent the day studying this. Here are the options I discovered. Requests / second are done via ab -n 100000 -c 1 http://127.0.0.1:9778/ on my local machine.

  • no sessions - fast (438 req / sec)
  • cookieSession : does not require an external service, insignificant effect of speed (311 req / sec) - faster, sessions expire with a cookie ( maxAge configured)
  • connect-redis : a redis server is required, a large impact of speed (4 req / sec with redis2go and redisgreen) is faster than mongo, sessions will be deleted after a while (configured to ttl )
  • connect-mongo - requires a mongodb server, a large impact of speed (2 req / sec with mongohq) - slower than redis, manual clear_interval to set up cleaning sessions

Here is the coffeescript file that I used for cookieSession:

 server.use express.cookieSession({ secret: appConfig.site.salt cookie: maxAge: 1000*60*60 }) 

Here is the code I use for redis:

 RedisSessionStore ?= require('connect-redis')(express) redisSessionStore ?= new RedisSessionStore( host: appConfig.databaseRedis.host port: appConfig.databaseRedis.port db: appConfig.databaseRedis.username pass: appConfig.databaseRedis.password no_ready_check: true ttl: 60*60 # hour ) server.use express.session({ secret: appConfig.site.salt cookie: maxAge: 1000*60*60 store: redisSessionStore }) 

Here is my mongo coffee pot:

 server.use express.session({ secret: appConfig.site.salt cookie: maxAge: 100*60*60 store: new MongoSessionStore({ db: appConfig.database.name host: appConfig.database.host port: appConfig.database.port username: appConfig.database.username password: appConfig.database.password auto_reconnect: appConfig.database.serverOptions.auto_reconnect clear_interval: 60*60 # hour }) }) 

Now, of course, remote redis and mongo databases will be slower than their local equivalents. I simply could not get local equivalents to work, especially considering that the installation and maintenance time for me was much longer than what I wanted to invest in comparison with remote alternative solutions, which I consider true for others, therefore why these remote remote services databases exist first!

For local benhmarks databases see @Mustafa answer .

Lucky for someone, edit this answer to add your local base database tests to the table.

+77
Oct 24
source share

Since the accepted answer is only associated with remote hosts, it is obvious that it will always be slower than localhost. Even if this is the next computer in your home, it will take milliseconds to read from this computer, but local memory only takes nanoseconds. You must compare them using locally installed servers.

Here are my results from my local computer: you see, redis is almost as fast as in memory, under high load. You can clone my repo to make these test codes available: https://github.com/mustafaakin/express-session-store-benchmark

 Concurrency: 1 none 4484.86 [#/sec] memory 2144.15 [#/sec] redis 1891.96 [#/sec] mongo 710.85 [#/sec] Concurrency: 10 none 5737.21 [#/sec] memory 3336.45 [#/sec] redis 3164.84 [#/sec] mongo 1783.65 [#/sec] Concurrency: 100 none 5500.41 [#/sec] memory 3274.33 [#/sec] redis 3269.49 [#/sec] mongo 2416.72 [#/sec] Concurrency: 500 none 5008.14 [#/sec] memory 3137.93 [#/sec] redis 3122.37 [#/sec] mongo 2258.21 [#/sec] 

The session pages used are very simple pages;

 app.get("/", function(req,res){ if ( req.session && req.session.no){ req.session.no = req.session.no + 1; } else { req.session.no = 1; } res.send("No: " + req.session.no); }); 

Redis save configuration:

 app.use(express.session({ store: new RedisStore({ host: 'localhost', port: 6379, db: 2, }), secret: 'hello' })); 

Mongo Store Configuration:

 app.use(express.cookieParser()); app.use(express.session({ store: new MongoStore({ url: 'mongodb://localhost/test-session' }), secret: 'hello' })); 
+62
Nov 05 '13 at 20:05
source share

Another good option is memcached. Session state is lost if memcached restarts, but there is virtually no reason for this. You can leave the cache all the time, even when you restart the application server. Access to session data is almost instantaneous, and memcached will work happily with any (corresponding) amount of memory that you give it. And I never saw memcached crash (on Linux).

https://github.com/elbart/node-memcache

What you need to remember about memcached in general:

  • Never use spaces in cache keys
  • Keep in mind that there is a maximum cache key length, including any namespace prefix you could use. If your cache key is too long, use the 1-way hash address instead.

None of these issues should be a problem for session storage; just with generalized caching.

+8
Jan 6 2018-12-12T00:
source share

I went with the MongoDB session store using connect-mongo .

Install using npm install connect-mongo and replace the existing MemoryStore with

app.use(express.session({ store: new MongoStore({ db: 'some-database' }) }));

Automatically manages a database session session.

+6
Jan 6 '12 at 18:44
source share

I would still use Redis even for local development. This is useful because it stores the session even when you restart the Node application while maintaining your browser session. By default, Redis saves the session in memory, just like in the storage, the connection is easy to configure (I just run it on the screen along with my Node applications) can support several applications if you just use a different database or session value in the settings .

+5
Jan 06 2018-12-12T00:
source share

I am just learning node.js myself, but if you don't need to store a lot of information in a session object, you can examine secure cookies.

Secure cookies store session information as part of the cookie that the browser stores and forwards with each request. They are encrypted so that the user cannot fake a valid cookie.

The advantage is that you do not need to maintain state on the server - this solution scales well and is easy to implement.

The disadvantage is that you can store up to 4 KB and send data to the server for each request (but you can have several dummy domains pointing to your server so that you do not impose this baggage on public static content, for example).

A web search seems to have at least two implementations of secure cookies for node.js. Not sure if the production is ready, but:

https://github.com/benadida/node-client-sessions/blob/master/lib/client-sessions.js

https://github.com/caolan/cookie-sessions

+2
Jan 05 2018-12-12T00:
source share

Check out my tests at https://github.com/llambda/express-session-benchmarks , which show comparisons of different session implementations.

+1
Dec 02 '14 at 18:20
source share



All Articles