
The Joke Domain That Outlived Gatsby
Five years ago I bought a domain about a coworker's Dr Pepper habit. Here is what building it in Gatsby, then rebuilding it on Next.js 16, taught me about side projects that outlive their framework.
Building the web since 2000
Practical writing on PHP, MySQL, Linux, WordPress, security and the weird corners of the web, by one engineer who's been shipping them for over two decades.

Five years ago I bought a domain about a coworker's Dr Pepper habit. Here is what building it in Gatsby, then rebuilding it on Next.js 16, taught me about side projects that outlive their framework.

CVE-2026-23111 is a one-character nf_tables use-after-free that escalates any unprivileged Linux user to root through user namespaces, and a public exploit is now out. Here is how I detect it, the user-namespace mitigation that matters most, the kernel patch, and a safe VM lab to reproduce it.

The Agentic Browsing audit is now live in Google PageSpeed Insights, no Chrome Canary needed. Paste your URL, read the fractional score, and pass every check that says whether AI agents can read and act on your site.

Most database attacks want money. The Meow attack just wipes your data, renames what is left with a -meow suffix, and walks away with no ransom note and no explanation. Here is how the bot works, why it exists, and how to avoid being harvested.

CVE-2026-31431 (Copy Fail) is a Linux kernel local privilege escalation that turns any unprivileged shell into root on essentially every distribution shipped since 2017. Here is how I check it, patch it, mitigate it pre-patch, and understand how the exploit actually works.

In May 2026 an automated bot wiped a terabyte of Elasticsearch data on a personal project of mine, through a port I left open. Here is exactly how the ransomware works, why it found me, and the boring one-time fixes that stop it.

Four reliable ways to change a WordPress password: admin dashboard, WP-CLI, directly in the database with the correct phpass or bcrypt hash, and the lost-password email reset.

Hosting is one of the most leveraged decisions an agency makes for margin. The honest math: hosting markup as recurring revenue, operational time as hidden cost, the per-client profit comparison across the four hosting tiers.
Hosting choices for WordPress agency clients are operational decisions, not pricing decisions. The decision tree by traffic tier and workload type: shared, managed WordPress, managed VPS, self-managed VPS. Plus the agency-side implications of each.
Self-hosting WordPress as an agency is one of the most consequential operational decisions you can make. The four conditions under which self-hosting is the right call, the four under which it is a mistake, and the honest math on the long-term cost.
Managed WordPress hosting buys you operational simplicity at a per-site price premium. VPS buys you flexibility and lower per-resource cost at the price of in-house sysadmin time. The honest comparison and the agency-side break-even math.

Practitioner reference for Elasticsearch 9.x: index and document operations, Query DSL, aggregations, vector / kNN search, ESQL, cluster management, version compatibility notes, and the gotchas that bite first-time operators.
MySQL cheat sheet covering CLI commands, database and table operations, joins, indexes, backups, user management, and transactions, with version notes for 5.7, 8.0, and 8.4.
MySQL 8.4 is the new LTS branch, with Premier Support through April 2029 and Extended Support through April 2032. The 8.0 to 8.4 upgrade is much smaller than 5.7 to 8.0, but removed options and the new authentication_policy variable still bite. Full procedure with rollback.
MySQL 5.7 has been past its EOL since October 2023. Here is the migration to 8.0: prerequisites, dry-run with mysqlcheck, in-place upgrade, the authentication-plugin change that breaks old clients, and rollback if it goes sideways.

macOS ships BSD find; Linux ships GNU find. The two share a name and most of an interface, but -printf, -regextype, and the stat format strings diverge hard enough to break scripts shipped between platforms. The full divergence list, the portable subset that works on both, and how to get GNU find on a Mac.
The grep -o 'pattern' file | sort | uniq -c | sort -rn pipeline is the classic log-analysis one-liner. Why sort must come before uniq, how each stage works, worked examples for top IPs and status codes, the awk one-pass alternative for huge files, and the BSD vs GNU notes.
find walks the live filesystem every time it runs: always current, sometimes slow. locate queries a prebuilt database: instant, but stale until the next updatedb. This breaks down the locate family (mlocate, plocate, slocate), the macOS situation, and exactly when to reach for each one.
grep filters lines, awk extracts fields. The classic pipe is grep 'pattern' file | awk '{print $2}'. This covers awk field basics ($1, $NF), custom separators with -F, multi-column output, the cases grep -o and cut cover on their own, and the fact that awk's own pattern match makes the grep half optional.

