elie
My first question is what does ETS add on top of just storing state in a GenServer?
In the documentation I see it is used as a “cache”, does this mean it won’t always return the latest data?
There’s a warning in the Elixir guide about using it prematurely:
Warning! Don’t use ETS as a cache prematurely! Log and analyze your application performance and identify which parts are bottlenecks, so you know whether you should cache, and what you should cache. This chapter is merely an example of how ETS can be used, once you’ve determined the need.
I don’t have any performance issues at this time? Does this mean ETS should not be used? What are the downsides of using ETS?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted”
Version...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Nilithus
No expert here – but from the reading I’ve done 90% of the time you’re better off just storing state in the GenServer.
There is a couple of interesting use cases since ETS tables have some access control:
so you can have shared state across processes. I believe the Elixir Registry uses ETS tables under the hood.
The other use case I’ve seen is if you are highly concerned about Garbage Collection(GC) cycles the ETS table is not stored in the process’s heap. This Erlangelist blog article talks about saving GC latency when you have large data buffered in a process.
But these are all pretty big edge cases I think. Hope this helps!
cevado
Addressing your points directly,
ETS is usually used as a way to share state between processes/GenServers.
No. ETS is a key-value store, it will be updated just as current as you update the data there.
Yes and no. It means that you dont need cache, it doesnt mean that you dont need ETS. Cache data is one of the many use cases for ETS.
rvirding
Using ETS as a cache is only one of its many uses. A major use is for storing LARGE amounts of data in memory. This is a typical use, for example it is how mnesia stores data in memory. So if your gen_server stores large amounts of data then maybe using ETS is a better alternative.
As has already been pointed out ETS tables can be shared between processes. One thing to watch out is that ETS is a datastore not a database and the support for transactions is VERY limited. If you need to implement transactions you will probably need a process in front of the ETS tables.
There are many other uses of ETS. Another one for example is having supervisor use ETS tables to share data between its children, both current and future ones.
So in Erlang ETS is used quite often.
minhajuddin
You can use
ETSin many places where you use your database depending on your use cases. One easy win is putting all your lookup data intoETStables.ETSis very fast when you do key lookups. I do a little bit of ETL and use ETS tables extensively to store lookup data, to write out to ets tables as an intermediate store etc,. I also use them in animage_downloaderapp to keep a list of URLs which have been downloaded with their checksums and headers so that I don’t need to download them the next time I see them. I use:ets.file2tab('./data/myetsdb.ets')as soon as I start the app and do a:ets.tab2file(:mydb, './data/myetsdb.ets')before I shut down or run into an error.CharlesO
Hi, please check the order of this … should it not be the other way round?
minhajuddin
Yeah
. Fixed it
sasajuric
You could simulate the complete interface of the
:etsmodule withGenServer. However, such implementation would be very inefficient in some cases.A typical example is in memory k-v. If you do this with a single process (GenServer or Agent), then all access is serialized. If you have thousands of client processes interacting with such k-v, operations are performed one at a time.
In contrast, an ETS powered table with proper knobs turned on (
:public,:read_concurrency,:write_concurrency) will allow different clients to interact with the same table simultaneously. Multiple processes can issue reads and writes to the same table at the same time, and the operations can be performed simultaneously, unless both processes are writing to the same row.An example of this in practice is Registry, which is powered by ETS tables. This ensures that client processes can quickly find desired processes, and even get some of their properties, without needing to message some process.
The thing @rvirding and @Nilithus mentioned about avoiding large process heap is also an interesting feature. ETS data is “off-heap”, so it doesn’t put any pressure on GC. If you have a single process with a large, and frequently changing, active memory set, ETS table might improve your performance significantly.
So basically, ETS is mostly an optimization technique. If your needs are simple, you can probably start with a
GenServer, and consider ETS if you find performance problems.PatNowak
Please correct me if I’m wrong, but it turns out that eg. info about Elixir modules is stored in ETS according to the source code.
minhajuddin
You are right (I am not sure what info about the modules is stored). There is a lot of information stored in ets tables. Simply opening
iexwill create ~19 ets tables.jyeshe
I choose ETS whenever I need to keep data despite of a GenServer process state. When a GenServer termination would imply relevant data loss. Specially due to the let it crash approach