polycratia

"Works on my machine" is almost never a configuration difference. It is a guarantee difference: your laptop quietly hands you something production never promised, and your code leans on it.

Ordering is the hardest class of these.

Locally, a query with no explicit ORDER BY comes back in insertion order. The table is small, nothing has been updated twice, there is one plan and one worker. In production that same query hits a table that has been written, updated and vacuumed for a year, and it may be read with a parallel plan, so "take the first row" quietly turns into "take an arbitrary row". In payment reconciliation that is the difference between the latest status of a transaction and some status of it.

Event order goes the same way. Locally a provider callback and the action that triggered it arrive in the order you clicked them, seconds apart. In production the provider retries, the callback overtakes your own commit, and the two states land in reverse.

Neither of those lives in a config file. They are assumptions your environment happened to satisfy.

So when something works locally and fails deployed, I stop hunting for a missing variable. I ask what the local environment was guaranteeing for free: ordering, uniqueness, a single process, one clock, zero network latency. Then I either write the guarantee into the code (explicit ordering, version checks, idempotency keys, state machines that reject backwards transitions) or I accept that it cannot be had and design for its absence.

A config difference is a bug you can find. A guarantee difference is a bug that waits for load.

I went deeper into this failure class on my blog, if it's useful: https://polycratia.com/c/42540bb3

Ordering, uniqueness, timing: one of those has probably cost you more than the other two, and it is worth knowing which one before it bills you again...

react

$ new-project --brief

or email hey@polycratia.com