Some operations are safe to repeat by construction, and recognising them saves a table and a transaction.
// naturally idempotent — repeating changes nothing
$order->update(['status' => 'shipped']);
Cache::forget("order:{$id}");
Storage::delete($path);
$search->index($document); // upsert by id
// not idempotent — needs a claim
$account->increment('balance', 500);
Mail::send(...);
$queue->push(new NextStep());
Setting a value is safe and adjusting one is not, which is the distinction that covers most cases. The subtle one is dispatching another job: a handler that enqueues a follow-up is not idempotent even if everything it does is, because a redelivery produces two follow-ups — which is how a duplicate propagates through a chain.