You picked a strong password generator. Your users are typing in 20-character random strings or 6-word diceware passphrases. Great. Now answer this: when that password lands on your server, what algorithm hashes it before it hits the database?

If you’re still reaching for bcrypt by reflex in 2026, you’re not wrong — but you’re not making the modern choice either. The OWASP Password Storage Cheat Sheet now lists Argon2id as the first recommendation, with scrypt second, bcrypt third, and PBKDF2 reserved for FIPS-compliance scenarios. Most ranking content predates that shift and still treats bcrypt as the default. This post is the decision table that should exist but doesn’t.

This is a direct follow-up to our password generator entropy guide — that post covered what makes a password strong on the user side. This one covers what your service should do with it on the storage side.

TL;DR: argon2 vs bcrypt 2026 quick answer

For a new application in 2026, use Argon2id with m=64MB, t=3, p=4 as a starting point and tune up from there. Use scrypt if you’re on a runtime where Argon2 bindings are flaky. Keep bcrypt if you already have it and migrating is risky — it’s still safe with cost=12 or higher. Use PBKDF2-SHA256 with 600,000+ iterations only when FIPS 140-2/3 compliance forces your hand.

That’s the headline. The rest of this post is the why behind each choice and the parameters you actually need to ship.

The four candidates at a glance

AlgorithmYearMemory-hard?GPU-resistant?OWASP 2026 statusUse when
Argon2id2015YesStrongRecommendedNew apps, no FIPS constraint
scrypt2009YesGoodAcceptableArgon2 unavailable
bcrypt1999NoWeak by 2026Legacy-OKExisting systems
PBKDF22000NoWeakFIPS-onlyCompliance forces it

Memory-hardness is the property that matters most in 2026. A GPU farm can compute SHA-256 hashes by the billions per second. The same farm chokes on Argon2id with 64MB of memory per hash because GPUs don’t have that kind of RAM per core. That’s the whole game.

Why Argon2id is the 2026 default

Argon2 won the Password Hashing Competition in 2015. There are three variants:

  • Argon2d — fastest, but vulnerable to side-channel attacks. Don’t use for password storage.
  • Argon2i — side-channel resistant, but weaker against GPU attacks.
  • Argon2id — hybrid. Combines the strengths of both. Use this one.

Argon2id has three tunable parameters:

  • m (memory cost) — RAM in KiB. Higher = more GPU-resistant. Start at 65536 (64MB).
  • t (time cost) — number of passes over memory. Start at 3.
  • p (parallelism) — threads. Start at 4.

A reasonable Node.js setup using the argon2 npm package:

import argon2 from 'argon2';

const hash = await argon2.hash(password, {
  type: argon2.argon2id,
  memoryCost: 65536, // 64 MiB
  timeCost: 3,
  parallelism: 4,
});

const valid = await argon2.verify(hash, password);

Tune these so a single hash takes ~500ms on your auth server. That’s the OWASP guidance: slow enough to make brute-force expensive, fast enough that login feels instant.

When scrypt still makes sense

scrypt predates Argon2 by six years and was the first widely-deployed memory-hard KDF. It’s solid. The reason it sits second on the OWASP list rather than first is that Argon2 has more tuning flexibility and clearer guidance on the time/memory tradeoff.

Use scrypt when:

  • Your runtime has weak Argon2 bindings (some embedded or older Node.js environments).
  • You’re already running scrypt and don’t want to migrate without a reason.
  • You need a single-parameter algorithm and don’t want to think about three.

OWASP’s recommended parameters in 2026: N=2^17, r=8, p=1 (that’s ~128MB of memory). The Node.js built-in crypto.scrypt works fine here.

When bcrypt is still fine

bcrypt is 27 years old. It’s not memory-hard. By 2026, GPU farms can attack bcrypt orders of magnitude faster than they could in 2015. And yet — for most apps, with cost=12 or higher, it’s still safe enough that migrating away isn’t urgent.

Keep bcrypt when:

  • You have an existing user base hashed under bcrypt.
  • Your cost factor is at least 12 (computes ~250ms per hash on modern hardware).
  • You’re not a high-value target (financial services, password managers).

If you do migrate, the standard pattern is rehash on next login: when a user logs in, verify with bcrypt, then immediately rehash with Argon2id and store the new hash. Within a few months you’ll have everyone migrated without forcing password resets.

Don’t use bcrypt for new applications in 2026 unless you have a specific constraint that rules out Argon2. The 72-byte input length limit alone is a footgun — long passphrases get silently truncated.

When PBKDF2 is unavoidable

PBKDF2 is the weakest of the four against modern GPU attacks. It’s not memory-hard. Its only structural advantage is that it’s been a NIST-approved algorithm since 2000, which means it shows up on FIPS 140-2 and FIPS 140-3 cryptographic module lists.

Use PBKDF2-SHA256 only when:

  • You’re shipping into an environment with FIPS compliance requirements (US federal, healthcare, certain financial sectors).
  • Your cryptographic library is restricted to FIPS-approved primitives.

If you’re forced to use it, OWASP recommends at least 600,000 iterations of PBKDF2-SHA256 in 2026. That number doubles every few years; check the latest cheat sheet before shipping.

The decision flowchart

Here’s the actual decision in five questions:

  1. Are you legally required to use FIPS-approved cryptography? → PBKDF2-SHA256 with 600K+ iterations.
  2. Do you have an existing bcrypt deployment that’s working? → Keep bcrypt at cost ≥ 12, migrate opportunistically on login.
  3. Are you on a runtime with reliable Argon2 bindings (Node.js, Python, Go, Rust, Java)? → Argon2id, m=64MB, t=3, p=4.
  4. Argon2 unavailable but scrypt is? → scrypt, N=2^17, r=8, p=1.
  5. None of the above? → Find a runtime that supports Argon2id. The choice is that important.

What about peppers, salts, and HMAC layers?

Quick clarifications, since these come up:

  • Salt — every modern algorithm above generates a random per-password salt automatically. You don’t manage this yourself.
  • Pepper — a server-side secret HMAC’d with the password before hashing. Adds defense-in-depth if your database leaks but your app secret doesn’t. Optional but cheap.
  • HMAC layer — pre-hashing the password with HMAC-SHA256 before passing to bcrypt is a known workaround for bcrypt’s 72-byte limit. Not needed for Argon2id or scrypt.

Putting it together

The argon2 vs bcrypt 2026 question really decomposes into: am I building something new, or maintaining something old? New apps should ship Argon2id. Existing bcrypt deployments should stay on bcrypt with a migration plan. Everything else is edge cases.

If you’re generating passwords to test a new auth flow, our Password Generator creates strong random strings and diceware passphrases entirely in your browser — no upload, no logging. Pair it with Argon2id on the server and you’ve got a 2026-grade password pipeline.