Joel: Welcome to No Compromises. A peek into the mind of two old web devs who have seen some things. This is Joel.
Aaron: And this is Aaron. As we go into many different projects as consultants, we see a lot of different architectural patterns.
And one of them that has always been sort of interesting to me is the multi-tenancy sort of setup inside of a Laravel application, when that
Laravel application has to be used over multiple clients. So, it has multiple... I don't even know how to explain it.
So, the idea of multi-tenancy basically being I can use this one single codebase but maybe separate multiple databases.
That's a very simple way of looking at it. There's obviously many more different things.
But the idea, I believe, is to generate some sort of isolation between clients so that there's not any sort of mistakes, I guess.
As you see, I'm having a hard time describing it because... I'm, I guess... What are your thoughts on why people pick
multi-tenancy architectures versus just choosing one directly? And, I don't know, having a client ID where they query on that, or something?
Joel: Yeah, I think maybe part of the the struggle you're having is like, this is one of those terms that actually means multiple things. Right?
Aaron: Yeah.
Joel: Because you even started talking about number of databases. And I would say, within multi-tenancy, you can have a
true multi-tenant setup that is a single database, or is one per tenant. Like, those are kind of like the two main paths I've seen.
But I was trying to think of how to phrase this, too. Because what you're talking about is like an app with users that can log in,
has isolation between the users. At least, I hope it does. But that's not what I think anybody means when they say multi-tenancy.
It's sort of like a layer above this. Where it's like this tenant to stick with the term, maybe has its own configuration of how they use their app.
Or, maybe it has its own set of resources, whatever that means. You know, it's isolation at a higher level, at the tenant level.
And maybe a little more, even self-service, and they can tweak it a little bit. You know, I'm throwing a lot of different things out there,
because these are all kind of under that umbrella. Maybe this tenant has a custom domain, or at least a subdomain.
Like, those are the things where I think that's what people mean, one of those things where they say, multi-tenancy.
Does that resonate with what you had in mind?
Aaron: Yeah, I would say that's true. Because multi-tenancy could mean kind of like more technical thing that I talked about.
But it also could be, like you said, these different configurations. But again, then maybe the question is a little bit more nuanced.
Where I'm not talking about multi-tenancy as a concept, I'm talking about why do people use specific packages to separate this stuff.
Because all the things that you just sort of described, I can do in my main application. And by the way, I'm not against multi-tenancy.
I'm just trying to define it right now first.
Joel: Yeah, me too. Okay, that helps. And it kind of narrows the scope. So it's like, you're going to do some form of multi-tenancy.
And it's like, do you just roll it yourself with Laravel? Or, do you adopt a starter kit, or, at a smaller level,
maybe a package that sort of enforces all of these things for you.
Aaron: Right.
Joel: Okay. So, when somebody comes to us with one of those questions. Do you have a default leaning?
Or, what are the things you would ask them to maybe try to help them, guide them toward a decision on how to proceed?
Aaron: Yeah. So, one of the challenges I've seen is when people do the multi-tenant thing and they talk about that different configuration,
they never know when to stop changing the configuration. And so, at some point, multi-tenant becomes...
there's actually if statements, or caches and all that kind of stuff. Or there's a code that's dot this client name, or something.
I mean, there's good ways to do that. There's strategy, patterns you can plop in there and whatnot. Or the database completely changes.
So, maybe it's a multi-tenant database the models all look the same, but technicall the Eloquent model has to do something
differently if it's this tenant because that database actually has three more columns that no one else needs,
but that client definitely needed. So, it's those sort of things that I've seen the problem come out of.
So, to answer your question. When someone says they need a multi-tenancy, I try to ignore that, and I just start asking them about
their application. And the things that I'm looking for are... And again, I'm being very focused, very specific on what I
believe multi-tenancy to be in this particular comment. I look at, does the data literally need to be separate between clients?
Like, physically. You mentioned something about, like, it could be the same database, maybe prefix tables, or something like that.
I get that, but I'm thinking of like, there's literal database separation, different zones. All kinds of different things like that.
You know, different login, username and passwords to access those resources. And you kind of hit on that when you said different
resources for different clients. But again, that could be configured at runtime. Like, if we look at the subdomain, it's all the same code.
What is the credentials? We pull it out from some stored secret, and that's how this works. So it's really, when I think about multi-tenancy,
I think, is there actually a law or a reason, or a necessity for this? Or, is it just something you think you should have?
Or something you would like in the future? When you have so many users, you're going to need multi-tenancy.
Well, let's get so many users first. You know?
Joel: Yeah. And when you say law, I just want to call that out. Like, a client might have customers in the EU, and there's like data privacy or...
What do they call it? Data governance. Like, where it literally has to be in a data center in the EU to legally comply with their laws.
So, then you have, unless you're going to... They put all your stuff there, you have to have multi-tenancy to separate that out.
Aaron: But again, then that also brings up the question. Is like, it could live there, and it could use the same code,
not have a multi-tenancy package from Laravel at all. And just have a middleware or something that
says, "If you're at the subdomain, you're using these type of credentials." I mean, it sounds a little hacky
in some ways, but at the same time, why bring in a whole package if you can solve it with a middleware and five lines of code?
Joel: Well, yeah. And I mean, Laravel has the concept of different database connections.
So it's not hacky, like you're introducing some totally new thing to the database or to the application,
but it's in there in the framework. But, yeah, how you specifically route to a particular connection based on a request, or whatever,
that's where there's some design decisions to be made. And honestly, any package you pick is going to just impose its design decision on you, right?
Aaron: Right.
Joel: So it's going to still be doing those same things. It's not some magical extra way of doing it.
It would be using one of the strategies you would use if you rolled it yourself.
Aaron: Yeah. So, I ask those questions, and then try to determine if it's necessity, and then what level of it is.
You know, it's the same sort of... I'm going to try not to expand the scope of this conversation.
But it's the same sort of question when people say things like, "Oh, I need the modules package for Laravel to put all my stuff in
different modules." A lot of projects may need that, but does yours? So, that's the same question. Is like, I get that that's definitely...
It's like all the people that tried to architect stuff after Netflix. Yeah, but you're not Netflix, so stop that.
Joel: But I could be. Okay, so let's just stick on the multi-tenancy and kind of maybe just frame it around.
Do I need a package, or am I going to do it myself? And the thing, I'll be honest, that concerns me a little bit about this decision...
Because there's so much in coding where it's like, "Well, I don't need it yet. I'll add it when I need it."
But this does feel like, unless you disagree, this feels like a decision that is kind of hard to change two years into a project.
Or do you disagree? Like, if you hand-rolled your own multi-tenancy approach and then decided, like, "I should have used the package,"
like, that's a pretty big change to make, isn't it?
Aaron: Yeah, I would agree with that. I think it has to do with how far you go with your own hand rolling thing again.
And it's what is the actual requirement? Is the requirement to have the exact same code?
The exact same everything, just a separate database? Then what do I need a package for?
Joel: Right.
Aaron: But if it's other things. Like, we will have a separate database, and some of the code will be different, and this.
And some of the strategies will be different, and this and that. Then I can start to see reasons for having this tenancy built up,
and you can kind of build out, does this tenant have this functionality? But again, you're still doing gate checks and
you're still doing different things on that tenant. So in reality, what I'm saying is, yeah, you could use the package to
make sure you're doing it consistently, that you're not reinventing the wheel all the time. And that's good once you get past the first thing.
But once you're doing a couple different things, you're using that package, then you have to make sure you're not doing too many crazy things
and changing too much just because you have tenancy now.
Joel: Yeah. And I'm not advocating one way or the other globally. I mean, because these all are application and business-specific decisions.
But I just wonder if there's a parallel. Like, the argument we might make to somebody. Like, "Don't roll your own framework."
And the advantage is, with Laravel you get all this stuff for free, and there's documentation and somebody's fixing bugs.
Like, does any of that factor in at all with this... specifically the idea of a multi-tenancy package?
Or, do you see it just as sort of like the same evaluation with any kind of package you might choose to bring into your app or not?
Aaron: Well, you kind of just led me to the answer, because we've talked about that before.
Like, you could code something, or you could use a package. But if you're going to use a package, make sure you understand what the package does.
And do you even need a package with that? We've talked about that on podcasts or tips, and stuff like that.
So it's the same thing. Like, do we just keep coming back to the same thing, I think. Which is, what is multi-tenancy mean to you?
What's actually required? And those DOE's answers, you actually think multi-tenancy means to you and your application now, and
up to six months in the future? Never further than that, come on. That's how we make our decision.
Joel: Yeah. I like that, it's a balanced approach. And we always like to... at least I, I like to have rules and kind of guidelines.
But this is sort of almost too big of a discussion to boil down. But I think maybe one of the takeaways is,
if somebody just puts on a requirements. Like, "We need multi-tenancy package X," it's definitely worth a discussion.
Like, how did you pick that package? And what features are we going to use in that package? And is this well supported?
And all those sorts of things. Like, what's its roadmap? I mean that just kind of...
Aaron: You said something interesting, too. Which was the comparison with Laravel.
So I'll give a good comparison on how that's the same as this multi-tenancy thing.
Joel: Okay.
Aaron: Like, if you said to someone, you only have PHP available to you, have a CSV file,
and I need you to extract the CSV and just print it to the screen. There's multiple ways to do that.
Joel: Sure.
Aaron: The easiest way is actually using, probably, league CSV or something like that, and just having it do that.
But that's a package, you know. Do I need that? If that is the only task ever, like it is one time, why not just use fgetcsv built in the PHP, you know?
Joel: Yeah.
Aaron: And so, it's that sort of thing where it's like. Well, what do you actually need and how much of that actually
matters to everything else you're doing, determines on how you pick the answer to this particular question.
Joel: I like that. There are certain things in my life I have mental blocks about. And I'm going to share...
I'll maybe share two of them with you. There's a long list, so we could be there all day. But I'm going to share this
just to give you a tangible example and then see if you relate to this at all, or if this is a uniquely weird thing about my brain.
So, there are two rooms in our house that have a place to sit.
Aaron: Heated floors.
Joel: Um, no. There's only one. There's two rooms where you can sit, and you could talk to people, or you could watch TV, right?
Aaron: Sitting rooms. Living rooms/sitting rooms.
Joel: Now, you're making it worse. Okay, so in our house, one of them is called the living room, and the other is called the family room.
Aaron: Okay.
Joel: And, for the life of me, why is one one versus the other? And here's why it even matters.
We have an Apple TV in each room, and when I want to cast to the TV, I have to stop and think to myself. Like, "All right, which room is this?"
And it's like mental effort, it takes me at least 30 seconds to think, and I still guess wrong about 10% of the time.
And then the kids in the other room would yell at me, like, "Dad, why is your thing on our TV?"
So, first of all, do you have something to help me understand that? And is there any help for me?
Aaron: I'm sure there is a historical reason why things are called the living room, the sitting room, and the family room.
But without looking it up, I have no idea. I just assume that the living room is what most people have.
And the family room is what rich people have and the sitting room is what uber-rich people have.
So that's why I started out with sitting room with you. Because I was like, "Well, he has the heated floor in his bathroom, so."
Joel: Well, this isn't going to help me at all. And you're making fun of me for having a rich house.
But the family room has the fireplace, and that's kind of how I think about it. Is like they both start with F.
But then that throws me off, because our living room has a fish tank, and I'm like, "Wait, is that the F?"
And anyways, this is what goes through my brain far too often.
Aaron: Understood. Hey, do you need some help on one of your upcoming projects? Well, if it has multi-tenancy, I want nothing to do with it.
Joel: Aaron is just joking. We are happy to talk to you. Head over to nocompromises.io and set up a call.