When to pivot to a custom code

So I’ve created quite a complex system I think. Lots of operations, searches, apis etc etc. its a solution for doctors/clinixs. And according to my conservative estimates, I’m thinking that roughly 1 doctor/user will be consuming somewhere around 130,000 140,000 workload units monthly. My questions are:

  1. Is that a realistic estimate? I know you guys can’t tell but maybe a ballpark figure ?
  2. When should I pivot to a custom coded solution?
  3. Is bubble reliable with speed ? With searches and all? Reliable with backend workflows and API workflows ?

I have a programming background so I’ve already structured my app in a way that data would be easy to migrate later on I just need advice as to when I shud plan to

I think that’s a touchy subject right now. You will also get a biased answer since all the people on the forum are still currently advocating and using Bubble. :blush:

I’d be surprised if it was 130k WU per user per month, that’s a lot, even if they’re using it every day. 50k seems a much more reasonable estimate, which means the cost of Bubble per user would be $6/user/mo. So, if you’re charging, say, $30/user/mo, that’s pretty good.

Are speeds reliable ? So if a doctor has 100s of patients and prescriptions and stuff. Lots of objects in my database that get created. Are search operations fast enough? Also once the app is deployed, how reliable is bubbles up time? I’ve been seeing some complaints recently that the actual uptime is not as they show it.

Yes, if you build your database in a scalable way

As of the last 3 weeks, not very good. But the system that’s caused that downtime is now removed entirely I believe, so at least that particular patch should be behind us

Like George is saying, it’s really a question of building both the database and your workflows in a scalable way. New Bubble users often mess that up big time. I talk from experience: During the first year or so after my first Bubble-app launch in 2021, I learned new ways of improving scalability on a daily basis, and frankly in a large app you’re never running out of new ways of optimizing performance.

A tool newbie Bubble devs have today that long-time users didn’t (George here comes some free marketing): Use Buildprint and ask agents to find ways of improving performance and optimizing for WU efficiency. Since we started using Buildprint I believe we’ve reduced WU usage by about 20%, most of which came from fixes to a few very inefficient recursive backend workflows.

I’m willing to use Buildprint. But idk if I’m too comfortable yet. Is the AI smart enough to completely understand my system and not mess anything up?

My controlling nature doesn’t allow me to let it do something that I don’t know or see. Feels like it might mess something up lol. But if it’s really reliable then I’ll try. are there any prompts or precautions to use with buildprint ?

Just use Plan mode while you’re identifying potential improvements, ask for diagrams and plan tables to get a clear picture of what exactly you need to edit, and switch to Build mode only when you’re onboard. Buildprint creates savepoints so you can revert back. For larger changes and improvements, such as changes to crucial backend workflows or data schema, create a new branch and limit access to that specific branch.

It’s very reliable, and like I said, you can always revert back to the savepoint if something goes wrong.

On this point, you’ll be surprised. Our main app’s got around 1100 backend workflows, hundreds of frontend pages and reusable elements, about 300 data types. I assure you, if you’re using GPT 5.6 Sol, Opus 5, or Fable 5, it’ll understand your app really well.

Okay my app is nowhere near that complex. What’re your search speeds like on the app? And are your users happy with the speeds ? I’ve heard somewhere that sometimes backend workflows that are scheduled just don’t run. Or timeout. Is that your experience ?

I’ve never found search speed to be an issue, and page load speed (which was always okay) has improved quite recently. Once again it’s a question of building the app in a scalable way, and that’s the case whether you’re using Bubble or something else, particularly by using “do a search for” efficiently, retrieving only information that’s actually useful in the UI or to a workflow, and using “list of”-fields to map data related to a record that you’re using frequently, especially if you’re using that data in repeating groups (assuming the list remains relatively short, certainly less than a couple hundred entries) since you’ll avoid “do a search for” in every row.

Backend workflows not running is a rare issue, but it’s not non-existent. That could happen as the result of an outage with any service, just as it can with Bubble. The way we’re solving this is by tracking the status of a scheduled workflow through a data type and by scheduling it twice, generally a few hours apart. When the scheduled workflow runs, the retry is canceled. Doing it this way also makes it easier to locate and cancel scheduled workflows since we’re storing the workflow ID which is necessary to trigger the cancel scheduled workflow action. Here’s our data type schema:

