BLOG

🌱 digital garden

Basé à Nice, France - CET (UTC+1)

BLOG

🌱 digital garden

Basé à Nice, France - CET (UTC+1)

BLOG

🌱 digital garden

Basé à Nice, France - CET (UTC+1)

Software engineering topics I changed my mind on

Eight positions I held with confidence and no longer do. Most of the reversals point the same way, toward fewer moving parts.

I keep a repository of short notes, one file per thing learned, 261 so far. Read in order they are mostly a record of positions I abandoned. These are the ones that changed how I design systems. I held most of the old positions for years, and argued for some of them in meetings.

Reliability comes from a queue

It comes from being able to run the operation again. I used to reach for a broker whenever something had to happen eventually. What I build now, almost every time, is a table with a status column and a job that re-reads everything not yet done. A reconciliation loop needs no delivery guarantees, survives its own crashes, and can be inspected with a SELECT. A queue gives you throughput. It was never what gave you correctness.

Exactly-once is a property to aim for

It is a property to stop needing. An idempotency key on the request and a unique constraint in the database turn every retry into a no-op, and then at-least-once is simply fine. I have spent more time than I like to admit designing around duplicate delivery when the cheaper move was to make duplicates harmless.

Design for the second use case

I design for the first and wait for the third. The abstraction you extract from two examples encodes whatever they happened to share, and the third example is always the one that does not fit. Duplication is a cost you can see and pay down. A wrong abstraction is a cost that every later change pays without anyone noticing why.

A service boundary is a module boundary

A process boundary gives you independent deployment and an unreliable function call. It does not give you a clean interface; that is a design activity, and you can do it inside one binary. I now want to see the modules stable under one roof before any of them gets a network between them. Most of the time they never need one.

Configuration makes a system flexible

Every option is a code path, and most options select a path nobody tests. I treat a new setting as a new feature, with the same bar. A system with three settings that all work is more flexible in practice than one with thirty where the combinations are unknown.

An enum makes an API safer

Inside a codebase, yes. Across a network it is a migration waiting to happen: clients switch exhaustively, so adding a value breaks everyone who treats the default case as an error. Unknown values have to be documented as tolerated from the first version, or the enum is frozen forever.

Long requests are fine if the timeout is long enough

Anything a person would go and get coffee during should return 202 and a status URL. The long-timeout version works in the demo and then meets a proxy, a mobile network or a deploy. The asynchronous version is three endpoints, and it is also the only version where the caller can ask how it is going.

A model is a function

A language model is a dependency with a release schedule you do not control. Four beliefs fell together here:

  • Temperature zero is not determinism. It removes most of the sampling variance, not all of it, and a model update changes the output anyway. Pin the version, and if you need the same answer exactly, cache it.

  • More context is not more accuracy. Loosely related material is noise the model must ignore, and it does not always manage. Measure retrieval separately from generation, or every failure looks like a model failure.

  • A score out of ten is not an evaluation. Ask the same judge twice and a 7 becomes a 6. A verdict against named criteria is less satisfying and is the only kind you can audit.

  • An agent does not stop when it is done. Without a hard step budget it retries a failing tool until the money runs out. A cap, and a report of what was left undone, beats a loop that pretends to finish.

The direction of travel

Most of these are the same reversal. I believed a system became more robust as I added mechanism to it: a broker, a guarantee, an abstraction, a service, an option. What actually made systems robust was being able to re-run things, inspect them with ordinary tools, and delete parts without fear.

The notes themselves are an instance of it. One fact, one file, no tooling. There is nothing in it to maintain, which is probably why it is still going. I expect to disagree with part of this list in a few years. That would be a good sign.

Written from my own notes and proofread with AI.