Villa Website Platform
3.2% direct booking conversion — bypassing $93K/year in OTA commission fees
$93K
OTA commissions bypassed/year
3.2%
Direct booking conversion
35K+
Monthly organic visitors
Business Context
Luxury villa operators in Bali pay 15–18% OTA commission on every booking routed through Airbnb or Booking.com. For a portfolio generating significant nightly revenue, that's roughly $93,000/year in fees — money that could stay with the operator if guests booked direct.
The business needed a multi-property direct booking platform that matched OTA-quality discovery UX while delivering faster checkout, better SEO, and real-time availability synced from the central PMS.
The Challenge
The previous WordPress-based site achieved only 0.8% direct conversion. Pain points:
- 4.2s LCP on image-heavy villa pages — mobile guests bounced before seeing availability
- Availability checks hit a slow PHP backend — 800ms+ API responses made the booking widget feel broken
- No SSG — every page request rebuilt dynamically, hurting SEO crawl efficiency
- OTA dependency — no compelling reason for guests to book direct beyond a small discount
Growing direct bookings required a platform that felt faster and more trustworthy than clicking through to an OTA listing.
Architecture Decision
Chosen: Next.js 14 (App Router) with SSG/ISR for villa pages, Go (Fiber) backend for booking API, PostgreSQL for reservations, deployed on Vercel + containerized Go service.
Rejected: Full Next.js API routes for booking logic — rejected because the booking engine needed sub-100ms responses under concurrent availability checks during peak season, and Go's concurrency model outperformed Node for this specific hot path.
Why SSG + ISR: 80+ villa pages pre-render at build time with nightly revalidation. Property content (photos, descriptions, amenities) changes infrequently — serving static HTML from the edge cut LCP from 4.2s to 1.1s.
Why Go for booking API: Availability queries involve date-range scans across multiple units with lock checks against the PMS. Go/Fiber handles concurrent requests with minimal memory overhead — p99 response times dropped from 800ms to under 120ms.
Key Results
| Metric | Before | After |
|---|---|---|
| Direct booking conversion | 0.8% | 3.2% |
| OTA commission costs | ~$93K/year (15–18% per booking) | Reduced via direct channel growth |
| Page load (LCP) | 4.2s (WordPress) | 1.1s (SSG + CDN) |
| Booking API response time | 800ms+ (PHP monolith) | Under 120ms (Go/Fiber) |
Lessons
- Direct booking growth is a performance problem before it's a marketing problem — guests abandon slow villa pages regardless of photography quality.
- SSG for property pages + dynamic API for availability is the right split; pre-rendering 80+ villa pages nightly beats on-demand rendering at this catalog size.
Next Project
VIPApp →96% faster compliance reporting — 2 days/month → 2 hours/month