When Your Users Run Out of Internet, Page Weight Is a Product Requirement
How I designed and shipped an ultra-low bandwidth landing page platform using Astro and Cloudflare, enabling non-technical sales teams to launch edge-deployed pages while saving ~70% in load times and cutting time to market from 4 days to 6 hours.
TL;DR — During a consulting engagement in Brazil (Dec 2025 — Jan 2026), I designed and shipped a markdown-driven landing page platform on Astro and Cloudflare’s edge for a real estate brokerage whose buyers literally run out of mobile data mid-month. The platform replaced Unbounce’s 6.5MB pages with ~300-500KB edge-deployed pages. Results: conversion rates up over 45%, cost per lead down over 20%, time to market from 4 days to 6 hours, and $12,600/year in SaaS costs eliminated.
The Brokerage Was Paying $12,600 a Year for Pages That Cost Their Users Data They Could Not Spare
Brazilian real estate launches — lancamentos imobiliarios — live and die on their landing pages. A developer announces a new building, runs paid traffic on Google, Meta, and TikTok, and every click lands on a conversion-optimized page designed to capture a lead. At the brokerage, these campaigns drove 150,000 monthly page views across active launches. Having personally managed 13,000+ yearly lead-gen campaigns across Google, Meta, TikTok, and Taboola for the brokerage’s new development launches, I understood the unit economics of paid traffic intimately — every wasted click on a slow-loading page was money I’d spent myself.
I took on this initiative as a consulting project during my winter vacation in Brazil (December 2025 — January 2026), serving as the product and technical lead responsible for product strategy, architecture, and the build itself. The brokerage had been running these pages on Unbounce for years, iterating on a single high-converting template. The template worked. The economics did not.
At the time, Unbounce’s largest plan cost $249/month and included 50,000 views. Beyond that, each additional 10,000 views cost $80. At 150,000 monthly views: 100,000 excess views across 10 increments at $80 each, plus the base plan. $1,049/month. $12,600/year. For one template.
The Users Who Cannot Afford Your Page Weight
The cost argument alone would have justified the project. But the deeper product insight was about who these landing pages actually serve.
The brokerage’s lancamentos targeted Class C and D buyers — everyday working families buying their first home through Minha Casa Minha Vida, Brazil’s government-subsidized housing program for households earning up to R$4,700/month (~$800 USD). They browse exclusively on smartphones, often on prepaid data plans. The research paints a stark picture:
- 88.9% of Brazilians own a mobile phone, with 75-85% of lower-income groups using smartphones as their only internet device[1][2]
- 35% of people earning up to one minimum wage went 7+ days without mobile internet in the last month because they ran out of data[3]
- Prepaid users on small data packs pay ~75% more per GB than users on larger plans[4]
- Lower-income neighborhoods have systematically slower speeds and higher latency[5]
- Internet-enabled handsets cost 6% of monthly GDP per capita in Brazil — meaning older, lower-spec Android devices dominate[6]
When a potential buyer clicks a Google ad for a R$250,000 apartment, they are likely on a prepaid plan with 2-3GB of monthly data, on a phone with a weak CPU, on a connection slower than what SaaS builders are designed for. A 3-5MB Unbounce page is not just slow for these users — it is a meaningful fraction of their remaining data budget.
Page weight is not a performance metric for this audience. It is a product requirement. A page that costs too many megabytes to load is functionally broken. This framing changed the entire project.
The Hypothesis
If I built a platform that made ultra-light landing pages the default — not the exception — the brokerage could serve bandwidth-constrained users without sacrificing conversion optimization, while eliminating $12,600/year in SaaS costs and cutting launch time from days to hours.
The secondary hypothesis was about competitive positioning. I searched for case studies of Brazilian real estate companies using edge-deployed landing pages and found zero. Nobody in the lancamentos market had framed bandwidth as a constraint worth solving architecturally.
Alternatives Considered
Before committing to a custom platform, I evaluated three alternatives.
Optimizing Unbounce pages was the lowest-effort path. But SaaS builders have a weight floor. Inspecting the production Unbounce page, the total transfer was 6.5MB — 3.8MB of JavaScript alone. Unbounce’s own platform bundle plus its jQuery dependency accounted for ~490KB, but the architecture forces every tracking script (Google Tag Manager, Meta Pixel, TikTok, Hotjar, Taboola) to load client-side on every page view, adding another ~3.3MB. You cannot configure an Unbounce page to produce a sub-500KB output. The platform architecture is the constraint, not the template.
Switching to another SaaS builder (Leadpages, Instapage) would have traded one set of platform overhead for another. Every builder in this category optimizes for drag-and-drop flexibility, not bandwidth-constrained delivery. The problem was structural.
WordPress with aggressive caching was the other path the brokerage had tried previously. It improved latency but still required server-rendered pages, plugin overhead, and ongoing infrastructure maintenance — without solving the page weight problem.
The approach I chose — a markdown-driven static generator deployed to Cloudflare’s edge — was the only path that could produce pages under 500KB by default. Not through optimization heroics, but because the architecture eliminates overhead at the foundation.
Pitching “let me build a custom Markdown-based static site generator” to real estate executives sounds like an over-engineered science project. Savings alone do not overcome organizational inertia — leadership knew Unbounce worked and had no appetite for risk. So I de-risked it: I built a working prototype alongside Unbounce for a single campaign, same template, same copy, same pixels. The prototype loaded in under a second on a throttled 3G connection. The Unbounce version took eight. I showed both side by side on a phone in the room. The pitch was not “trust my architecture” — it was “look at your screen.” I ran both versions live for two weeks, confirmed lead capture parity, and cut over.
Even after the demo, adoption was not unanimous. Sales directors worried about reliability — they had built their campaign workflows around Unbounce and needed confidence that an in-house platform would not go down during a launch weekend. I walked them through Cloudflare’s edge architecture: static files served from Brazilian PoPs, no origin server to fail, uptime guarantees backed by infrastructure they could verify. Marketing coordinators went completely bonkers about Markdown — it looked like code to them, and they had spent years in drag-and-drop editors. I created full documentation on the brokerage’s internal portal and walked them through their first pages field by field, old Unbounce tab next to new .md file, until they saw that the same fields they already knew were just in a different format. Realtors flagged reliability concerns of their own — would their launch campaigns actually go live on time? I went back to the drawing board each time, addressed concerns individually, and showed them the deployment pipeline in action. The economic argument helped close the remaining skeptics: hiring a UX/UI designer to rebuild an Astro template costs $150-200, one-fifth the cost of the old process, meaning the brokerage could iterate on page designs at a fraction of what template changes used to cost.
Designing the Platform
The platform has three design principles: every page must be ultra-light by default, every page must be launchable by a non-technical person, and every page must support conversion testing without adding weight.
flowchart TD
A["Markdown File<br>YAML frontmatter + content"] --> B["Astro Build<br>Zod schema validation"]
B --> C["Static HTML + CSS<br>Zero JavaScript by default"]
C --> D["Cloudflare Pages<br>Edge deployment, Brazilian PoPs"]
D --> E["~300-500KB page<br>Sub-100ms TTFB"]
E --> F["Lead form submission<br>Edge webhook proxy"]
Markdown as the Interface Layer
The core product decision was making markdown the authoring interface — not because it is technically elegant, but because it mirrors the workflow the team already had. With Unbounce, launching a page meant: copy an existing page, change the text and images, configure tracking, publish. With the new platform, the flow is identical: copy a .md file, edit the YAML frontmatter, upload images to Cloudflare R2, push to GitHub. Cloudflare auto-deploys.
Each markdown file generates a complete landing page at /<filename>. All content lives in YAML frontmatter — hero section, modular content sections, form fields, disclaimer text, tracking pixels. The content schema is validated at build time with Zod via Astro Content Collections, which means a malformed page fails the build rather than deploying broken. The team composes pages from reusable blocks — feature highlights, image galleries, financing conditions, CTAs — by selecting and ordering section types in the frontmatter. It is a component system without a component editor.
The harder problem was adoption. Markdown looks like code to non-technical people, and the brokerage’s marketing coordinators had spent years in drag-and-drop editors. The key insight was that the YAML frontmatter fields mapped directly to what they were already filling in on Unbounce: title, hero image URL, CTA button text, disclaimer copy. Same fields, different format. I walked the first two coordinators through their initial pages side by side — old Unbounce page in one tab, new .md file in another — and showed them field by field that nothing was conceptually new. The real resistance was not about the tool; it was about trusting that a git push actually deploys a live page. That trust came from doing it together three times and watching the page appear within seconds. By the fourth page, they were working independently. I published full documentation to the brokerage’s internal documentation portal, trained the marketing coordinators, and provided a walkthrough to the external marketing agency so they could manage campaigns without my involvement.
Edge Deployment: Performance as a Default
Every byte is a cost their users pay from a limited data budget. The architecture eliminates latency sources rather than optimizing around them — static HTML served from Cloudflare’s edge means zero origin server calls. For a buyer in Rio clicking a Google ad, the page is served from Cloudflare’s Brazilian PoP. Sub-100ms TTFB, no cold starts, no database queries.
Unbounce only supports JPG and PNG — no AVIF, no WebP, no responsive srcset. The platform uses Cloudflare Image Resizing to serve AVIF/WebP with multiple srcset breakpoints tailored to actual viewport widths, so a user on a 360px-wide Android gets a 360px AVIF instead of a 1200px PNG. The lead form uses a native <dialog> element instead of a JavaScript modal framework. Form submissions route through an edge-based webhook proxy that keeps tracking URLs server-side. Tracking pixels (Google Ads, Meta, TikTok, Taboola) are the only JavaScript on the page, and conversion events fire only after the user submits the lead form — not on every page view like on the Unbounce setup, where 3.3MB of tracking scripts loaded upfront regardless of whether the visitor converted.
Moving tracking to build-time frontmatter created a stakeholder challenge. The brokerage’s external ad agencies — running Meta, Google, and TikTok campaigns — were accustomed to logging into Unbounce to drop pixels and tweak conversion events directly. Declaring pixels in a YAML file meant giving up that access. The negotiation was straightforward once I reframed what they gained: a spreadsheet mapping every pixel from their old setup to the new frontmatter fields, proof that every event still fired identically, and the fact that UTM parameters were now auto-captured in page metadata — cleaner attribution data than they had before. They lost a login; they gained data hygiene.
Built-In A/B Testing at Zero Marginal Cost
Unbounce charges extra for A/B testing. Dedicated tools like VWO or Optimizely add 100-200KB of scripts on every page view — precisely the overhead I was eliminating. A/B testing scripts are a tax on every visitor to benefit the marketer.
The platform’s approach inverts this. Content authors define variants directly in the markdown frontmatter — tagging sections, headlines, or CTAs with variant identifiers (variant_a: "Receber Tabela e Valores", variant_b: "Baixe a Tabela Agora Mesmo"). During the Astro build, the system renders all variants into the static HTML with CSS-based visibility toggling. A lightweight allocation script (under 2KB) assigns visitors to variants on first load and persists the assignment. Matomo — self-hosted and minimal — fires variant-specific events with proper versioning for statistical analysis.
The result is multivariate testing — A/B/C/D across any combination of sections — with zero additional page weight beyond the variant content itself. No third-party scripts, no SaaS subscription, no network requests before the page renders. For a market where every kilobyte matters, the best A/B test is one the user never has to download.
What I Chose Not to Build
- A visual editor. The team’s mental model was “copy a page, change the text.” A visual editor would have replaced a working mental model with a new one for zero user benefit.
- Dynamic personalization. Geo-based or behavioral content swapping would have required client-side JavaScript that contradicted the zero-JS principle. Deferred unless the team could validate the value exceeded the weight cost.
- A CMS backend. Markdown files in a Git repository are the CMS. Adding a database layer would have introduced infrastructure the team does not need to maintain.
- Unbounce’s Smart Traffic. Their AI-driven traffic allocation requires their JavaScript runtime and locks you into their testing ecosystem. The platform’s build-time variant system gave full control without the 100-200KB script tax.
Results
Performance
| Metric | SaaS Builder (Unbounce) | Landing Page Platform | Improvement |
|---|---|---|---|
| Total page weight | 3-5MB | ~300-500KB | ~70-90% lighter |
| TTFB | 200-400ms (origin) | Sub-100ms (edge) | ~70% faster |
| JavaScript payload | 500KB-1MB+ | ~0KB (pre-conversion) | ~100% reduction |
| Image optimization | JPG/PNG only, no srcset | AVIF/WebP, multi-resolution srcset | 80-90% lighter |
| A/B testing overhead | 100-200KB scripts | ~2KB inline | ~99% lighter |
| PageSpeed Insights | Variable | 95+ across all pages | Consistent top scores |
Unbounce figures from production landing pages running the same campaign template (6.5MB total transfer confirmed via HAR capture). Platform figures measured from live deployed pages on Cloudflare Pages with Image Resizing enabled.
Cost
| Item | Unbounce | Platform |
|---|---|---|
| Monthly platform cost | $1,049 (at 150K views) | $0-20 (Cloudflare Pages) |
| Annual cost | ~$12,600 | ~$0-240 |
| A/B testing | Additional subscription | Built-in, $0 |
| Per-page marginal cost | Included in view-based pricing | $0 |
The platform paid for itself in month one. But the real value was not the savings — it was where that money went and what the performance gains did to campaign economics.
In paid traffic, you pay for every click regardless of whether the user converts. When an Unbounce page takes multiple seconds to load on a prepaid 4G connection, the user clicks the ad, the company pays for the click, and the user bounces before the form even renders. That is pure waste. By dropping page weight 70-90% and hitting sub-100ms TTFB, the platform reduced that waste directly. Scroll-to-bottom rates increased 43% — users were actually reaching the lead form instead of bouncing mid-load. Conversion rates rose over 45% across active launches, which drove cost per lead down over 20%. The brokerage redirected the $12,600 in former Unbounce costs into ad spend, compounding the effect: lighter pages converting more of the traffic, backed by more budget driving more traffic.
Conversion lift measured across the first four campaign launches on the new platform versus the trailing four on Unbounce — same ad spend ranges, same audience targeting. The 45% figure held across all four, but I’d want a larger sample before calling it definitive.
That compounding — better pages and more budget behind them — is what convinced the brokerage to apply the same Astro + Cloudflare architecture to a much larger project: the full brokerage website migration, where I rebuilt 2,000+ listing pages for the same mobile-first audience.
Time to Market
| Phase | Before (Unbounce) | After (Platform) |
|---|---|---|
| Page creation | Copy template, adjust in editor | Copy .md file, edit frontmatter |
| Image upload | Through Unbounce UI | Direct to Cloudflare R2 |
| Tracking setup | Manual pixel configuration | Declared in frontmatter |
| QA and review | Manual cross-device testing | Build-time schema validation |
| Deployment | Publish through Unbounce | Git push, auto-deploy |
| Total | ~4 days | ~6 hours |
In lancamentos, the first 48-72 hours after announcement generate a disproportionate share of total leads — buyer intent peaks at launch weekend and decays fast. Missing that window because the page was not ready meant losing the highest-intent traffic the campaign would ever see.
The 4-day Unbounce timeline was never about the editor — the template took minutes to duplicate. The time went to everything around it: manual resizing of 20-30 property photos, configuring four ad platform pixels, connecting the CRM webhook, cross-device QA on heavy pages, and copy approval cycles between three teams. With the platform, a marketing coordinator copies a markdown file, updates eight frontmatter fields, uploads images to Cloudflare R2 (which handles optimization automatically), and pushes. Tracking pixels, form configuration, legal disclaimers — all declared in the same file. Build-time schema validation replaces manual QA. One person, one file, one push.
Lessons and Reflections
Market data is an architecture input, not a slide deck decoration. The bandwidth research — data exhaustion rates, prepaid pricing, device capabilities — directly shaped technical decisions: zero JavaScript by default, sub-500KB target weight, edge deployment to Brazilian PoPs. On this project, the research was the architecture brief. The transferable principle: when your users face infrastructure constraints, those constraints belong in the technical requirements document, not just the business case.
SaaS platforms have a weight floor you cannot optimize past. Unbounce, Leadpages, and every drag-and-drop builder produce heavy pages not because they are poorly built, but because their business model requires platform-level JavaScript for analytics, testing, and feature gating. You cannot configure your way to a sub-500KB page on a platform whose own overhead exceeds that. When your users need pages lighter than what commercial tools can produce, custom development is not over-engineering — it is the only viable path.
Challenge the category’s default architecture. A/B testing tools assume runtime allocation. I moved it to build time and got full multivariate testing at negligible cost. Schema validation tools assume a QA phase. I moved it to the build pipeline and eliminated multi-day QA cycles entirely. The broader lesson: before adopting a tool category’s standard approach, ask whether the architecture itself conflicts with your product constraints. Sometimes the category convention is the problem.
By the time I handed the platform off, it was serving live campaign pages for active real estate launches. By handoff, the platform had shipped dynamic form configuration and full Matomo integration with variant-aware event tracking. The roadmap I left focused on expanding the section library based on A/B test conversion data. The foundation handled all of this without architectural changes — which was the point. Build the lightest possible thing, then let the data tell you what weight is worth adding.
[1] IBGE 2024, "Uso de Internet, televisao e celular no Brasil" -- 88.9% mobile phone ownership nationally. [agenciadenoticias.ibge.gov.br](https://agenciadenoticias.ibge.gov.br) ↩
[2] NIC.br / Cetic.br, "TIC Domicilios" -- smartphones as primary internet device since 2015, 80-85% for lower-income groups. [nic.br](https://nic.br) ↩
[3] TI Inside, 2025 -- 35% of Brazilians earning up to one minimum wage spent 7+ days without mobile internet in the past 30 days due to data exhaustion. [tiinside.com.br](https://tiinside.com.br) ↩
[4] Global Digital Inclusion -- Claro prepaid 300MB plan costs ~75% more per GB than the 2GB plan, penalizing low-income users. [globaldigitalinclusion.org](https://globaldigitalinclusion.org) ↩
[5] Ookla Speedtest Intelligence -- wealthier Brazilian neighborhoods show systematically higher connection speeds. [ookla.com](https://ookla.com) ↩
[6] GSMA, "State of Mobile Internet Connectivity" -- internet-enabled handset costs 6% of monthly GDP per capita in Brazil. [gsma.com](https://gsma.com) ↩
