sbuttgereit

sbuttgereit

Hi–

I’m in the early process of building an application that will include mutlitenancy. Given the overall design considerations, the Ecto features allowing for multiple dynamic repos looks very workable for our case. For data, we’ll only be targeting PostgreSQL and using individual databases in a PostgreSQL cluster for each tenant.

The big point that’s unclear to me right now is if the Ecto implementation is possibly subject to race conditions when concurrent database accessing processes try to set different repos via MyApp.Repo.put_dynamic_repo/1. The documentation says

From this moment on, all future queries done by the current process will run on
[repo].

But to me it’s unclear what “current process” means here. The current process that made the put_dynamic_repo call or the process related to MyApp.Repo?

So for example, let’s say I have a process that is booking a set of transactions for Tenant A… it starts off by calling put_dynamic_repo(:tenant_a) and then proceeds to process its queries… but midway through those steps, a second process comes along with work for Tenant B. That process calls put_dynamic_repo(:tenant_b) and starts its work. Assuming that the process for Tenant B makes it’s put_dynamic_repo call before the process for Tenant A is finished… does the process for Tenant A start making calls to the repo :tenant_b? Or do these processes necessarily need to be serialized in order to ensure correct execution of the database queries?

I couldn’t see it clearly enough stated for a newbie such as myself to know with certainty how that’s managed or if it’s managed. I saw a topic talking about what I’m doing here (Multitenancy with Ecto), but it didn’t address this issue. There’s enough stuff going on here in the code, and I’m sufficiently inexperienced with Elixir, that I thought asking here was probably best.

Thanks,
SCB

Showing Posts 1 to 3

josevalim

josevalim

Creator of Elixir

Each request is handled by a separate process. This is not the operating system process but a lightweight thread of execution in the VM. You can literally have hundreds of thousands of those.

Processes are isolated and run concurrently. When you set the dynamic repo for one process, it does not affect any other process/request whatsoever. There is no serialization or race condition.

The information is stored on what is called “the process dictionary”. Depending on your background, it would be equivalent to “thread local variables”.

sbuttgereit

sbuttgereit OP

Many thanks for helping me with this question.

I’m thinking about this purely in terms of Elixir/BEAM processes. The concern came from seeing a pattern, generically speaking, where a primary action (put_dynamic_repo) is setting state somewhere that subsequent actions (e.g. `MyApp.Repo.all(query)') are depending on to determine their behavior.

The information is stored on what is called “the process dictionary”. Depending on your background, it would be equivalent to “thread local variables”.

I think this is the crux of what i was hoping for. So long as the effects of put_dynamic_repo are sufficiently isolated/local so that concurrent processes all making various MyApp.Repo calls only see the repo they set with put_dynamic_repo, then life is happy. Sounds like this is the case.

And I would assume that all that had been worked out… but while I’m an Elixir newbie, I’ve got enough overall experience to know that these things shouldn’t be assumed!

Now the only sticking point is that this functionality is still marked “experimental” :grinning: …

Thanks again,
SCB

josevalim

josevalim

Creator of Elixir

I believe we removed the note in master (with no changes to the API).

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews