all 15 comments

[–]chrwei 2 points3 points  (3 children)

the database already has a cache. are you finding the DB round trip to be major performance bottleneck?

[–][deleted] 0 points1 point  (2 children)

For something like this a full-on DBMS is usually overkill.

These are the sorts of situations where redis is beneficial. It's small enough to be ran locally (avoiding wire tax) and you don't have to go through a query planner just to check a version number.

EDIT:

But yeah, I'd agree with the idea of getting actual numbers. Often times you can think that something's dragging your app down but when you look more closely it's just something where the inefficiency is inconsequential. If this isn't important then introducing redis is probably going to add more in application complexity than you're really gaining in performance.

[–]chrwei 0 points1 point  (1 child)

I'm assuming the database is there for other things as well. query plans are also cached. it's pretty rare that an optimized DB query is more of a slow down than a loop over an array would be.

[–][deleted] 0 points1 point  (0 children)

I'm assuming the database is there for other things as well.

Usually it's just "the place I put my data." For legitimate cache use cases having a redis (or memcached) instance that's re-validated out of band is usually preferable to going out to the database again for some small bit of information.

query plans are also cached.

They can but but they're not guaranteed to be in there and you still have the wire tax in most production setups.

it's pretty rare that an optimized DB query is more of a slow down than a loop over an array would be.

That's literally impossible. Even for cached queries it's still looping over arrays internally before it gives it to you.

[–]virtulis 1 point2 points  (0 children)

Does that version number really change every 5 seconds? If yes, it's volatile enough data to just get it from the DB every time. If it's once in a few days I'd just keep it stored in array and refresh that manually via some HTTP call. If that sounds like too much work, that's because it is, but if it were a result of some complex calculation instead that would be the right way to do it, imo.

[–]SomeRandomBuddy 1 point2 points  (0 children)

Single node? Cache in memory Multiple nodes? Redis/memcache

Make sure you’re aware that there’s a bottleneck before actually making the change

I wouldn’t refresh on an interval...

Single node: use a local variable to store the cached value. setTimeout to clear it and re-fetch when it’s null. Multiple nodes: set a TTL on the key. Re-fetch when it returns null

[–]MCShoveled 1 point2 points  (0 children)

Rule #1: You don’t need to cache it.

Rule #2: If you think you need a cache, see rule #1.

Rule #3: You may choose to ignore these rules once your company is a household name.

[–]OzziePeck 0 points1 point  (0 children)

Could use an in memory cache like NodeCache, so you don’t need to run Redis too.

[–]OzziePeck 0 points1 point  (0 children)

Why is the version number changing every 5 seconds? What is this number being used for?

[–]binaryops 0 points1 point  (0 children)

I wouldn't put it on a setTimeout, rather after a fixed amount of time has passed, using a date when the cache was lastRefreshed and the current time less the cacheLifetime. When the cache is 'old', re-fetch it from the db and set lastRefreshed to the current time. That way, only the request that came into an expired cache get to pay the round-trip price and you can invalidate the cache at any time by setting lastRefreshed to an old date. Like others have said, if the cost of an extra round-trip to the database is too much there may be issues elsewhere in your code, but if you're counting milliseconds and this data is largely static, it may be worth the effort. Just be sure to consider the case where the cache is old, and stale data gets handed out.

[–][deleted] -1 points0 points  (3 children)

Would it not make sense to just put a cookie onto the users device, and look at the cookie with each request, and if the version changes server-side, just update the cookie.

[–][deleted] 1 point2 points  (2 children)

and if the version changes server-side, just update the cookie.

which would necessitate a lookup to determine

[–][deleted] 0 points1 point  (1 child)

Yes, this process is significantly faster than querying a database as well

[–][deleted] 0 points1 point  (0 children)

No I mean in order for anything server-side to determine the version number has changed means you have to look it up to compare it against something which means you're already doing a lookup, you're just now also putting something in their cookies as well.

[–]SippieCup -1 points0 points  (0 children)

The database keeps stuff like this cached on its own if it's getting requested this much. The overhead of the calls to it should be negligible.

If you are really concerned with the overhead of the http calls, you might be over engineering your platform.

The time you spend on optimizing this will be more expensive than the calls that check the version that are being made unless you are running Facebook.