Back2OldGames is a large downloadable archive with a community on top: profiles, points, user uploads. And it is run by one person. That last fact drives every technical decision in the project.
back2oldgames.com Live Gamification is easy. Gamification without writing on every visit is not
A points system looks harmless until you look at what it does to the database. Every visit to an entry adds a view; every download, a point; every comment, another. If each of those events is an immediate write, caching stops being possible: the page has to execute in order to count.
The way to have both is to separate reading from counting. The page is served from cache and the count travels separately, in a small request that does not block paint. Events accumulate and are consolidated in batches instead of row by row. A user's score does not have to be accurate to the second; it has to be accurate when they look at it.
Leaderboards are the classic trap
A leaderboard is an ORDER BY over a sum of events. Computed live, it is the most expensive query on the site, and it is requested from the front page, which is the most visited one. That is the perfect combination for falling over on a Saturday afternoon.
So it gets precomputed. The ranking is generated on a schedule and stored already sorted; the front page only reads it. Nobody notices a leaderboard a few minutes behind except the person who just moved up a place, and they see it on reload.
PHP does not serve the downloads
The archive is the reason the site exists, and it is also what eats the bandwidth. Serving a large file through PHP means one PHP process tied up for the whole download: twenty concurrent downloads and there is nobody left to serve pages.
The web server delivers the file, not the application. The application checks permissions, records the event and hands off delivery. Cloudflare sits in front and absorbs the spike when a link gets shared on a forum and a thousand people arrive at once.
If response times get worse while downloads are in progress, the problem is not the database: it is that the application is acting as a file server.
User content: moderation is a design problem
When the community uploads, the admin workload grows on its own. With one person in charge, moderation has to be designed so the normal case needs no intervention:
- Strict validation on upload — the file's real type, not its extension — so what should not get in never gets in and never has to be taken out.
- A review queue with the doubtful cases on top, not a chronological inbox: what has waited longest is not what most needs looking at.
- Bulk actions. Approving forty legitimate uploads at once is the difference between ten minutes and an afternoon.
- Accumulated reputation: somebody with two hundred good uploads does not go through the same queue as somebody who arrived today.
This is not one more feature. It is what decides whether the project is still alive in two years or the admin burns out.
An uploaded file is an attacker's favourite front door
Any site that accepts uploads inherits the same risk: that somebody uploads something executable and gets the server to run it. The defences stack, and none is enough on its own: files are stored outside the public directory, renamed, served from a path that does not interpret code, and the upload directory has execution disabled at the server level.
It is the same standard we apply to the maintenance of any site we run: never trust a single layer, because the one that fails is always the one you assumed was safe.
A living archive gets heavier every year
A community project is not delivered and forgotten: it grows. The measure of the architecture is not how it behaves on launch day, it is whether in three years, with triple the content, the same person can still run it.
Every decision in this project was made by answering the same question: will one person still be able to maintain this in three years?
Ignacio Pineda, Intervolutions