From the field
Notes on Stripe payments, AI agents in production, and full-stack SaaS architecture
-
A reader read my benchmark better than I did
I published a fine-tune that beat prompting by 29 points. A commenter said the gap between my two accuracy drops was the real signal. He was right that my table was misleading, wrong about which arm was inflated, and the experiments I ran to check produced a third answer.
-
The client wanted production data in preprod. I said no, then gave them something better.
A reasonable request from a reasonable client: make preprod look like prod, with real data. Why that would have been the worst security decision in the project, how I pushed back without a fight, and the anonymised seed pipeline that made preprod more useful than a copy would have been.
-
The certificate expired in silence, and the scans never stopped
A renewal cron ran every night for months and never renewed anything, because of one wrong letter. Meanwhile the server took thousands of scans and brute-force attempts a day. Here is what CrowdSec actually blocked, the nginx rules that held, the ports I should never have exposed, and why Cloudflare is the next layer.
-
Users emailed me about 500s before I ever saw them
Every error in production was logged with console.error and then died in a log file nobody read. Customers became my error tracker. Here is how I wired Sentry-compatible tracking into Express and React with sourcemaps, grouping, and one alert rule that actually fires.
-
I was grepping JSON over SSH while production was down
During an incident, my observability stack was an SSH session, docker logs, and grep. Here is the zero-budget setup that replaced it on the same VPS: Uptime Kuma on the healthchecks I already had, Dozzle for live logs, and the alert that now reaches my phone.
-
The Friday push that taught me to ban commits on main
A git push at 6pm on a Friday deployed straight to production, untested, and took the API down. Nothing in the pipeline could have stopped it, because there was no pipeline. Here is the one I built: protected main, CI that runs the tests, images built off the box.
-
My fine-tuned model scored 100%. The benchmark was lying.
I fine-tuned Mistral 7B with LoRA on a MacBook to detect personal data. On my own test set it scored 100% and prompting nearly matched it. On real data the fine-tune won by 29 points. The dataset had been choosing my conclusion.
-
Database backups that actually restore: the pgdata I lost
I deleted a Postgres data directory that lived in a bind mount with nothing behind it. My backup plan was hope. Here is the cheap, single-VPS backup setup I should have had, including the step everyone skips.
-
PII and data masking: how to stop leaking personal data everywhere
Personal data spreads into logs, staging, analytics, and exports, far beyond the users table. A practical guide to masking, pseudonymization, and anonymization, and knowing which one you actually did.
-
GDPR data retention and deletion: a practical guide for developers
The two GDPR duties engineers get wrong most often are keeping data too long and failing to fully delete it. A hands-on guide to retention windows, the right to erasure, and the part nobody plans for: backups.
-
CPU utilization lies: autoscaling a single-threaded service
A service was slow under load, but autoscaling never fired because CPU sat at 30 percent. A single-threaded app on a multi-core task saturates one core and reads as barely busy. Why, and how to fix it.
-
Docker never restarted my database: the price of restart: no
A container died at night and nothing brought it back, because every service was set to restart: no. The healthchecks I did have could not help, and the reason why surprises most people.
-
The tests were already written. Nothing ever ran them.
A regression reached production, and the test that would have caught it was already in the repo. There was no test script, and the only CI workflow never triggered on a push. How I wired it up.
-
Docker bypassed my firewall: the database port was open to the internet
My host firewall blocked port 5432. It was reachable from the internet anyway, because Docker writes its own iptables rules that your INPUT and ufw rules never see. Why it happens, and how to actually close it.
-
The MCP servers that actually earn their keep with Claude Code
Not a directory of 200 MCP servers: the three I still use after a month of real work, how to wire them cleanly, and the ones I removed.
-
The docker build that filled the disk and took down production
Production went down with no code change. The cause was a docker compose build orphaning a new <none> image on every deploy until the disk filled. What actually cleared it, and the deeper fix.
-
Shipping a SaaS on one VPS with Docker Compose: an honest audit
The whole product runs on a single VPS behind one docker-compose.yml. Here is why that was the right call at launch, and an honest map of every single point of failure it hides.
-
Sharing a Claude Code config across a team
Versioned CLAUDE.md, settings.json vs settings.local.json, shared MCP servers, hooks: what gets shared, what stays local, and the traps in between.
- teamprocessagile
A practical playbook for running a remote dev team
One QA, eight people, a multi-tenant codebase, and too many bugs in prod. Here are the five ceremonies a new lead used to fix it, with the exact way we run each one.
- webdevux
The cart timer expired while they were paying. Now what?
A countdown that fires mid-payment is a tiny bug with a huge tell: the engineer optimized for the system and forgot there was a person on the other end. Here is how to handle it, and the product habit it reveals.
-
Multiple accounts in Claude Code: the complete setup
How to run multiple Claude Code accounts on one machine, with shell aliases, config isolation, per-project defaults, and the pitfalls nobody warns you about.
-
Cloudflare under the hood: how it works and how attackers try to get around it
What actually happens when a request hits a Cloudflare-protected site, how Turnstile distinguishes bots from humans, and the techniques attackers use to find the origin server behind the proxy.
-
Stop refunding payments you should never have charged
The charge-then-refund flow is everywhere, and it's almost always wrong. Authorize first, run your checks, then capture. Here's the property that does it.
-
Sharing cookies across subdomains locally
A prod-identical local setup where cookies are shared across subdomains over real HTTPS, with zero app code changes. The trick lives in /etc/hosts + nginx.
-
Architecture matters more than clean code
I spent 2 weeks making my serverless functions clean. The architecture was wrong. I rewrote everything as a single Express server and it was simpler.
-
Debugging is more important than features
My blog returned 404 on every page at 2 AM. I had zero visibility into why. Here is the debugging infrastructure I wish I had set up from day one.
-
Why the perfect code is less maintainable
I spent 3 hours reviewing a 200-line PR handling every edge case. A 40-line version with a TODO beats it. Here's why perfect code slows you down.
-
Stripe alternatives in the EU
Stripe is the default for online payments, but if you need only one method, you're paying for features you'll never use. Here's what I found comparing.
- webdevreact
Social previews in React: UA detection
How to handle Open Graph meta tags for LinkedIn, Google, and Discord previews in a React SPA using server-side user-agent detection with nginx/.htaccess.
-
AI-powered git branch diff summaries
How to generate a smart summary of branch diffs, highlighting deleted files and renames so AI agents have context to review, refactor, or document it.
-
Testing Lambda + EventBridge locally
How to test AWS Lambda functions and EventBridge rules locally using SAM, LocalStack, and docker-compose. No cloud deployment needed.
-
AI infrastructure: a maintenance nightmare
I asked AI to generate Terraform for a standard AWS setup. It produced 2,400 lines that worked perfectly. Here's why I'd never deploy it to production.
-
How to check your AI's actual context window
How to verify the actual context window of an LLM, understand external vs internal context, and avoid the silent truncation problem.
-
Token economy: cutting context waste
How loom-memory turns a Git repository into a persistent knowledge base for AI agents, cutting token spend with durable context instead of cold reads.