In web applications, cache is often used to temporarily store things in memory in order to speed things up.

In Elixir, the go-to library for this is Cachex.

In my use case, I wanted to setup different instances of cachex so that I can selectively clean them them up.

The way you normally set it up is by adding a child to the supervision tree in lib/my_app/application.ex:

children = [
  {Cachex, [:my_cache]}
]

To setup multiple caches, my first approach was to do this:

children = [
  {Cachex, [:my_first_cache]},
  {Cachex, [:my_second_cache]}
]

However, when you start the application, you'll be greeted by an error:

** (Mix) Could not start application my_app: MyApp.Application.start(:normal, []) returned an error: bad child specification, more than one child specification has the id: Cachex.
If using maps as child specifications, make sure the :id keys are unique.
If using a module or {module, arg} as child, use Supervisor.child_spec/2 to change the :id, for example:

    children = [
      Supervisor.child_spec({MyWorker, arg}, id: :my_worker_1),
      Supervisor.child_spec({MyWorker, arg}, id: :my_worker_2)
    ]

As the error message indicates, the way to fix it is to define them like this:

children = [
  Supervisor.child_spec({Cachex, [:my_first_cache]}, id: :my_first_cache),
  Supervisor.child_spec({Cachex, [:my_second_cache]}, id: :my_second_cache)
]

You can read more about Supervisor.child_spec/2 in the documentation.

If you don't want to set the value for id manually, you can also use the make_ref/0 function:

children = [
  Supervisor.child_spec({Cachex, [:my_first_cache]}, id: make_ref()),
  Supervisor.child_spec({Cachex, [:my_second_cache]}, id: make_ref())
]