DEV Community

Daniel Mercer
Daniel Mercer

Posted on

Shipping a 56,000-game portal as a one-person operation: the stack that holds it together

Running a site with fifty-six thousand games sounds like a team sport. In our case it's mostly one person, a cheap server, and a stack chosen for boring reliability over cleverness. Here's what actually holds GameZiko together, and the unglamorous decisions that matter most.

Static-first, dynamic where it counts. The game pages are overwhelmingly static HTML generated at build time. Fifty-six thousand dynamic page renders per deploy would melt anything, so the catalog is pre-rendered: title, description, tags, embed, related games — all baked in. The dynamic parts (search, "recently played") are small API calls against a lean index. The rule: if it doesn't change per user, it shouldn't be computed per request.

The game files are the easy part. HTML5 games are self-contained bundles. The hard part is metadata quality — a game with a wrong title, a broken thumbnail, or a miscategorized tag is a dead page. We built a pipeline that validates each submission: does it load in a sandbox, does it actually respond to input, is the thumbnail the right aspect ratio. About a third of submissions fail validation and never ship. That filter is the product, honestly.

Search is a solved problem if you stay humble. We don't run Elasticsearch. A precomputed trigram index plus tag weighting handles "car games" and "2 player" fine at our scale. The moment you accept that your search doesn't need to be Google, the infrastructure gets ten times cheaper.

Images are the silent budget killer. Fifty-six thousand thumbnails will eat any hosting budget if you're careless. Ours are aggressively compressed WebP at fixed dimensions, served from a CDN with long cache headers. The page weight budget per game page is under 300KB excluding the game itself. On a site where most visitors are on phones or school Chromebooks, that discipline is the difference between playable and abandoned.

Caching everything, invalidating almost nothing. Game pages change rarely, so cache TTLs are measured in days, not minutes. The only thing that busts cache is a metadata correction, and those go through a targeted purge. Stale-while-revalidate does the rest. Our origin server mostly serves the API and the build pipeline; the CDN does the real work.

Monitoring that a solo dev will actually read. We don't have dashboards — we have three alerts: error rate spike, deploy failure, and disk space. Everything else is a weekly report email. A monitoring setup you'll ignore is worse than a simple one you'll read.

What I'd do differently. I'd have built the validation pipeline first instead of bolting it on after the catalog passed ten thousand games. Cleaning ten thousand bad entries retroactively was the most miserable month of the project. If you're building any kind of user-submitted catalog: validate at ingest, or pay for it later with interest.

The unsexy summary: pre-render everything, validate at the door, compress images like your budget depends on it (it does), and keep the dynamic surface tiny. GameZiko stays fast on a shoestring because the architecture refuses to do work it doesn't have to.

Top comments (0)