rsync has no native time filter, so the standard trick is to let find pick the files and feed the list to rsync. The one-liner is find ... -print0 | rsync --files-from=- --from0, and the failure mode is always the same: the paths in the list have to be relative to the rsync source argument. The breakdown, the dry run habit, and when rsync's own filters make find unnecessary.
find locates the files, tar archives them. The safe pairing is find -print0 piped into tar reading a NUL-delimited list from stdin: no breakage on spaces or newlines. The flag breakdown, the macOS BSD tar vs GNU tar difference, the -exec append alternative, archiving by modification time, and the compression choices.
grep is on every system and searches exactly what you point it at. ripgrep (rg) is the fast Rust-based default for code search: it skips .gitignore'd, hidden, and binary files unless told otherwise. ag (the_silver_searcher) was the older fast-grep, now largely superseded by ripgrep. This breaks down speed, defaults, regex engines, and exactly when to reach for each one.
find . -type f -name '*.log' -print0 | xargs -0 -P 4 -n 1 gzip compresses every matched file four at a time. The flags that make it work: -P for parallel workers, -n 1 so each worker gets one job, -0 paired with find's -print0 for safety. When parallelism helps (CPU-bound work) and when it just thrashes the disk.

Every reliable way to update Node.js on Linux, macOS, and Windows. Covers nvm, fnm, Volta, n, the nodejs.org installer, apt/brew/winget, Docker, GitHub Actions, per-project pinning, and the rebuild-native-modules step everyone forgets.
globalThis.crypto (the Web Crypto API) is a global in Node 19+ with no shim or flag: crypto.randomUUID(), getRandomValues(), and crypto.subtle. How it differs from the node:crypto module, and when you still need a shim.
Add a timeout to fetch() the modern way: pass AbortSignal.timeout(5000) as the signal. Plus AbortController for manual cancel, combining signals with AbortSignal.any, and catching AbortError. Works in the browser and in Node.
The array methods worth reaching for in modern JavaScript: at() for negative indexing, flat(Infinity), the copying toReversed/toSorted/toSpliced/with that fix the mutation trap, and the corrected grouping API (Object.groupBy, not the Array.prototype.group that never shipped).

CSS :has() is the parent selector we waited 20 years for: style an element based on what it contains. Now Baseline in every engine. Form rows, quantity queries, the previous-sibling trick, and the @supports gate for old browsers.
Style form validation with pure CSS. :user-valid and :user-invalid only react after the user interacts, so empty required fields stop showing red on page load. Plus :required, :optional, :in-range, :placeholder-shown, :autofill, and :has().
The accessible way to handle focus rings: :focus-visible shows the outline only when someone navigates by keyboard, so you can stop blanket-removing outlines and breaking keyboard users. Native, Baseline, and the old :focus-ring polyfill is dead.
Tint native checkboxes, radio buttons, range sliders, and progress bars to your brand color with one line of CSS. accent-color, the controls it affects, the auto-contrast checkmark, and the graceful fallback for old browsers.

The API security tools I actually reach for in 2026: Burp Suite, mitmproxy, OWASP ZAP, kiterunner, Postman, jwt_tool, graphql-cop, and the commercial platforms. Strengths, weaknesses, and how I decide which to use.
The file upload vulnerability tools I actually reach for in 2026: fuxploider, Burp Upload Scanner, weevely, exiftool, ffuf, and the webshell repos. Strengths, weaknesses, and how I decide which to use.
The application-layer DoS testing tools I actually use in 2026 for resilience and load testing: k6, wrk2, slowhttptest, recheck, h2spec/h2load, Burp Turbo Intruder, Locust, and ZAP. Strengths, weaknesses, and how I pick.
The clickjacking tools I actually reach for in 2026: PoC generators, OWASP ZAP, DNSChkr HTTP Security Headers, Mozilla Observatory, Burp Active Scanner, and the post-Yibelo double-clickjacking PoC repos. Honest framing on a thin tool space.

NVIDIA GTX 1070 Ti Ethereum Mining review: Hashrate, overclocking settings, and power efficiency analyzed for miners.

