Retries are great, but duplicates are inevitable—workers crash, Redis reconnects, deploys happen. I prefer building idempotency into the job key itself. BullMQ supports a jobId that acts like a de-dupe key: if a job with the same id already exists, enqueue becomes a no-op. I derive the jobId from the business identity (like welcome-email:${userId}) so upstream retries don’t accidentally flood the queue. It doesn’t solve every case (jobs can still run twice in certain failure modes), but paired with idempotent handlers and proper DB constraints, it makes the system much calmer in production.