As you can see, we’re also recording the time the workflow was scheduled for, so if it remains in a pending state after the time it was scheduled for, we’ll see that through a filter in our platform admin portal (a feature we’ve built for internal use in the frontend).

That’s wonderful. Thanks for the info. Just 1 thing. My app logic is more or less sound and quite lean. Tho I’ll defo start using buildprint. but to give more of a native web app feel, I’ve gone with tab logic. So my app only has about 2-3 pages but the pages have many views/tabs. So a dashboard page has about 5 tabs like overview/ consultation/ patients etc. is that the efficient way to go? Or is it more sensible to have more pages ?

I feel like using the tab logic may make the first load a bit slow but then the app feels faster later on. Pages might make it more of a website feel
In any case which is more recommended ?

I typically hide pages behind roles so a receptionist page, index page, login page etc.

I definitely prefer that type of setup: A page for login/signup, one page for each action you’re likely to perform rarely or just once (such as onboarding), and a page for the main app. Personally I prefer using reusable elements a lot, almost as if they were pages on their own. Keeps the app more organized, and you’ll notice with large apps that the editor speed becomes an issue on pages with hundreds of elements (that is, the speed of the Bubble Editor, not the app itself).

If you do this you may end up with lots of data fetches that are unnecessary and can eat up WUs. There are simple ways to ensure you do not load data until necessary via conditionals, so make sure all data fetches are behind conditionals if you use the tabs.

Without knowing what the app does, or how a user would expect to use it, a well built optimized app should not require more than 10,000 WU per user per month, and if you really know what you’re doing you can probably get it to be around 1,000 depending on what the app does and how the users are using it.

You can also improve performance of data fetching using a Hybrid Data Structuring approach that also reduce data fetches WUs and bulk data creation and modification. If done properly for correct use cases and data you can get 30-50% performance improvements in data load times and 95% reduction in WU costs for data fetching.

Either way, the question of when to migrate to custom code is not when but if…with a doctor app, that might touch patients data, compliance requirements may be biggest factor in that decision and nothing to do with performance, uptime or costs of Bubble.

The editor definitely gets slow form time to time but that’s okay. As long as it’s me who’s suffering and not my users haha.

I haven’t used reusable elements much but I can see the benefit. Especially when maintaining uniformity across the app in terms of appearance and operational logic.

Yep most of my data searches are hidden behind visibility conditions. Trying to minimise database fetches and if I do them then I make sure I edit as much as possible in a single run. I think it’s reasonably optimised. But just read up a few articles here and got worried.

But you guys look fairly happy with your apps and mine isn’t as complicated anyway so I think I’m happy.

Just one thing. Has anyone made an app with the entire database hosted elsewhere like mongo or sth? Was wondering if that’s a doable approach. API calls might be more WU intense tho. For now I’m using bubbles own database tho.

You say you have programming experience…

so you obviously know going the code route will save you money. But, on the other hand, it will cost you a lot more time and headaches. So the question is what your time is worth.

It’s best to rent the tools (Bubble) while you can.

I would suggest you stay with Bubble until you reach the point where switching over will pay for itself… if you ever get to that point.

As others have alluded to, you can go a long long way with Bubble before you ever (if ever) need to leave and go another route to make it a worthwhile investment.

True! Once again all about building with scalability top of mind and using Buildprint and other tools to improve performance and optimize for WU efficiency.

130k WUs is too high.
You will be able to optimize this imo, this sounds like the implementation has scope for streamlining.

You have to follow some best practices while designing your DB - it needs to consider privacy rules AND your UX (what kind of searches / filters / associations are necessary). Once optimized accordingly it works decently. But there are inherent load speed limitations.

Before moving to custom code, you could probably use Buildprint’s AI functionalities.
I personally dont use the Bubble’s inbuilt AI for anything and don’t recommend it.

Also if you’re going to host your DB elsewhere, I’d just move the entire app elsewhere. The whole point of Bubble is that it lets you manage everything graphically in one place. So that defeats the purpose.