A Bubble booking app whose platform bill grew faster than its revenue
At $9,400 in monthly revenue the app was consuming $2,300 a month in workload units, rising 18% a month against 6% revenue growth.Composite engagement. Details anonymised; figures are representative.
$2,300 → $640
monthly platform bill, same traffic
- Platform
- Bubble
- Industry
- Consumer marketplace · Fitness booking
- Duration
- 5 weeks
- Findings
- 1 critical, 3 high, 2 medium
What we walked into
A booking marketplace connecting 220 independent fitness studios with about 11,000 consumers. Built in Bubble by a non-technical founder, profitable on paper, and genuinely well made as a product.
The problem was arithmetic. Two plan upgrades in five months had been needed purely to stay under the workload cap, and the next tier would have pushed platform cost past 30% of revenue.
Bubble was not the wrong tool for this app. The app was simply doing far more work than the product required - and because workload arrives as one number on one invoice, nobody could see which part of it was expensive.
Every engagement opens with a free consultation and a scoped audit. This one drew on the following:
Composite engagement. Details anonymised; figures are representative.
What we found
Severity is about consequence, not effort. A critical finding is one where a stranger can read data, move money, or destroy state.
- Critical
Privacy rules added after the data model
Six data types were readable through the Data API by any signed-in user, including bookings - customer name, phone number, and full class history - and studio payout records.
- High
A search inside a repeating group
The schedule page ran a nested search: for each of up to forty classes, a further search across all bookings to compute remaining spots.
- High
An hourly workflow scanning the entire booking table
A reminder job searched every booking ever created, once an hour, to find the ones starting in the next two hours.
- High
List views with no constraints
The studio directory loaded all 220 studios with every field, including a description field averaging four kilobytes, and filtered in the browser.
- Medium
Images served at original size
Studio photos uploaded at up to six megabytes were served unresized into cards 320 pixels wide.
- Medium
No attribution for what was spending
Workload was a single monthly figure with no breakdown. Nobody could name the expensive workflow, which is exactly why the response to every overage had been to buy a larger plan.
The work we did
Delivered over 5 weeks, on branches, alongside a founder who kept shipping product the whole time.
- 01
Instrumented consumption before changing anything: two weeks of per-workflow attribution, so the work went where the units actually were rather than where they felt like they were.
- 02
Rebuilt privacy rules from the data model up, type by type and field by field, then verified each one by querying the Data API with an ordinary user token instead of trusting the editor preview.
- 03
Replaced the nested search on the schedule page with a maintained spots-remaining field, updated by the booking and cancellation workflows: one search per page load instead of forty-one.
- 04
Rewrote the hourly reminder job to query a narrow, date-bounded slice instead of scanning the booking table, and moved it onto the backend workflow queue.
- 05
Added constraints, pagination, and field selection to the directory and search pages, so the cost of a page stops tracking the size of the catalogue.
- 06
Moved image handling to a resizing CDN and set explicit dimensions on every card.
- 07
Set up a weekly workload report and an alert on consumption anomalies, so the next regression shows up in days rather than on an invoice.
- 08
Documented which parts of the app would need to leave the platform first if growth continues, with the cost model for when that becomes worth doing - and the honest conclusion that it is not worth doing yet.
Before and after
The same metrics, measured the same way on both sides of the work. Where a number got worse, it is in the table.
Monthly workload units
68 M19 MSame traffic, measured over a thirty-day window after the changes landed.
Schedule page load
6.5 s2.1 sThe most-visited page in the app: forty-one searches down to one.
Directory first load
21 MB1.8 MBResized images, pagination, and selecting only the fields a card renders.
Data types exposed via the API
60Verified against every type and field with a real, ordinary user token.
Platform cost as a share of revenue
24%6.8%At unchanged monthly revenue. The plan tier came down two steps.
Monthly infrastructure cost
$2,300/mo$640/moIncludes the image CDN added during the work. This is the only engagement of the five where hardening also reduced the bill.
Composite engagement. Details anonymised; figures are representative. Figures are rounded from what we measured across the engagements this study is drawn from.
What it runs on now
The builder stayed in the picture where it earned its place. Nothing here was rewritten for the sake of rewriting it.
- Bubble
- Bubble backend workflows
- Bubble Data API
- Cloudinary
- Stripe
- Postmark
- Metabase
Every time we hit the cap we upgraded, because upgrading took ten minutes and looking took a week. It turns out the looking was the cheap option.
Other write-ups
Different builder, same shape of problem.
- Lovable
A Lovable client portal where every tenant could read every other tenant
11 → 0 - tables readable across tenants
Read the write-up - Replit
An internal ops tool that lost a week of data every time it redeployed
96.8% → 99.95% - measured uptime after the move
Read the write-up - Base44
Record-level authorization for a Base44 equipment-rental marketplace
6 → 0 - endpoints returning other users' records
Read the write-up
Same builder, same symptoms?
Send us a repo link and a paragraph about what it does. The audit is free and the report is yours either way.