At-most-once vs at-least-once vs exactly-once
Commit the offset BEFORE processing (or produce with acks=0). If the consumer crashes after committing but before finishing, the record is lost - but it is never processed twice. Cheapest, and rarely what a business flow wants.
Process first, commit the offset AFTER. A crash between processing and commit means the record is redelivered and processed again - never lost, sometimes duplicated. The practical default; it obligates every consumer side effect to be idempotent.
In Kafka: idempotent producer (dedupes broker-side retries) + transactions (atomically write output records and commit offsets together) gives exactly-once within a Kafka-to-Kafka pipeline. The moment a side effect leaves Kafka (call an API, charge a card), you are back to at-least-once + your own idempotency keys.
Default to at-least-once with idempotent consumers for anything that matters. At-most-once only for lossy-tolerant telemetry. Say 'effectively-once' in interviews and explain it as at-least-once plus dedup - claiming true exactly-once across arbitrary systems is a red flag.