New Pricing Disaster

I just want to add that I hate Airtable too!

Though it’s because of that annoyance with Airtable that led me to find Bubble.

2 Likes

Knowing when to write your own Python API to extend a Bubble app, for me that usually comes down to when doing compute heavy actions… Bubble’s greatest value proposition is “display stuff in a browser”… it’s not very good at “compute many things” to display in browser. For example, the cost calculator for one of my plugins is powered by a Python endpoint… could I have done that in Bubble? Probably. Is it way easier in Python - yes! Expand the hidden code below and think about how to do it in native Bubble… I probably could have baked this into an Expression element using javascript but… because I already have a Python API setup, just adding this endpoint was easy enough. Beyond that, if trying to fetch data from other APIs/was a longer running process, like I was here, then that’s even more reason to try to do it in Python.

Cost Calculator Endpoint Code
@app.get("/api/v1/get_search_provider_pricing")
def compute_search_provider_costs(
    search_provider: str = "algolia",
    average_record_kb: float = 0.6,
    number_of_records: int = 50000,
    monthly_searches: int = 50000,
    regions: int = 1,
    is_new_algolia_plan: bool = True,
):
    def select_typesense_cluster_base_cost(
        number_of_records=50000, average_record_kb=0.6, regions=1
    ):
        region_cluster_pricing = {
            1: {0.5: 14.40, 1: 21.60, 2: 36, 4: 64.80, 8: 122.40, 16: 180},
            3: {0.5: 64.80, 1: 86.40, 2: 129.60, 4: 216.00, 8: 432.00, 16: 669.60},
            5: {0.5: 108, 1: 144, 2: 252, 4: 432.00, 8: 828.00, 16: 1260},
        }
        cluster_pricing = region_cluster_pricing[regions]
        cluster_gb = average_record_kb * number_of_records / 1000000
        minimum_cluster_gb = cluster_gb * 2
        recommended_minimum_cluster_gb = [
            key for key in cluster_pricing.keys() if key > minimum_cluster_gb
        ][0]
        base_monthly_price = cluster_pricing[recommended_minimum_cluster_gb]
        return recommended_minimum_cluster_gb, base_monthly_price

    if search_provider == "algolia":
        if is_new_algolia_plan:
            if number_of_records <= 100000:
                cost_number_of_records = 0
            else:
                cost_number_of_records = (number_of_records - 100000) / 1000 * 0.4
            if monthly_searches <= 10000:
                cost_monthly_searches = 0
            else:
                cost_monthly_searches = (monthly_searches - 10000) / 1000 * 0.5
            cost = cost_monthly_searches + cost_number_of_records
        else:
            if number_of_records <= 10000:
                cost_number_of_records = 0
            else:
                cost_number_of_records = (number_of_records - 10000) / 1000 * 1.0
            if monthly_searches <= 10000:
                cost_monthly_searches = 0
            else:
                cost_monthly_searches = (monthly_searches - 10000) / 1000 * 1.0
            cost = cost_monthly_searches + cost_number_of_records
    elif search_provider == "typesense":
        recommended_minimum_cluster_gb, base_monthly_price = (
            select_typesense_cluster_base_cost(
                number_of_records=number_of_records,
                average_record_kb=average_record_kb,
                regions=regions,
            )
        )
        # works out to 720MB per day per node across a month multiplied by regions and 0.09 GB
        bandwidth_out_cost_base = 0.720 * 30.44 * regions * 0.09
        bandwidth_out_cost_searches = (
            monthly_searches * average_record_kb * 100 / 1000000 * 0.09
        )
        cost = (
            base_monthly_price + bandwidth_out_cost_base + bandwidth_out_cost_searches
        )
    return {"cost": cost}
2 Likes

+1

I now have a library of custom APIs that I use with various apps we work on. Some built with Python (using Flask), some with Node.js. I host them all on Google Cloud Platform for pennies.

