Is using Genserver as an intermediary cache for my app faster than going straight to postgres (and good idea)?

I have a Liveview app and I send data to the database via ECTO. All my CRUD actions do this.

If I created a Genserver that mirrored my database content and then changed the ECTO code to perform CRUD operations directly to the Genserver while updating my Database in parallel, would my app perform faster ( or at least appear to perform faster) from the perspective of the user during CRUD actions?

To rephrase, I want to know if I used a Genserver to store state would my app be faster than a round-trip to the Database .

Thank you.

Edit

Now I’m wondering if ECTO already does this behind the scenes? If not, I’m curious if there is a mix plug in that would automate it.

First question are you experiencing any delays that would necessitate this?

Secondly Ecto has a pool of connections it uses when going to the database, usually 10.
When using a GenServer you are serializing all your actions, so unless this is something that you want, don’t do this. Or you would have to create some kind of pooling strategy yourself.
If you are in need of a cache because of some expensive db operation, use ETS or something like CacheEx.

Just my 2 cents.

3 Likes

No, I’m just bored and want to mess with Genservers. I have no reason other than that whatsoever.

EDIT

I take that back, my app CRUD updates feel a tad slow and chunky compared to an app that does it all on the client first but this isn’t my motivation.

All content, or partially? If partially then it is unlikely to be faster because database already has cache. If all content, then see below.

Do you wait for completion from the database? if yes, then it can’t be faster. If you don’t, that means you don’t need the durability guaranty from the database, and since your data is small enough to fit in memory, you don’t need database at all.

Ok, so it sounds like Ecto already does what I am asking about nullifying any reason to re invent the square peg.

No, Ecto does not cache; it does not need to. All relational databases have sophisticated caching layer already.

In general, refrain from making a caching layer yourself. It is a most likely a premature optimization and a huge source of bugs.

2 Likes

Okay, let me rephrase so I’m clear.

Assume I didn’t have a database and all my app data was stored in a Genserver.
Would CRUD operations to and from the Genserver be faster than a postgres database?

Maybe, but it should not be your biggest concern. If technically I don’t need to use a database, I may still choose to use one because it is future-proof and maybe I am familiar with a database. On the other hand, a database-less setup greatly simplify deployment, and this is something I value highly, then I don’t.

maybe at low volume, but at any sort of traffic, a single genserver will be a strict bottleneck for your app, whereas postgres is built to handle concurrent requests. genservers serialize every request.

what you seem to be doing is optimizing prematurely. you can always optimize later, don’t let “performance” drive you into a corner you can’t get out of.

If you are just interested in caching, look into Cachex or Nebulex, or learn to use ETS. Hell, I have apps running that just use ETS as their backing store because the data is ephemeral.

3 Likes

If you are just interested in caching, look into Cachex or Nebulex, or learn to use ETS

So I assume that if I wanted to do this exact same thing but use these tools, it won’t create the same kind of bottleneck as a (single) Genserver?

Access to ETS can be concurrent, whereas a GenServer handles messages one at a time.

1 Like