Is it possible to use ETS when deploying to Heroku?


Is it possible to use ETS or libraries that uses ETS when deploying to Heroku?

Things like: ConCache / Elixir Registry?


Yes. :ets only holds information inside a single node anyway, so the fact that you can’t cluster in heroku isn’t an issue. Do note however that when heroku reboots your dyno (which happens every 24 hours) any information stored inside :ets will be lost, so I would only use it for ephemeral state.

How does it work with multiple dynos?

Let’s say I created a named table in ETS, it means that I will have a named table per dyno (since dynos are not connected)? doesn’t it misses the purpose of named table or I confusing things?

Let’s say I like to implement a leaderboard with ETS sorted set. how will it work if requests are load balanced between dynos and each dyno has it’s own ETS tables?

Naming a table just means that within a given node, you can refer to a table by some name. It does not let you refer to tables on other nodes. :ets always only holds state in a single node, it is not global at all.

On its own, you can’t use it to do a cluster wide leaderboard whether on heroku or not. If you weren’t on heroku you could have the processes that manage the ets table talk to one another so that they could stay synchronized. On heroku you’d probably just use redis or a database for that kind of thing.

As a follow up, :ets is still plenty useful on heroku for all kinds of stuff. For example, Ecto uses :ets to maintain its prepared query cache, Absinthe does a similar thing for its cached queries. Even when Phoenix PubSub is using Redis it’s also still using :ets to handle subscribers on each node.

1 Like

Thank you for the detailed explanation and the examples, I will check them out :slight_smile:

Hey @benwilson512 and thanks for all the details.

You’re saying that ETS can work nicely with Heroku for ephemeral storage and that Heroku kinda reboots the dyno every 24 hours.
But it means that if I’m using ETS to store session keys, someone could login just before Heroku reboots and be logged out just a short time after? Not really great in terms of User experience right :expressionless:?

That is exactly right. Also, if you run more than one node, sessions would not be shared. :ets is really not usable for sessions beyond single node hobby scenarios.