Examples:

  1. File conversion endpoint that converts any endpoint to text (saves using expensive external API)
  2. Pinecone upsert endpoint that takes a text and custom metadata, chunks it, and upserts it all to Pinecone (saves loads of WU for large documents)
  3. Progressive tax rate calculator that takes tax bands, deductions, and an amount, and returns the relevant tax (would be more efficient in a client side plugin but wasn’t a rabbit hole I was willing to go down)
  4. Wasabi URL generator (the plugin I use has this integrated but Bubble SSAs take ages to spool up, so I just deployed it on Google Cloud).

The best thing? I coded all of them basically entirely with ChatGPT / Claude 3.5 Sonnet (Claude is better at this in my experience). I can’t write code - I can look at it and understand what’s going on, but I can’t be bothered with syntax (hey, that’s why I use Bubble!).

I dream that one day Bubble will add proper SSA building that’s reasonably priced and would actively encourage developers extending their app with custom code. However, it’s clear their product direction is ‘make bulk data better’ so that custom code becomes unnecessary.

I’m a Bubble-native all the way advocate wherever it’s reasonably possible, but Bubble isn’t perfect for every use case (and how could you expect it to be), which is why it’s okay to integrate it with other tools :slight_smile:

5 Likes

Nice idea you have.

I do think the code could be improved?

It makes the cost calculations easier.

Has error handling…

and rounds the final costs to 2 decimal places.

Just something you can consider.

1 Like

bubble actually called me yesterday and a spoke with one of their engineers / product support guys, and we talked about adding the WU cost to the workflows themselves so that when you create a workflow you can run it to determine the total cost. He liked the idea and wanted to take it to the team… so maybe they will implement it. :slight_smile: anything to cut down on log slogging

4 Likes

@ryan8 I kinda assumed this was something they’d thought of before. Jaw on floor if not true. Would have to be something normalized, though… so like reported as WUs per 100 records.

@senecadatabase Very cool, thanks for doing that :slight_smile:

1 Like

From https://www.youtube.com/live/o-mrUwQa1aM?si=HGnU2TPrzGE_DnEO&t=986

Revamped workflow logs design

well, I don’t wanna say bubble didn’t have the idea. They could’ve just been nice. Maybe they already had it on their Horizon. But I know they were gonna take it back to the team either way, even if it’s a maybe to help prioritizing that function. But it was a fun talk and nice to chat with them.

1 Like

Maybe this is related to the big news at bubbleCon considering how important it is going forward

1 Like

Thank you! :pray:

Great information. Thank you. I hadn’t heard of Claude. I’ve been using ChatGPT with somewhat satisfactory results. But since you say this is better I’ll give it a try.

My experience was the other way. I was already familiar with bubble, then went to work for a company that is in love with airtable. Were way too big for AT. We’re a manufacturing/construction company. Way too many parts, pieces, tasks. We exceed the limits of AirTable ok just one project. So I work around it with bubble. LOL

1 Like

I can personally vouch for Claude Sonnet. Been using it for about a month to build out some pretty complex stuff and it rarely misses. Even when it does, eventually it will figure out the solution, even if it means scrapping the original implementation. It’s much more flexible syntactically and often comes up with creative solutions due to that flexibility.

ChatGPT is too prone to making mistakes with code and often struggles with consistent layouts. Especially when you try to change something. It’s just too rigid and limited and has a bad habit of breaking code that works while attempting to correct code that doesn’t.

Claude Sonnet is superior in almost every respect. The only downside is I occasionally have to remind it about how I want something done after a long conversation…but that’s few and far between.

1 Like

Ha. “ChatGPT is too prone to making mistakes with code and often struggles with consistent layouts. Especially when you try to change something. It’s just too rigid and limited and has a bad habit of breaking code that works while attempting to correct code that doesn’t.”

So I’m not the only one frustrated with that behavior. I’ve many fights with ChatGPT over the very issue! I’ve had it get stuck in a rut and it refuses to get out of it. So then I start a new chat and have to explain the problem again, and summarize to where it stopped working. It’s fascinating that it can figure it out then. :roll_eyes:

I’ve also learned that the machine can get offended. Like really? Do what I tell you and I won’t have to go there. LOL

I’ll be giving this a try my next session! Thanks again!

1 Like