We recently relaunched Sonsaur.com, a free browser gaming portal with over 8,000 games. Here's the tech stack and interesting challenges we solved.
The Stack
- Framework: Next.js 16 with App Router
- Database: Neon PostgreSQL with Prisma 7 ORM
- Hosting: DigitalOcean VPS + Cloudflare CDN
- Image CDN: Custom nginx-based CDN (img.sonsaur.com) serving pre-resized AVIF thumbnails
- Search: PostgreSQL trigram indexes (pg_trgm) for fuzzy game search
- AI Translation: Gemini API with 60-key rotation for rate limit management
- Process Manager: PM2 with auto-restart and memory limits
The Image CDN Challenge
With 8,000+ games, each needing thumbnails, image optimization was critical. We built a custom image pipeline:
- Original images stored as AVIF at 512px
- Pre-resized to 128px (~6KB) and 256px (~13KB) variants
- Served via dedicated nginx subdomain (img.sonsaur.com)
- Zero-JavaScript image components (plain `` tags for zero hydration cost)
Result: 84% reduction in image payload for game cards.
Translating 8,000 Games into 38 Languages
This was the most interesting challenge. We needed to translate not just the UI (which is straightforward with next-intl) but also game-specific content: descriptions, how-to-play guides, tips, and FAQs.
Our approach:
- 60 Gemini API keys distributed across multiple projects
- Cron job running every 2 minutes, processing 60 games per batch (1 per key)
- Sequential processing to prevent Node.js streaming crashes
- 2-minute key cooldown with 10-minute pause when all keys are exhausted
- Tier 1 rate limits: 1,500 requests per day per key per project
At full capacity, we translate ~43,200 game pages per day across all languages.
Performance Results
- Lighthouse: Performance 79, Accessibility 93, Best Practices 100, SEO 100
- First game load: under 3 seconds
- Subsequent navigations: near-instant (Next.js prefetching)
- Image CDN: 128px thumbnails average 6KB (vs 34KB originals)
What's Next
We're working on native Android and iOS apps, completing full translation coverage for all 38 languages, and continuously adding new games to the library.
Check it out: sonsaur.com
Happy to answer questions about any part of the stack. The combination of Next.js + Neon PostgreSQL + custom image CDN has been great for this use case.
Top comments (0)