Devlog
Building In The Open.
Notes from a solo founder building Players Engine: engineering decisions, closed-beta lessons, and the problems in gaming communities we're trying to fix. Honest, occasionally messy, written as it happens. July 2026 brings a twelve-entry batch of engineering notes — the infrastructure lessons of the past months, from cold starts to keyless deploys, written down while they still sting.
Refresh on read instead of a cron job
A nightly sync bills you for every linked account, while its value only comes from the profiles people actually open. Why game stats refresh on view with stale-while-revalidate, why freshness depends on who is looking, and the guards that keep paid APIs in budget.
Read entry →Consent mode before the first ad
The site doesn't serve a single ad, and it already has a default-deny consent layer. Why privacy claims rot faster than code, why the consent decision must live in exactly one place, and how to build the seam for the certified CMP that will replace the banner.
Read entry →E2E tests against a live staging environment
Every service had green unit tests and the bugs lived in the seams between them. Why end-to-end sweeps against one shared, imperfect staging environment — through the gateway, asserting on side-effects — became the cheapest safety net in the monorepo.
Read entry →Serving user images without burning money
User media is the first feature that turns into an infrastructure bill. Immutable headers, filenames instead of URLs in the database, write-time derivatives and a cache hit ratio watched like an error rate — because the cheapest byte is the one your origin never serves.
Read entry →GDPR deletion is a distributed systems problem
Deleting an account reads like a checkbox and turns out to be a distributed workflow: a 30-day grace period, a rehydrating restore path, tombstoned graph nodes, an idempotent purge across four storage systems — and a sweep for the ones that get stuck.
Read entry →An OpenAPI gateway you never edit by hand
The spec that configures every route on the platform is build output, not a file anyone edits — per-route fragments, a generator that enforces the invariants, and the four missing lines of JSON that taught me why.
Read entry →Eight languages, one developer
Eight locale catalogs maintained by one person: the lockstep rule that keeps them honest, the parity tests that catch drift — and the staged languages CI cannot see at all.
Read entry →Rate limiting APIs that charge per call
Protecting a bill instead of a server: validation, idempotency, brute-force locks and caches ordered by cost — because autoscaling defends your uptime, not your budget.
Read entry →Dead-letter queues are a solo dev's safety net
The unglamorous machinery that makes event-driven side-effects survivable for one person: retries, idempotent handlers, a DLQ on every subscription — and why an unmonitored one is just slower data loss.
Read entry →The day our graph database went to sleep
A staging outage postmortem: a managed database auto-paused by design, a DNS error that pointed everywhere but the cause, and the doorknob-simple runbook that came out of it.
Read entry →The real cost of a social feed
Modelling Firestore read costs before having users: fan-out trade-offs, indexed reads with boring cost curves, and the one-page cost model every feature now has to survive.
Read entry →Testing responsive layouts, 360 to 1920
Responsive is a claim until you count it: the viewport-sweep method that audited every route from 360px to 1920px, and why fixes belong to the component layer, not the page.
Read entry →Keyless deploys with Workload Identity
Retiring the immortal JSON key: short-lived federated CI credentials, per-repo trust — and the cleanup policy that deleted an image production was still running.
Read entry →Structured logging on a budget
Logs are a product with a bill. JSON events with request context, levels used as cost dials, redaction by default, and what actually gets queried during an incident.
Read entry →One schema, three jobs
TypeScript evaporates at runtime. How one schema definition produces static types, request validation and API documentation — so the three can never drift apart.
Read entry →Pub/Sub side-effects and the discipline of idempotency
At-least-once delivery means at-least-twice: idempotency keys, re-fetching truth on retry, and the outage caused by a topic nobody was subscribed to.
Read entry →Documents and graphs: why we run two databases
A document store for "give me this thing fast", a graph for "how are these connected" — plus the float-versus-integer driver bug that broke pagination at night.
Read entry →JWT at the edge
Verify authentication once at the gateway, forward verified identity, and let services do authorization only. Two traps included, one of them autobiographical.
Read entry →One repo, many deployables
A workspace of repositories: superproject plus submodules plus pnpm workspaces, one pragmatic npm exception, and docs that update in the same diff as the code.
Read entry →Environment variables and secrets without foot-guns
Configuration is dogma territory: validate everything at startup, one config module per service, and secrets that are never allowed a default value.
Read entry →Connection pooling when every service is tiny
Pooling advice assumes big servers. What changes when instances are tiny and mortal: driver singletons, cached tokens, and surviving the wake-up stampede.
Read entry →Scale-to-zero is a budget strategy
Scale-to-zero isn't an aesthetic, it's the finance department: what idle really costs, what zero costs instead, and the written criteria for paying for warmth.
Read entry →Cold starts, warm wallets: tuning Cloud Run startup
The first request after quiet pays the wake-up tax. Boot-order discipline, lazy clients and honest p95s keep it small — without paying for idle.
Read entry →What the closed beta is teaching me
A small group that trusts you to listen beats a big number that stays silent — and other lessons from the first weeks of real users.
Read entry →Fake accounts are ruining gaming communities
Bots, engagement farming, smurfing: why trust is the scarcest resource in online gaming spaces, and why it keeps losing.
Read entry →Running a closed beta with Discord, Sentry and GitHub
The feedback pipeline: forum channels, crash alerts, issue triage, and the weekly rhythm that keeps one person on top of all of it.
Read entry →Building solo with an AI pair programmer
What AI coding assistants are genuinely good at, where they fail, and how a one-person team reviews code it didn't type.
Read entry →The stack: one founder, ten microservices
Why a bootstrapped solo project runs on Cloud Run, a document database and a graph database — and what scale-to-zero really buys you.
Read entry →Why I'm building PlayersEngine
Starting this devlog with the story so far: a gamer's identity is scattered across a dozen launchers, and nobody built it a home.
Read entry →