nicktenc's avatar

Multi tenant with a lot of service providers

Hi,

I run a multi tenant SaaS Laravel application and we are trying to improve the speed of our application. With 300-500 ms per page it's not that bad, but it's also not fantastic. Queries aren't the problem. Of course, we can make some of them a bit better, but we 'only' spend +-50ms on avg. per requests on queries. A big chunk of the rest of the response time comes from registering (+10%) and bootstrapping (90%) the providers.

We have 289 providers right now. Ouch :-)

Some of the providers are registered by Laravel, around 30 in total. Then we use some external packages, that's another 10. The rest are our own providers. We use providers to add custom code for tenants. So if they like a specific mail template, document template or an integration with some external API we create a tiny package, that gets registered and bootstrapped. Like I said bootstrapping most providers only takes 1 or sometimes 2 ms. But 289 * 1ms = 289ms lost on bootstrapping providers.

We have a couple of solutions in mind:

  • Remove unused packages (eg client is gone, we don't need the app) - Easiest to do, but won't do a lot.
  • Only use external libraries when absolutely necessary.
  • Make sure the provider doesn’t register itself for a request it shouldn’t (based on domain, page, etc)?
  • Build features that allows our customers to compose exports templates, emails and PDF’s, so we don't need to build custom apps in the first place. Probably one of the changes that wil have most affect, but also the most impact.
  • Serve (a part of) the application via https://laravel.com/docs/8.x/octane, so that the application boots ones (like a queue worker), and responses to incoming requests.
  • Speed up the bootstrapping a lot so that it takes a fraction of a ms to bootstrap a provider? Not sure if there are ways to speed this up (in code).

This is all on my local Mac. Production is a pretty fast and powerfull server, so there the speed is a big higher. My main concern is that we keep on adding new clients (good), but with the speed of building custom packages that we do now we could easily end with hundreds if not thousands of packages.

We can get rid of a lot of providers / packages by building a feature where our customers can 'skin' an email, document etc inside our application (so we don't have to build custom themes, email templates, etc). We can also do that for custom export formats. But then we still have the packages that handle custom integrations with external systems. You could build some workflow automation that supports some HTTP action, but not sure if we're able to support all kinds of integrations. So it looks like we would still be stuck to quite some packages...

Looking forward for some great idea's. I know that keep on building custom packages is not the right path :-(.

0 likes
2 replies
kitchh's avatar

Did you consider using PHP Swoole/Laravel Octance? Basically, avoid register & bootstrapping for each request?

nicktenc's avatar

@kitchh thanks! Yeah I did. I put it in my post that one of the options is to go to Octane. Which is using Swoole under the hood. But a bit worried what we’ll have to do to have our app running on Octane. But definitely something worth investigating!

Please or to participate in this conversation.