Understanding Bcrypt vs Argon2 for Password Hashing

Bcrypt or Argon2id? Compare how they work, their security against GPU attacks, recommended settings and how to migrate safely.

Last updated · 2026-09-28

Why passwords need special hash functions

General-purpose hashes like SHA-256 are designed to be fast. That is great for checksums and terrible for passwords: a modern GPU can compute billions of SHA-256 hashes per second, so a leaked database of fast hashes falls to dictionary attacks within hours.

Password hashing functions are deliberately slow and salted. Each guess costs the attacker real time and money, while a single login check still feels instant to a legitimate user.

How bcrypt works

Bcrypt, published in 1999, is based on the Blowfish cipher's expensive key setup. Its cost factor is a power of two: cost 12 means 2^12 rounds. Every hash includes a 128-bit random salt, which is why the same password produces a different 60-character string each time — try it in our PHP password hash tool.

Bcrypt's limitations are its small memory footprint (about 4 KB), which makes it somewhat GPU-friendly, and a 72-byte maximum input length.

How Argon2 works

Argon2 won the Password Hashing Competition in 2015. Its key idea is memory hardness: computing a hash requires a configurable amount of RAM, for example 64 MB. GPUs and ASICs have plenty of compute but limited fast memory per core, so memory hardness dramatically reduces their advantage.

Argon2 has three variants. Argon2d resists GPU attacks but is vulnerable to side channels; Argon2i is the opposite; Argon2id combines both and is the one you should use.

Recommended parameters

OWASP currently recommends Argon2id with at least 19 MiB of memory, 2 iterations and 1 degree of parallelism, or bcrypt with a cost of at least 10. Tune on your own hardware so a hash takes around 100–300 ms.

// Node.js
import argon2 from "argon2";
const hash = await argon2.hash(pw, { type: argon2.argon2id, memoryCost: 19456, timeCost: 2 });
const ok = await argon2.verify(hash, pw);

// PHP
$hash = password_hash($pw, PASSWORD_ARGON2ID);

Which should you choose?

For new projects where your language and hosting support it, choose Argon2id. For existing systems, bcrypt is still secure — there is no emergency. Bcrypt also has the widest support across languages, frameworks and tools like Apache's .htpasswd files.

Migrating without forcing resets

You cannot convert old hashes because you don't know the passwords. Instead, upgrade on login: verify the password with the old algorithm, then immediately re-hash it with Argon2id and save. In PHP, password_needs_rehash() does exactly this check. After a few months, only inactive accounts remain on the old scheme, and you can require a reset for those.

Try the tools from this article

← All tutorials