# Proposing Registry

**URL:** <https://forum.elixirforum.com/t/proposing-registry/2121>\
**Category:** Elixir News\
**Tags:** registry, core\
**Created:** [October 25, 2016, 9:11pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121 "2016-10-25T21:11:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![josevalim](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/32/1787_2.png) [@josevalim](https://forum.elixirforum.com/u/josevalim)\
**Post date:** [October 25, 2016, 9:11pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/1 "2016-10-25T21:11:26Z")

</div>

Hello everyone,

I would like to propose the addition of the Registry project to Elixir:

[https://github.com/elixir-lang/registry](https://github.com/elixir-lang/registry)

The Registry project is a local and scalable key-value process storage in Elixir. It encapsulates 3 known use cases:

- Process registry: to register process with dynamic names. Often Elixir developers need to rely on gproc or other tools.
- Code dispatching: dispatch a module/function associated to a given key
- PubSub implementation: send messages to local processes registered under a given topic

There are probably other use cases waiting to be discovered. 🙂  
You can learn more in the documentation:

[http://elixir-lang.org/docs/registry/](http://elixir-lang.org/docs/registry/)

The project clocks only 700LOC with documentation and performs well. We have extracted, improved and generalized the patterns from Phoenix.PubSub, the [implementation used to manage and publish messages to 2 million subscribers](http://www.phoenixframework.org/blog/the-road-to-2-million-websocket-connections).

When benchmarking thousands of processes registering serially, it is twice slower than local atoms, albeit 33% faster than gproc. On concurrent cases, it distributes well across all cores, becoming only 15% slower than local atoms, and 3x faster than gproc on a machine with two cores (gproc seems to be serial with its default configurations so the difference will be even bigger on more cores).

Please give it a try and let us know what you think.

---

<div class="post-metadata">

**Author:** ![JEG2](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jeg2/32/936_2.png) [@JEG2](https://forum.elixirforum.com/u/JEG2)\
**Post date:** [October 25, 2016, 10:23pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/2 "2016-10-25T22:23:24Z")

</div>

I am so excited about the possibility of having this built-in!

---

<div class="post-metadata">

**Author:** ![OvermindDL1](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/32/2677_2.png) [@OvermindDL1](https://forum.elixirforum.com/u/OvermindDL1)\
**Post date:** [October 25, 2016, 10:23pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/3 "2016-10-25T22:23:26Z")

</div>

Ooo, so basically an Elixirfied `:gproc` it looks like? That is awesome if so! ^.^

EDIT: Indeed it does, a bit more simplified in the docs as I’m not seeing anything like `:gproc`s local and remote distinctions or pubsub helpers and such, but it looks like the pubsub helpers can be build on what is here, and the local and remote distinctions are probably not necessary if it is naturally distributed. 🙂

---

<div class="post-metadata">

**Author:** ![josevalim](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/32/1787_2.png) [@josevalim](https://forum.elixirforum.com/u/josevalim)\
**Post date:** [October 25, 2016, 10:51pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/4 "2016-10-25T22:51:44Z")

</div>

> [@OvermindDL1](#):
>
> Ooo, so basically an Elixirfied :gproc it looks like?

Its API is quite simpler than gproc’s. There is no support for distribution as well, it is by definition local. One reason why we are hesitant on tackling any distributed registry as part of Elixir is because such is already part of the OTP team plans.

---

<div class="post-metadata">

**Author:** ![OvermindDL1](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/32/2677_2.png) [@OvermindDL1](https://forum.elixirforum.com/u/OvermindDL1)\
**Post date:** [October 25, 2016, 10:57pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/5 "2016-10-25T22:57:30Z")

</div>

> [@josevalim](#):
>
> One reason why we are hesitant on tackling any distributed registry as part of Elixir is because such is already part of the OTP team plans.

Ooo, I’ve apparently not kept up with the OTP doings, that would be fascinating.

---

<div class="post-metadata">

**Author:** ![benwilson512](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/32/1457_2.png) [@benwilson512](https://forum.elixirforum.com/u/benwilson512)\
**Post date:** [October 26, 2016, 12:55am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/6 "2016-10-26T00:55:18Z")

</div>

What would the relationship between this and those OTP plans be once they come to fruition?

---

<div class="post-metadata">

**Author:** ![ChrisYammine](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chrisyammine/32/19254_2.png) [@ChrisYammine](https://forum.elixirforum.com/u/ChrisYammine)\
**Post date:** [October 26, 2016, 1:14am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/7 "2016-10-26T01:14:38Z")

</div>

Neat! Definitely giving it a try 🙂

---

<div class="post-metadata">

**Author:** ![belaustegui](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/belaustegui/32/36580_2.png) [@belaustegui](https://forum.elixirforum.com/u/belaustegui)\
**Post date:** [October 26, 2016, 6:58am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/8 "2016-10-26T06:58:48Z")

</div>

Wonderful! The implementation seems very clean and understandable 🙂

Noob question: what would be the utility of having multiple partitions for the same Registry? Looking at the code I see that the registry uses only one by default. In which cases should I use more partitions than the default one?

---

<div class="post-metadata">

**Author:** ![Qqwy](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/32/1349_2.png) [@Qqwy](https://forum.elixirforum.com/u/Qqwy)\
**Post date:** [October 26, 2016, 8:30am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/9 "2016-10-26T08:30:08Z")

</div>

This is very interesting!

I believe it would be great to have this become part of Elixir’s core or at least the ‘officially maintained packages’, as it is a very common use case.

What was the main reason behind starting this project? In the first post you mentioned that Registry is somewhat faster than gproc: Was this (make it faster) the main reason to start building this? Or are there features that you feel are missing from gproc and other existing alternatives that are important enough to start something new?

---

<div class="post-metadata">

**Author:** ![gmile](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gmile/32/33982_2.png) [@gmile](https://forum.elixirforum.com/u/gmile)\
**Post date:** [October 26, 2016, 9:52am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/10 "2016-10-26T09:52:21Z")

</div>

Can you please point to a relevant discussion?

---

<div class="post-metadata">

**Author:** ![josevalim](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/32/1787_2.png) [@josevalim](https://forum.elixirforum.com/u/josevalim)\
**Post date:** [October 26, 2016, 10:00am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/11 "2016-10-26T10:00:04Z")

</div>

> [@benwilson512](#):
>
> What would the relationship between this and those OTP plans be once they come to fruition?

This is local, the OTP one is distributed. You shouldn’t use the OTP one to store local data, as looking up or storing information may require messages across nodes.

> [@belaustegui](#):
>
> what would be the utility of having multiple partitions for the same Registry?

On my benchmarks, the use of partitions have only been justified for the pubsub/dispatch use cases. For the unique registry, I couldn’t find a case yet where increasing the number of partitions matter. However, my current machine has only 2 cores. Maybe a partitioned unique registry may matter on machines with 16+ cores.

> [@Qqwy](#):
>
> What was the main reason behind starting this project?

:gproc is a great project, albeit I find its API confusing (YMMV). If you asked me about a registry in Elixir six months ago, the answer would likely be no. So what has changed?

1. I confirmed with the OTP team they have no plans to tackle a local registry
2. While working on a separate project wth @chrismccord, we realized we could generalize the PubSub implementation while keeping the scalability aspects of Phoenix.PubSub
3. The generalization of PubSub made it useful for at least 2 other common cases: :via lookups and module/function dispatching. :via lookups is a frequently required feature. Plus I am using module/function dispatching to replace GenEvent in another app and we will explore it instead of GenEvent in Logger too.

Being faster than gproc is a perk, although the registry was designed to scale with multiple cores. Work in the registry is always done on the client, there is no centralized entity, and that’s another useful pattern to have in hand.

In other words, there isn’t a single reason. We found a generic solution that is performant and scalable and our reaction is that it can be very useful as part of the language.

---

<div class="post-metadata">

**Author:** ![chrismcg](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chrismcg/32/671_2.png) [@chrismcg](https://forum.elixirforum.com/u/chrismcg)\
**Post date:** [October 26, 2016, 10:05am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/12 "2016-10-26T10:05:50Z")

</div>

This looks great. I had a quick go at replacing gproc in an app I’m working on. There’s one place where I use the await functionality of gproc to wait for a particular worker in a parallel supervisor hierarchy to start and register itself. Now that I look at the code I’m not sure if I need it but I was wondering if there were any plans for something similar?

Semi related question… I store the worker pid in a phoenix channel state. Would it be better to look this up in the registry each time I use it or grab it once and monitor in the channel?

---

<div class="post-metadata">

**Author:** ![josevalim](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/32/1787_2.png) [@josevalim](https://forum.elixirforum.com/u/josevalim)\
**Post date:** [October 26, 2016, 10:50am UTC](https://forum.elixirforum.com/t/proposing-registry/2121/13 "2016-10-26T10:50:39Z")

</div>

> [@chrismcg](#):
>
> This looks great. I had a quick go at replacing gproc in an app I’m working on.

Thank you!

> [@chrismcg](#):
>
> Now that I look at the code I’m not sure if I need it but I was wondering if there were any plans for something similar?

Not right now but I believe it could be implemented using the partitioning semantics, so that seems possible.

> [@chrismcg](#):
>
> Semi related question… I store the worker pid in a phoenix channel state. Would it be better to look this up in the registry each time I use it or grab it once and monitor in the channel?

Looking up every time is cheap and simpler, so maybe that? Unless you need to synchronize state between both processes. In this case, you need to associate them somehow by either monitoring or linking.

---

<div class="post-metadata">

**Author:** ![josevalim](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/32/1787_2.png) [@josevalim](https://forum.elixirforum.com/u/josevalim)\
**Post date:** [October 26, 2016, 12:51pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/14 "2016-10-26T12:51:57Z")

</div>

@voltone and others have benchmarked the registry. I have consolidated @voltone results here:

> **[Comparing registries](https://docs.google.com/spreadsheets/d/1MByRZJMCnZ1wPiLhBEnSRRSuy1QXp8kr27PIOXO3qqg/edit#gid=0)**
>
> This Sheet is private

Summary: on a machine with 40 cores, a Registry with 40 partitions provides across the board better results on concurrent registration. Without partitioning, the Registry starts to scale poorly when the concurrency factor is somewhere between 8 and 20.

Surprisingly, gproc performs quite well, even in concurrent scenarios. \<speculation\>I am assuming serializing writes ensures there is no contention for concurrent threads, so less coordination and process switches.\</speculation\>.

Erlang’s built-in atom registration does not perform well in highly concurrent scenarios but that’s fine. It was not meant to support dynamic names registration anyway (and doing so would certainly be a bug in your app!).

---

<div class="post-metadata">

**Author:** ![bbense](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bbense/32/1074_2.png) [@bbense](https://forum.elixirforum.com/u/bbense)\
**Post date:** [October 26, 2016, 1:45pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/15 "2016-10-26T13:45:33Z")

</div>

I have easy access to 24 core machines if there is some specific test you would like me to try.

---

<div class="post-metadata">

**Author:** ![dimitarvp](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/32/38664_2.png) [@dimitarvp](https://forum.elixirforum.com/u/dimitarvp)\
**Post date:** [October 26, 2016, 2:28pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/16 "2016-10-26T14:28:54Z")

</div>

I am not sure I am reading the spreadsheet well – but did anybody make a benchmark on the Macbook 2015? The 12" with a single USB Type-C 3.1 port? I have it and can run the benchmark anytime.

EDIT: When I run a benchmark, how do I contribute the results to the spreadsheet?

---

<div class="post-metadata">

**Author:** ![josevalim](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/32/1787_2.png) [@josevalim](https://forum.elixirforum.com/u/josevalim)\
**Post date:** [October 26, 2016, 8:47pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/17 "2016-10-26T20:47:40Z")

</div>

I have bumped the version to 0.2.0. This version removes whereis/2 in favor of lookup/2. The new lookup/2 function works on both unique and duplicate registries.

put\_info/3 and update/3 have also been added.

> [@dimitarvp](#):
>
> EDIT: When I run a benchmark, how do I contribute the results to the spreadsheet?

That spreadsheet is about one single 40 cores machine. Feel free to copy it and add your own numbers. 🙂

---

<div class="post-metadata">

**Author:** ![imranismail](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/imranismail/32/1763_2.png) [@imranismail](https://forum.elixirforum.com/u/imranismail)\
**Post date:** [October 26, 2016, 9:47pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/18 "2016-10-26T21:47:43Z")

</div>

@voltone is it possible to also include syn benchmark?

[https://github.com/ostinelli/syn](https://github.com/ostinelli/syn)

---

<div class="post-metadata">

**Author:** ![josevalim](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/32/1787_2.png) [@josevalim](https://forum.elixirforum.com/u/josevalim)\
**Post date:** [October 26, 2016, 10:39pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/19 "2016-10-26T22:39:54Z")

</div>

Syn is global. They are not equivalent.

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [October 26, 2016, 11:15pm UTC](https://forum.elixirforum.com/t/proposing-registry/2121/20 "2016-10-26T23:15:58Z")

</div>

Hello! Why phash2? Have you compared it to scheduler pinning (`:erlang.system_info(scheduler_id)`)?

[Next page](https://forum.elixirforum.com/t/proposing-registry/2121.md?page=2)
