How to Build a Serverless, Zero-Database Web App for 100k+ Users Using Client-Side Image Processing
As software engineers, our default setting is often to over-engineer. When tasked with building a web utility—such as an image sorter or a layout planner—our minds immediately jump to designing a complete backend ecosystem. We start sketching out PostgreSQL schemas, configuring AWS S3 bucket lifecycles for user uploads, setting up Redis caches, and writing authentication middleware. While this architecture is robust, it introduces massive overhead: Financial Cost: Database queries and S3 egress fees scale with your user base. Maintenance Burden: Keeping server packages updated, managing API endpoints, and handling database backups. Legal Compliance: Storing user-uploaded files means dealing with GDPR, CCPA, and data privacy regulations. When I started building Rankly, an online Tier List Maker, I challenged myself to eliminate the backend entirely. I wanted to build a high-performance web tool capable of scale, with a server hosting bill of exactly $0/month, while giving users complete privacy. Here is a technical deep dive into how we built a stateless, zero-database frontend architecture that processes complex image grids entirely client-side. Traditional tier list tools follow a client-server-client round-trip pattern: User uploads images -> Sent to server. Server saves to S3 -> Returns public URLs. User drags/drops -> State saved to database via JSON payload. Export -> Server-side headless browser (like Puppeteer) renders the page and takes a screenshot -> Sent back to user. This pattern is slow and highly resource-intensive. Rankly completely bypasses the server by implementing an entirely local-first rendering pipeline. [Local File Upload/Drag] │ ▼ (FileReader API / Object URL) [Local Memory State (React/State)] ───► [Interactive Grid UI (Tailwind)] │ ▼ (HTML5 Canvas Synthesis) [Local Client-Side Render] ───► [High-Res PNG Download] To let users use their own images without uploading them to a remote server, we utilize the HTML5 File API. When a user drags and