INSERT ... ON DUPLICATE KEY do nothing
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In MySQL, there is no literal INSERT ... ON DUPLICATE KEY DO NOTHING syntax like PostgreSQL's ON CONFLICT DO NOTHING. The usual MySQL answer is INSERT IGNORE, or in some cases a no-op ON DUPLICATE KEY UPDATE clause. Which one you should use depends on whether you want silent duplicate suppression or more explicit duplicate-handling behavior.
The Simple MySQL Answer: INSERT IGNORE
If your goal is "try to insert this row, but do nothing if a unique or primary-key conflict happens," the most direct MySQL syntax is:
If the row would violate a unique or primary-key constraint, MySQL suppresses the error and skips that row.
This is the closest practical equivalent to "do nothing on duplicate" in MySQL.
A No-Op ON DUPLICATE KEY UPDATE
Sometimes people prefer to stay in the ON DUPLICATE KEY UPDATE form, especially when surrounding code already uses that pattern.
This triggers the duplicate-key path but performs a no-op update.
Functionally, this can behave like "do nothing," but it still goes through the duplicate-update machinery, which is different from simply ignoring the row.
Which One Is Better
Use INSERT IGNORE when you genuinely want to skip duplicate inserts quietly.
Use ON DUPLICATE KEY UPDATE when:
- you may later want real update behavior
- the duplicate path should be explicit in the query shape
- you need behavior tied to that clause specifically
If the real requirement is just "insert if absent, otherwise leave it alone," INSERT IGNORE is usually simpler.
Be Careful About What IGNORE Hides
INSERT IGNORE does not only affect duplicate-key handling. It can also suppress other kinds of insert errors or convert them into warnings depending on the situation.
That means IGNORE is convenient, but it is also broad.
If you want a very explicit duplicate-key path and do not want to suppress other issues as casually, the no-op ON DUPLICATE KEY UPDATE pattern can be easier to reason about.
Bulk Insert Example
INSERT IGNORE is especially common in bulk-loading scenarios.
Rows with duplicate unique values are skipped, while valid new rows are inserted.
That is often the exact behavior you want for idempotent reference-data loading.
Concurrency Perspective
A major reason to prefer constraint-based insert handling over "check then insert" logic is concurrency. If you first query to see whether a row exists and then insert only if absent, another session can still insert the same row between those two steps.
Using a unique constraint together with INSERT IGNORE or duplicate-key handling moves the race resolution into the database engine, which is safer.
Common Pitfalls
The most common mistake is assuming MySQL has the exact same DO NOTHING syntax as PostgreSQL. It does not.
Another issue is using INSERT IGNORE without understanding that it can silence more than just duplicate-key problems.
Developers also sometimes write application-side "if not exists then insert" logic and forget that it can race under concurrency.
Finally, if you use a no-op ON DUPLICATE KEY UPDATE, make sure it is truly acceptable for the database to treat the row as having taken the duplicate-update path rather than being simply ignored.
Summary
- MySQL does not have a literal
ON DUPLICATE KEY DO NOTHINGsyntax. - '
INSERT IGNOREis the usual practical answer for skipping duplicate inserts.' - A no-op
ON DUPLICATE KEY UPDATEclause is another option. - Unique constraints are the right place to enforce idempotent insert behavior under concurrency.
- Choose the approach based on whether you want broad ignore behavior or a more explicit duplicate-handling path.

