Three habits for building reliable backends
June 5, 2026 · 6 min read
A placeholder post with a little more structure so you can see code blocks and lists. Rewrite it with your own lessons.
1. Make failure boring
Design so that the common failure — a timeout, a dropped connection — is handled the same dull way every time. Retries with backoff, idempotent writes, clear error types.
func withRetry(fn func() error) error {
for i := 0; i < 3; i++ {
if err := fn(); err == nil {
return nil
}
time.Sleep(backoff(i))
}
return ErrExhausted
}
2. Log the decision, not just the event
"Charged user 42" is an event. "Charged user 42 because subscription was past_due and grace period expired" is a decision. The second one saves you at 3am.
3. Test the unhappy path first
The happy path tends to work by construction. Bugs live where things go wrong — so write those tests first.