👋 Hey friends,

This is the final newsletter of the year! Here’s what I’ve got in store for you this week:

  • A short summary of the year

  • Another snippet from The Backend Lowdown

  • Agent Skills

Let’s get into it 👇

2025 Wrapped

I started making and posting content this year in May and it’s been an incredible journey. I’ve had so much fun making videos, reading up on obscure data structures and algorithms, planning on call scenarios (or reciting them from memory), and just reading your comments. As a fun way to celebrate the year, I jotted down some quick numbers to share:

  • TikTok (started May): ~26K followers

  • Instagram (started Aug): ~39K followers

  • Newsletter (started May): 667 subscribers (still can’t believe that’s a real number)

  • The Backend Lowdown (started May): now 100+ pages and still growing

Honestly, I’m just grateful. If you’ve ever watched a video, shared a post, replied to an email, or told a friend about the newsletter… thank you.

The Backend Lowdown: Chapter 1 Preview

Every newsletter will include a snippet from my book in progress, The Backend Lowdown, available for $5 right now on Gumroad!

Get The Backend Lowdown →

Workflow Tips

Even safe migrations can go sideways if they're poorly timed, rushed, or not coordinated. Schema changes are as much a team process as they are a technical task - and the way you structure your workflow can dramatically reduce risk.

Here are some practical habits that make migrations safer, easier to deploy, and less likely to surprise anyone at 2AM:

Write Descriptive Migration Names and Comments

Naming your migration AddStatusToUsers is fine, but leaving comments inside the file explaining why you're doing something is even better - especially if it's a workaround or involves delayed backfilling.

Example:

# Adding this as nullable first to allow backfill via background job.
# Once all rows are populated, we'll add NOT NULL in a follow-up migration.
add_column :users, :status, :string

Your future teammates (or future you) will thank you.

Don't Ship Code That Assumes the Migration Already Ran

If your application code expects a column or table that hasn't been deployed yet, it can break production if the app deploys before the migration runs - or if the migration fails halfway through.

Safer pattern:

  • Deploy schema changes first

  • Ensure they succeed

  • Then deploy the code that depends on the new schema

This requires separating schema and code deploys when they're tightly coupled - or using runtime conditionals (e.g., feature flags, presence checks).

Trend to watch: Agentic Skills

In case you missed it, Anthropic published a new open standard: Agent Skills. It’s an interesting idea, but also an incredibly simple one: it’s just a folder that contains SKILLS.md (instructions + metadata), plus optionally scripts, references, and assets/templates. The power behind it is to “write once, use everywhere”, and in doing so your team’s procedural knowledge becomes a reusable package that agents can load when relevant. Instead of building a different “agent” for every niche job, you keep a general agent and give it a library of skills (like internal playbooks). That makes agent behavior more consistent, repeatable, and shareable across tools/teams. I haven’t had the ability to try this out yet, but will do so soon. In case you’re using something besides Claude, Codex also has been building off this standard and Copilot apparently supports it as well.

That’s a wrap for this week as well as this year. If something here made your day smoother, feel free to reply and tell me about it. And if you think a friend or teammate would enjoy this too, I’d be grateful if you shared it with them.

Until next year,
Steven

Keep Reading