Read your own GA4 metrics server-side from WordPress: a Google Cloud service account, the google/analytics-data PHP client, a te_ga4_run_report() wrapper around runReport, plus caching and credential hygiene.
How to build a dynamic Gutenberg block: render the front-end markup in PHP at request time with render_callback (or the block.json render property), return null from save, and preview it in the editor with ServerSideRender.
Keep API keys, database credentials, and SMTP secrets out of wp-config.php and out of git by loading them from a .env file with vlucas/phpdotenv, fed into define() where WordPress expects constants.
Editing a taxonomy term does not refresh the posts that cache term-derived data. Hook saved_term, re-save the attached posts, and bust the stale output, carefully and at scale.

The five online regex testers I actually use, ranked: Regex101, RegExr, RegexPlanet, Debuggex, and Rubular. What each is good at, where each falls short, and which flavor each one supports.
Regex word boundaries (\b and \B) match positions between word and non-word characters with zero width. The full reference with engine differences, Unicode handling, lookaround alternatives, and worked examples for whole-word replace, search highlighting, and log parsing.
Regex anchors are unique tokens that assert positions within a string without matching characters. Discover their role in pattern matching across languages.
Regex Cheat Sheet including regex symbols, ranges, grouping, assertions, syntax tables, examples, matches, and compatibility tables. Definitive Regular Expressions Quick Reference!

Forty-five AI meeting summary jokes about the action items nobody owns, the decisions the meeting did not actually make, the attendee list it got wrong, and the Slack thread asking what we just decided.
Fifty-five AI replacing jobs jokes about the McKinsey deck, the LinkedIn thinkpiece, the engineer who is also now the support team, and the layoff announcement that mentioned AI seventeen times.
Sixty-five AI generated code jokes about Copilot, Cursor, the function that imports a library that does not exist, the perfectly formatted bug, and the deployment script that ran on a Friday.
Fifty AI CEO jokes about the all-hands AGI announcement, the Q3 pivot, the strategic vision deck, and the chief executive who saw one demo and now wants to disrupt the industry by Friday.

My experience meeting WordPress co-founder Matt Mullenweg at WordCamp Europe 2024 in Torino, Italy. A journey filled with inspiration, connections, and memorable moments.
I aced the coding test and walked into the interview with the job nearly in hand. One vague question at the end sank it. The lesson: if you don't understand what they're really asking, ask for context.

The five Claude Code tools that change frontend design work: impeccable skill, Figma MCP, claude-in-chrome MCP for visual QA, banana skill for AI image generation, and shadcn/ui MCP.
The five Claude Code tools that change how SEO and content teams work: seo-content skill, seo-technical skill, Firecrawl MCP, Exa MCP, and the filesystem MCP for direct CMS access.
The agency-ops playbook for AI: proposals, SOWs, onboarding documents, SOP creation, meeting summaries, status reports, internal documentation. Where the per-hour gain is highest, and the rules that keep client trust intact.
The five Model Context Protocol servers worth installing today: filesystem, GitHub, Postgres, claude-in-chrome (browser), and Sentry. With install commands, the tools they expose, and the security model.

A practical DNS health check covers nameservers, A and AAAA records, MX, SPF, DKIM, DMARC, and CAA. Here is the full checklist, what each record actually tells you, and how to verify all of them in one pass.
The Internet Archive plays by different rules than AI or search bots. Here is how to keep new pages out of the Wayback Machine, how to remove pages that are already archived, and what to do when robots.txt is not enough.
I blocked every AI bot I could when they first started slamming my servers. A few months later I unblocked most of them. This is the decision framework I wish I'd had at the start.
The full reference for blocking AI crawlers: which bots matter, what each one does, robots.txt and server-level rules, Cloudflare's managed approach, WordPress paths, and the bots that ignore robots.txt entirely.

A scannable curl reference: GET, POST, PUT, DELETE; JSON and form bodies; basic, bearer, and digest auth; redirects, retries, timeouts; --resolve overrides, SOCKS proxies; with PowerShell Invoke-WebRequest equivalents.
A scannable SSH reference: ssh-keygen, ssh-copy-id, port forwarding (-L, -R, -D), ProxyJump, ~/.ssh/config blocks, scp and rsync over SSH, with the Windows OpenSSH differences and PuTTY equivalents.
A scannable find reference: search by name, size, time, type, perms; safe pipelines with -print0 and xargs -0; -exec and -execdir; plus the macOS BSD vs GNU find divergences and Windows PowerShell equivalents.
A scannable grep reference with the flags I actually use, the GNU vs BSD differences that bite on macOS, and the Windows equivalents (Select-String, findstr) for the same patterns.