Josh Davies

Senior Software Engineer

I build beautiful, engaging, and perfectly executed frontend and backend experiences. While finding time to write, hike and read.

Blog

  • NOV 2026

    Promise.all Is Not a Plan

    Firing every request at once works great with twenty items in dev. With five thousand in production, you are load testing someone else's API. Put a number on your concurrency, in TypeScript and in PHP.

    • typescript
    • node
    • php
    • laravel
    • integrations
    • queues
  • NOV 2026

    Your Worker Remembers the Last Job

    Queue workers, Octane, and Node servers boot once and keep running. Anything you leave in a static, a singleton, or module scope is still there for the next job or request. Sometimes for the next user.

    • laravel
    • php
    • typescript
    • node
    • queues
  • NOV 2026

    Let It Finish Before You Kill It

    Every deploy, scale-down, and restart starts with a signal asking your process to stop. If your app ignores it, the platform kills it mid-request or mid-job. Handle SIGTERM on purpose.

    • devops
    • laravel
    • php
    • typescript
    • node
  • NOV 2026

    Don't Let the Request Pick the Columns

    Passing the whole request body into a create or update call means the client decides which columns change. Name the fields you accept, and make the framework yell when something sneaks in.

    • security
    • laravel
    • php
    • typescript
    • node
  • NOV 2026

    Don't Redirect Wherever They Tell You

    A ?next= parameter feels harmless until your login page starts sending people to someone else's site. Only redirect to paths you own, and check them the way a browser reads them.

    • security
    • laravel
    • php
    • typescript
    • node
  • NOV 2026

    You Wrapped the Column

    DATE(created_at) and helpers like whereDate() look tidy. In MySQL they usually keep a plain created_at index from doing a range seek. Compare a range against the raw column instead.

    • laravel
    • typescript
    • mysql
    • databases
    • performance
  • NOV 2026

    Page Two Already Moved

    OFFSET pagination skips and duplicates rows when the table changes under you. Use keyset/cursor pagination for live feeds, and keep OFFSET for stable admin lists.

    • laravel
    • typescript
    • databases
    • apis
  • NOV 2026

    Don't Trust X-Forwarded-For

    Rate limits, audit logs, and bans all lean on the client IP. Behind a load balancer that header is easy to misconfigure, and easy to spoof if you trust the wrong hop.

    • security
    • laravel
    • typescript
    • networking
  • NOV 2026

    A Unique Index Beats Your If Statement

    Checking that a row does not exist, then inserting it, is two steps racing the same table. Put the real guard in the database and treat the duplicate as a normal outcome.

    • laravel
    • typescript
    • mysql
    • databases
    • concurrency
  • NOV 2026

    Changing the Password Should Log Them Out

    A password reset that leaves every old session alive only fixed the problem for the attacker's next login. Here's how to make sessions and tokens actually end in Laravel, Node, and WordPress.

    • security
    • laravel
    • typescript
    • wordpress
    • authentication
  • NOV 2026

    A String Isn't as Long as You Think

    Bytes, code points, UTF-16 units, and what a human calls a character are four different numbers. Your frontend, backend, and database each pick one, and they usually don't pick the same one.

    • php
    • laravel
    • typescript
    • mysql
    • debugging
  • NOV 2026

    Don't Fetch Whatever URL They Give You

    Link previews, webhook settings, and "import from URL" all mean your server makes requests on a user's behalf. Make sure it can't be pointed at your own network.

    • security
    • laravel
    • typescript
    • wordpress
  • NOV 2026

    Escape It on the Way Out

    Validation keeps bad data out. Escaping keeps the data you let in from turning into code on someone else's screen. They are different jobs, and the second one depends on where the data is going.

    • laravel
    • typescript
    • react
    • wordpress
    • security
  • OCT 2026

    Stop Logging the Password

    Logs and error trackers end up holding passwords, tokens, and card data because nobody decided they shouldn't. Redact at the source, log on purpose, and check what's actually in there.

    • security
    • laravel
    • php
    • typescript
    • logging
  • OCT 2026

    A Flaky Test Is Telling You Something

    Flaky tests aren't bad luck. They're usually time, order, shared state, or the network leaking into your suite. Here's how to find the leak instead of hitting rerun.

    • testing
    • laravel
    • typescript
    • debugging
  • OCT 2026

    Staging Should Never Email a Real Customer

    Copy production data into staging, point it at a real mail server, and wait. Sooner or later a customer gets an invoice that doesn't exist. Make it impossible, not just unlikely.

    • laravel
    • typescript
    • wordpress
    • devops
    • email
  • OCT 2026

    You Don't Have Backups Until You've Restored One

    A backup job that says 'success' every night proves a file got written. It doesn't prove you can get your data back. Test the restore, on purpose, before you need it.

    • databases
    • devops
    • laravel
    • typescript
    • reliability
  • OCT 2026

    CORS Is Not Your Firewall

    CORS decides which web pages can read your API's responses in a browser. It doesn't stop anyone from calling your API. Configure it like that's true.

    • security
    • laravel
    • typescript
    • node
    • apis
  • OCT 2026

    Commit the Lockfile. Then Actually Use It.

    composer.json and package.json describe what you'd accept. The lockfile is what you actually tested. Treat it that way in CI and on deploy.

    • php
    • laravel
    • typescript
    • node
    • deployment
    • dependencies
  • OCT 2026

    Every Endpoint Needs a Speed Limit

    If an endpoint can be called once, it can be called ten thousand times. Rate limit by the right key, count in a shared store, return a real 429, and put the tightest limits on the things that cost you money.

    • software-engineering
    • laravel
    • php
    • typescript
    • node
    • security
    • api
  • OCT 2026

    Never Trust the Filename

    File uploads are user input with extra steps. Validate the contents, rename everything, keep it out of the webroot, and serve it on your terms.

    • security
    • laravel
    • typescript
    • file-uploads
    • aws
  • OCT 2026

    Soft Deleted Isn't Deleted

    Soft deletes keep the row around, which is the point. It also means the row still holds its email, still hits your unique index, and still shows up in any query that skips the scope. Decide what deleted means before the database decides for you.

    • laravel
    • typescript
    • databases
    • architecture
  • OCT 2026

    Anyone Can POST to Your Webhook

    A webhook endpoint is a public URL that changes data in your app. Verify the signature on the raw body, compare it safely, reject old timestamps, and don't trust the payload more than you have to.

    • laravel
    • typescript
    • webhooks
    • security
  • OCT 2026

    Your Cron Job Runs on Every Server

    Scheduled tasks are easy on one box. Add a second server or a third container and your nightly job runs three times. Pick one runner, lock the work, and make it safe to repeat anyway.

    • laravel
    • typescript
    • scheduling
    • architecture
  • OCT 2026

    The Job Ran Before the Row Existed

    A database transaction isn't done until it commits. Jobs, emails, and API calls fired from inside one can run too early, or run for something that never happened. Wait for the commit, and keep the slow stuff out.

    • laravel
    • typescript
    • databases
    • queues
  • OCT 2026

    Ship It Turned Off

    Deploying code and releasing a feature don't have to happen at the same time. Merge small, ship behind a flag, roll out on purpose, and delete the flag when you're done.

    • software-engineering
    • laravel
    • typescript
    • deployment
  • OCT 2026

    Logged In Isn't the Same as Allowed

    Authentication tells you who someone is. It says nothing about whether this record is theirs. Check ownership on the server, on every route, and scope your queries so the wrong row never comes back.

    • software-engineering
    • laravel
    • typescript
    • security
  • OCT 2026

    200 OK Is Not a Health Check

    A health route that always returns 200 only proves the process is on. Split "is it alive" from "can it serve traffic," check the things that actually break, and don't let one slow dependency take every server out of rotation.

    • software-engineering
    • laravel
    • typescript
    • reliability
    • devops
  • OCT 2026

    Retrying Harder Won't Fix a 400

    Retries help when the network hiccuped. They hurt when the request was wrong, the dependency is down for real, or fifty workers all try again at once. Retry the transient ones, back off, and know when to quit.

    • software-engineering
    • laravel
    • typescript
    • reliability
  • OCT 2026

    Last Write Wins. That's the Bug.

    Read it, change it, save it works fine with one user. Put two requests on the same row and one of them quietly disappears. Let the database do the math, lock when you have to, and check a version when a human is in the middle.

    • software-engineering
    • laravel
    • typescript
    • databases
  • OCT 2026

    Don't Load the Whole Table

    Code that grabs every row works great in dev and falls over in production. Process big data in pieces, and pick pieces that don't move under you.

    • laravel
    • typescript
    • performance
    • databases
  • OCT 2026

    The Cache Is Lying to You

    Caching makes slow things fast and correct things wrong. Decide how stale is okay, who clears it, and what happens when it expires, before you add it.

    • software-engineering
    • caching
    • laravel
    • typescript
    • performance
  • OCT 2026

    Validate It at the Door

    Bad data is cheapest to reject the moment it shows up. After that, every layer has to guess.

    • laravel
    • typescript
    • validation
    • architecture
  • OCT 2026

    The AI Wrote It. You Still Own It.

    AI tools write plausible code fast. Plausible is not the same as correct, and your name is still on the commit.

    • ai
    • code-review
    • laravel
    • typescript
  • OCT 2026

    A Log Line Nobody Can Search Is a Diary

    If your logs are sentences, you are writing a diary. Log events with context so you can actually find the problem at 2am.

    • logging
    • debugging
    • laravel
    • typescript
  • OCT 2026

    Your Old Code Is Still Running

    Deploys aren't instant. Old servers, old queued jobs, and old browser tabs keep running against your new schema and API. Change things in steps they can survive.

    • software-engineering
    • laravel
    • typescript
    • databases
  • OCT 2026

    It Was Fast With Ten Rows

    Most slow pages aren't slow because of PHP or React. They're slow because of how many queries and requests they make once real data shows up. Count them.

    • software-engineering
    • php
    • laravel
    • typescript
    • performance
  • OCT 2026

    Your Server Doesn't Live in Your Timezone

    Store moments in UTC, keep the user's timezone as a real IANA name, and convert at the edges. A lot of date bugs come from skipping one of those.

    • software-engineering
    • php
    • laravel
    • typescript
  • OCT 2026

    Money Is Not a Float

    Floats are fine for a lot of things. Prices, totals, and refunds are not on the list. Store integer cents, round once, and do the math in one place.

    • software-engineering
    • php
    • laravel
    • typescript
  • OCT 2026

    Your .env File Is Not a Global Variable

    Reading environment variables wherever you need them works until a cached config, a typo, or the string "false" bites you. Read config once, validate it, and pass it around.

    • software-engineering
    • laravel
    • typescript
    • node
  • OCT 2026

    Hang Forever Is Not a Strategy

    Every outbound call has a timeout, even when you never set one. Pick numbers on purpose so hung remotes fail fast instead of tying up workers and users.

    • software-engineering
    • laravel
    • typescript
  • OCT 2026

    Make It Safe to Run Twice

    Retries, webhooks, and double clicks will run your write path again. Design the work so a second pass does not double-create, double-charge, or double-email.

    • software-engineering
    • laravel
    • typescript
  • OCT 2026

    Catching It Doesn't Mean You Handled It

    An empty catch block (or one that only logs "failed") hides the failure from everyone who needs it. Catch with a plan, or let it surface.

    • software-engineering
    • php
    • typescript
  • OCT 2026

    A Boolean Is a Terrible Status

    true and false feel simple until you have to explain what actually happened. Name the outcome and your code gets easier to read, retry, and debug.

    • software-engineering
    • php
    • typescript
  • SEP 2026

    Treat Every Integration Like It Will Break

    Stripe, email, shipping, CRMs, webhooks. The other system will flake. Design the handoff so your app stays honest when it does.

    • software-engineering
    • architecture
    • apis
  • SEP 2026

    If It Can Wait, Put It In a Queue

    Web requests are for answering people. Emails, exports, webhooks, and image work can wait in a job. Here’s the boring habit that keeps apps feeling fast.

    • software-engineering
    • laravel
    • architecture
  • SEP 2026

    Stop Turning Every WordPress Problem Into a Plugin Problem

    Another plugin is often the wrong fix. Sometimes the cleaner path is custom code, a setting you already have, or deleting something.

    • software-engineering
    • wordpress
    • maintainability
  • SEP 2026

    PHP Has Been Dying for 20 Years. It’s Doing Fine.

    The obituaries keep coming. The web keeps running on PHP anyway. Here’s why the “dead language” story keeps missing the point.

    • software-engineering
    • php
    • laravel
  • SEP 2026

    I Still Like Boring Software

    New frameworks are fun. Most products still need a stack that ships features, takes payments, and stays up without a PhD to deploy.

    • software-engineering
    • architecture
    • laravel