SQL upsert for counters (ON CONFLICT DO UPDATE)

Counters are classic race-condition bait. If two requests read, increment, and write, you’ll lose updates under load. I prefer letting Postgres do the atomic work with an upsert: INSERT ... ON CONFLICT ... DO UPDATE to increment the existing value. Th

Frontend: copy-to-clipboard with fallback

Copying code is a core interaction in a snippets app, and it needs to work reliably across browsers. The modern API is navigator.clipboard.writeText, but it requires HTTPS and permissions in some contexts. I try it first, and if it fails I fall back t

Backend: normalize errors with a single Express handler

Without a centralized error handler, you end up with a mix of thrown errors, ad-hoc res.status(500) blocks, and inconsistent JSON shapes. I use one Express error middleware that maps known errors to stable codes and logs unknown errors with request co

Frontend: toast notifications via a small event bus

I don’t want components depending on each other just to show a toast. A tiny event bus (or context) lets any part of the app emit a toast without wiring props through five layers. The important part is keeping the API small—something like show(message

Frontend: skeleton loading instead of spinners

Spinners hide layout shifts and make an app feel slow even when it isn’t. Skeletons preserve layout and give users a sense of progress without jumping content around. I keep skeleton components simple and match the shape of the final UI. One practical

Batched writes with COPY (conceptual)

Row-by-row inserts are painfully slow for big ingests. Postgres COPY is a great bulk-ingestion tool, and in Node you can stream into COPY using libraries like pg-copy-streams. The important part is validating before you stream, because once you’re in

Prisma: avoid N+1 with include/select

Prisma makes it easy to write readable queries, but you can still create N+1 patterns by fetching parents and then fetching children in a loop. I prefer using include or select to get related data in one query when the cardinality is reasonable. I als

SQL migration safety: add column nullable, backfill, then constrain

The fastest way to surprise yourself in production is ADD COLUMN ... NOT NULL DEFAULT ... on a large table. My safe pattern is: add the column nullable with no default, backfill in batches, then add the NOT NULL constraint. If I need a default for new

GraphQL persisted queries (hash allowlist)

GraphQL endpoints can be abused with huge queries that are expensive to parse and execute. Persisted queries let clients send a hash (e.g. sha256:...) instead of the full query, and the server only executes queries it recognizes. This reduces payload

tRPC router pattern for type-safe APIs

Maintaining separate REST types and frontend client types can be a lot of overhead in TypeScript-heavy teams. With tRPC, the API types flow directly to the client, which reduces duplication and keeps refactors safe. Runtime validation still matters, s

Service worker: cache static assets safely

Offline-first is hard, but caching static assets is an easy win for repeat visits. I keep the service worker scope narrow and cache only versioned assets (hashed filenames) so I don’t accidentally serve stale HTML or API responses. The most common fai

Web Vitals reporting to an API endpoint

Synthetic performance tests don’t always match what real users experience. Web Vitals reporting gives you field data (CLS, LCP, INP, etc.). I collect vitals on the client and POST them to a lightweight endpoint, then aggregate on the backend. Sampling