Pick the wrong password-hashing algorithm in 2026 and you find out the hard way, usually after a breach, when someone runs your hash database through a GPU cluster. Two memory-hard functions dominate the real conversation: Argon2, winner of the 2015 Password Hashing Competition, and scrypt, the older design that Colin Percival built for his Tarsnap backup service back in 2009. Both force an attacker to spend real memory, not just CPU cycles, to test each guess. Both show up in production systems today. They are not interchangeable, and the gap between them shows up the moment you read their reference parameters side by side.
OWASP’s Password Storage Cheat Sheet puts a number on that gap. Its minimum Argon2id profile needs about 19 mebibytes of memory per login attempt. Its scrypt fallback needs roughly 128 mebibytes for a comparable level of protection. That is not a rounding error, it is a nearly 7x difference in the memory budget required to hit OWASP’s baseline security bar. This comparison walks through the RFC specifications (RFC 9106 for Argon2, RFC 7914 for scrypt), the actual memory and CPU tradeoffs, where each algorithm shows up in production today, and how to migrate a system that still runs scrypt, bcrypt, or plain PBKDF2.
What Is Argon2? Design, Variants, and RFC 9106
Argon2 won the Password Hashing Competition in July 2015 and was later standardized by the IETF as RFC 9106 in September 2021. It builds a memory-fill graph organized into lanes, slices, and passes, then reads and writes across that graph in a pattern that depends on the chosen variant. Three variants exist. Argon2d uses data-dependent memory addressing, which gives it strong resistance to GPU cracking because each memory access depends on values computed earlier in the run. Argon2i uses data-independent addressing instead, trading some GPU resistance for protection against cache-timing side channels on shared hardware. Argon2id splits the difference: it starts with Argon2i-style passes and finishes with Argon2d-style passes.
RFC 9106 requires every compliant implementation to support Argon2id and names it the recommended default for password hashing. The algorithm exposes three tuning knobs: memory cost (measured in kibibytes), time cost (the number of passes), and parallelism (the number of parallel lanes). RFC 9106 gives two reference profiles. The high-memory profile runs Argon2id with 2 GiB of RAM, one pass, and four lanes. The lower-memory profile drops to 64 MiB with three passes and four lanes. Both use a 128-bit salt and produce a 256-bit tag.
What Is scrypt? ROMix, SMix, and RFC 7914
scrypt predates Argon2 by six years. Colin Percival designed it in 2009 for Tarsnap, his own encrypted backup service, specifically to make brute-forcing a backup passphrase expensive even for an attacker renting cloud hardware. The IETF later published it as RFC 7914, “The scrypt Password-Based Key Derivation Function.” Its core routine, ROMix, repeatedly fills a large pseudorandom memory array and then revisits that array using an internal function called SMix. SMix in turn calls BlockMix, which mixes data using the Salsa20/8 core, a reduced-round version of the Salsa20 stream cipher.
scrypt exposes three parameters: N, r, and p. N sets the CPU and memory cost as a power of two, r sets the block size that controls memory used per instance, and p sets the number of independent parallel instances. Total memory works out to roughly 128 × r × N bytes. Crank N up and memory cost rises exponentially, which is the whole point: an attacker running a GPU farm has to buy memory bandwidth, not just raw compute.
Where bcrypt and PBKDF2 Fit Into This Comparison
Argon2 and scrypt are not the only names in this space, and it helps to know why the other two common options usually lose to both of them. bcrypt dates back to 1999, designed by Niels Provos and David Mazières around the Blowfish cipher. It scales CPU cost through a work factor, but it has no memory-hardness component at all, which means a modern GPU with enough parallel cores can grind through bcrypt guesses far faster than it can grind through Argon2id or scrypt at equivalent settings. PBKDF2, standardized by NIST in SP 800-132 and also defined in RFC 2898, has the same weakness. It iterates a hash function thousands of times, but every iteration touches almost no memory, so an attacker’s cost scales with compute alone, not with memory bandwidth.
That gap is exactly why OWASP’s Password Storage Cheat Sheet ranks bcrypt and PBKDF2 below both Argon2id and scrypt, reserving them for situations where a FIPS-140 compliance requirement rules out Argon2 and scrypt entirely. PBKDF2 remains common in exactly that kind of regulated environment because it has a long-standing NIST endorsement in SP 800-132. If your system already runs bcrypt or PBKDF2 and a compliance mandate is not forcing that choice, both Argon2id and scrypt outperform them for the same reason: memory-hardness raises the cost floor for GPU and ASIC attackers in a way that pure iteration counts cannot.
Argon2 vs scrypt: Full Specs Comparison
The table below lines up both algorithms on the properties that actually matter for a deployment decision: standards status, tunable parameters, side-channel behavior, and where each one gets recommended by name.
| Property | Argon2 (Argon2id) | scrypt |
|---|---|---|
| Standard | RFC 9106 (Sept. 2021) | RFC 7914 (Aug. 2016) |
| Origin | Password Hashing Competition winner, 2015 | Colin Percival, Tarsnap, 2009 |
| Core construction | Lane/slice memory-fill graph | ROMix / SMix / BlockMix (Salsa20/8) |
| Tunable parameters | Memory cost (m), time cost (t), parallelism (p) | CPU/memory cost (N), block size (r), parallelism (p) |
| Variants | Argon2d, Argon2i, Argon2id | Single design, no variants |
| OWASP first choice | Yes, Argon2id | Fallback when Argon2id unavailable |
| OWASP minimum memory | 19,456 KiB (~19 MiB) at t=2, p=1 | ~128 MiB at N=2^17, r=8, p=1 |
| RFC high-security profile | 2 GiB, t=1, p=4 | No single reference profile in RFC 7914 |
| Side-channel design | Argon2i/id use data-independent addressing for part of the run | ROMix access pattern requires careful implementation review |
| GPU resistance approach | Data-dependent addressing (Argon2d/id) slows parallel guessing | Large pseudorandom memory array forces memory bandwidth cost |
| ASIC history | None documented at production mining scale | Purpose-built ASICs exist (Litecoin, Dogecoin mining) |
| Salt / tag size | 128-bit salt, 256-bit tag (RFC 9106 profiles) | Configurable, commonly 256-bit derived key |
| License (reference implementation) | CC0 / Apache 2.0 dual license | BSD-style (RFC reference code) |
Benchmark Data: Memory Cost and Tuning Compared
Raw throughput numbers for memory-hard functions mislead people more often than they help, because the entire design goal is to make throughput expensive, not fast. A meaningful benchmark has to hold memory budget constant and then compare wall-clock time, or hold time constant and compare memory. The table below pulls from three sourced references: the IETF’s own RFC 9106 test profiles, OWASP’s current Password Storage Cheat Sheet, and RFC 7914’s formula for scrypt memory consumption.
| Source | Algorithm | Profile | Memory | Passes / Iterations |
|---|---|---|---|---|
| RFC 9106 §4 | Argon2id | High-memory reference | 2,097,152 KiB (2 GiB) | t=1, p=4 |
| RFC 9106 §4 | Argon2id | Low-memory reference | 65,536 KiB (64 MiB) | t=3, p=4 |
| OWASP Cheat Sheet (2026) | Argon2id | Minimum acceptable | 19,456 KiB (~19 MiB) | t=2, p=1 |
| OWASP Cheat Sheet (2026) | Argon2id | Stronger alternative | 47,104 KiB (~46 MiB) | t=1, p=1 |
| OWASP Cheat Sheet (2026) | scrypt | Fallback recommendation | ~128 MiB (128 × r × N) | N=2^17, r=8, p=1 |
| RFC 7914 formula | scrypt | Memory scaling rule | 128 r N bytes per instance | N doubles cost per increment |
Read across that table and one pattern jumps out. OWASP’s Argon2id minimum uses roughly 19 MiB, its scrypt fallback uses roughly 128 MiB, and both are meant to deliver a comparable level of offline-cracking resistance at typical login latency. Argon2id gets there with less memory because its tunable parallelism and hybrid addressing let it squeeze more resistance out of each kibibyte. That efficiency is exactly why RFC 9106 and OWASP both point at Argon2id first and treat scrypt as the fallback for stacks where an Argon2 library is not available.
None of these figures translate directly into a “time to crack” number, and any article claiming an exact dollar figure for cracking either algorithm without naming the attacker’s hardware, cloud pricing, and password entropy is guessing. What the RFC and OWASP numbers do establish reliably is the memory floor an attacker’s hardware has to clear for every single guess, which is the whole mechanism these functions rely on.
Running your own benchmark beats trusting any published number, because CPU model, RAM bandwidth, thread count, compiler flags, and library version all shift the result. libsodium ships a documented API for Argon2id and exposes interactive and moderate cost presets specifically so developers can measure real hardware rather than copy numbers from a blog post. The same caution applies to scrypt implementations built on OpenSSL or Node’s native crypto module. A fair test holds either memory or wall-clock time constant across both algorithms, runs the comparison on the exact server class the production system will use, and reports thread count and concurrency alongside the result. Skip that step and a benchmark comparison is little more than a coincidence of whichever hardware happened to be on hand.
Security and Side-Channel Resistance
Argon2d, Argon2i, and Argon2id
Argon2d’s data-dependent memory addressing makes it the strongest of the three variants against GPU cracking, but that same property becomes a liability on shared or multi-tenant hardware. An attacker who can observe cache access patterns on the same machine may extract information from those data-dependent addresses. Argon2i avoids that risk by keeping memory access independent of the data being processed, at the cost of needing more total work to reach the same memory-hardness. Argon2id, the RFC 9106-mandated default, runs Argon2i-style passes first and Argon2d-style passes after, which is why OWASP and most password libraries point users at Argon2id rather than either pure variant.
scrypt’s ROMix Access Pattern
scrypt has no equivalent to Argon2’s three-way variant split. Its ROMix construction fills and revisits a large memory array through SMix, and the resulting access pattern needs the same kind of careful implementation review that any memory-hard function requires on shared infrastructure. RFC 7914 does not offer a side-channel-hardened alternate mode the way RFC 9106 does with Argon2i. Neither algorithm is broken by any published cryptanalysis as of September 2026, and researchers have studied both extensively since scrypt’s 2009 debut and Argon2’s 2015 PHC win. Academic work on Argon2i and Argon2id has explored memory-time trade-off attacks, where an attacker reduces memory at the cost of extra computation, but that research constrains parameter selection rather than pointing at a break in the algorithm itself. The same caution applies to scrypt: drop N, r, or p too low and the memory-hardness guarantee weakens fast.
GPU and ASIC Cracking Resistance
scrypt’s most interesting real-world stress test did not come from password crackers. It came from cryptocurrency miners. Charlie Lee picked scrypt as Litecoin’s proof-of-work function in October 2011 specifically because its memory requirement made GPU mining less dominant than it was on Bitcoin’s SHA-256 chain. Dogecoin followed the same path and merge-mines with Litecoin today, sharing scrypt’s hash function. That decision did not stop specialized hardware. Purpose-built scrypt ASICs eventually reached the market and took over Litecoin and Dogecoin mining, proving that a memory-hard function raises the cost of specialized hardware without making it economically impossible when the reward is large enough.
Argon2 has no equivalent production-scale ASIC history because it has never anchored a major proof-of-work cryptocurrency the way scrypt anchors Litecoin. That does not make Argon2 immune to specialized hardware in principle, but its GPU resistance draws from a different mechanism (data-dependent addressing in Argon2d and Argon2id) than scrypt’s pure memory-bandwidth wall. For password storage specifically, where an attacker faces a static hash rather than a live proof-of-work reward, both algorithms accomplish the same practical goal: they make each guess expensive enough in memory that the economics of large-scale GPU cracking break down compared to a fast hash like unsalted SHA-256.
Manufacturers like Bitmain built dedicated scrypt-mining ASICs, most visibly in the Antminer L-series line, purpose-built to compute scrypt’s ROMix construction far more efficiently than a general-purpose GPU. That hardware exists because Litecoin’s block reward made the investment worthwhile at cryptocurrency-mining scale, running the same computation billions of times a day for years. A password database does not offer that kind of sustained, guaranteed payoff, so building a scrypt-specific ASIC purely for password cracking has never made the same economic sense. The lesson for defenders is not that scrypt fails against dedicated hardware. It is that memory-hardness raises the bar rather than removing the incentive entirely, which is exactly why increasing your memory cost parameter over time, as hardware gets cheaper, matters more than picking one algorithm and freezing its configuration forever.
How Latency Budgets Shape the Choice
A memory-hard function that takes half a second per login is invisible to a user typing a password once. That same half-second becomes a real problem on a mobile app that authenticates against a backend on every API call, or on a system that needs to verify thousands of logins per second during a traffic spike. Latency budget, not raw security margin, often decides which algorithm and which parameter set a team actually ships.
Argon2id’s tunable parallelism gives it an edge here. A team can raise parallelism on a multi-core server to keep wall-clock latency low while still hitting a target memory cost, something scrypt’s simpler N/r/p model handles less flexibly since its parallelism parameter multiplies independent instances rather than splitting one computation across cores the way Argon2’s lane design does. For a single-page login form, that distinction rarely matters. For an authentication microservice fielding thousands of requests per second behind a mobile app, it can be the difference between a smooth rollout and a capacity incident. Either way, the fix is the same: measure actual p95 latency on production-equivalent hardware before locking in a parameter set, rather than trusting a number from a blog post written on different silicon.
Real-World Adoption: Who Uses What in 2026
- Tarsnap: the service scrypt was built for. Colin Percival still runs it, and scrypt protects the encryption keys derived from a user’s passphrase.
- Litecoin: uses scrypt as its proof-of-work hash function, a design choice made by Charlie Lee in 2011 that shaped a decade of GPU and later ASIC mining hardware.
- Dogecoin: merge-mines with Litecoin and shares its scrypt-based proof-of-work.
- Django: the Python web framework ships an Argon2 password hasher class and documents installing the
argon2-cffipackage to enable it, alongside support for a scrypt-based hasher for teams that cannot add the Argon2 dependency. - libsodium: the widely embedded crypto library exposes
crypto_pwhash, which implements Argon2id as its password-hashing and key-derivation API. - OWASP: the Password Storage Cheat Sheet, maintained by the OWASP Foundation, lists Argon2id as its first-choice recommendation and scrypt as the documented fallback.
- The IETF: standardized both algorithms as RFCs, publishing RFC 9106 for Argon2 in 2021 and RFC 7914 for scrypt in 2016, which is why both show up as accepted options in compliance-driven environments.
Password Managers and Crypto Wallets: Where the Two Algorithms Meet
Outside of web application login forms, both algorithms show up wherever a system needs to turn a human-memorable secret into a strong encryption key. Bitcoin’s BIP-38 standard, which defines how to encrypt a private key with a passphrase so it can be printed or stored offline without exposing the raw key, uses scrypt as its key-derivation step. That choice predates Argon2’s existence by six years and has stuck around in wallet software that still supports BIP-38-encrypted keys today. Hardware and software wallets that implement newer key-protection schemes increasingly reach for Argon2id instead, following the same logic that pushed OWASP toward it: less memory required for an equivalent security margin against an attacker who steals an encrypted wallet file and tries to brute-force the passphrase offline.
Password managers face an almost identical problem to a web application’s login form, except the “database” an attacker might steal is a single encrypted vault file rather than a table of millions of accounts. That changes the calculus slightly. A vault only needs to resist one offline attack against one file, so a password manager can often afford a heavier Argon2id or scrypt profile than a web server handling thousands of concurrent logins, since there is no concurrency budget to protect. Vendors that publish their key-derivation parameters let security researchers verify the claim directly, which is worth checking before trusting a password manager with a master vault, rather than assuming a vendor’s marketing copy matches its actual configuration.
Common Mistakes When Deploying Argon2 or scrypt
Choosing the right algorithm solves half the problem. Deployment mistakes undo the benefit just as fast as picking a weak algorithm in the first place.
- Copying default library parameters without checking them. Some language bindings ship conservative defaults meant for laptops, not production auth servers. Set memory cost, time cost, and parallelism explicitly and compare them against OWASP’s current published minimums.
- Ignoring parallelism as a denial-of-service vector. A high parallelism setting combined with high concurrency can exhaust server memory during a login spike or a credential-stuffing attack. Load-test the hashing endpoint under realistic concurrent traffic, not just a single request.
- Never revisiting parameters after initial deployment. Hardware gets cheaper every year, and a memory-cost setting that felt aggressive in 2022 may be comfortably affordable to an attacker by 2026. Reassess parameters on a fixed schedule, not only after an incident.
- Reusing a salt across users or storing it improperly. Both algorithms require a unique, randomly generated salt per hash. A shared or predictable salt lets an attacker amortize precomputation across every account that used it.
- Choosing Argon2d for a password-storage use case. Argon2d’s data-dependent addressing is designed for scenarios without a shared-hardware threat model. Password storage on shared cloud infrastructure should default to Argon2id.
- Skipping rate limiting because “the hash is slow enough.” Memory-hardness slows down offline attacks, not the online login endpoint. Rate limiting and account lockout policies remain necessary regardless of which hashing algorithm sits behind them.
Licensing and Implementation Costs
Neither algorithm charges a licensing fee. Both are open specifications with open-source reference implementations, so the “cost” difference between them shows up in engineering time and infrastructure memory, not invoices. The table below breaks down what a team actually pays to adopt each one.
| Cost factor | Argon2id | scrypt |
|---|---|---|
| Algorithm license | Free, CC0 / Apache 2.0 reference code | Free, BSD-style RFC reference code |
| Reference implementation | github.com/P-H-C/phc-winner-argon2, free | Built into most standard crypto libraries, free |
| Python binding | argon2-cffi, MIT license, free | hashlib.scrypt, standard library, free |
| Node.js support | argon2 npm package, MIT license, free | Built into Node’s native crypto.scrypt, free |
| Per-login memory overhead | ~19–46 MiB at OWASP minimums | ~128 MiB at OWASP minimums |
| Relative server RAM budget impact | Lower, given OWASP’s own minimum figures | Roughly 3–7x higher than Argon2id minimums |
The real cost is capacity planning. An authentication service handling thousands of concurrent logins has to reserve memory for every in-flight hash computation. At scrypt’s roughly 128 MiB OWASP minimum, a server supporting 50 concurrent login attempts needs to reserve over 6 GiB just for hashing headroom. At Argon2id’s 19–46 MiB range, the same 50 concurrent attempts need roughly 1–2.3 GiB. That gap is the practical argument engineering teams raise when they choose Argon2id for new systems: not that scrypt is insecure, but that it costs more server memory to hit the same OWASP-defined security bar.
Sample Implementation: Argon2id in Python
Here is a minimal Argon2id password hash using the argon2-cffi library, set close to OWASP’s stronger recommended profile.
from argon2 import PasswordHasher
ph = PasswordHasher(
time_cost=1,
memory_cost=47104, # ~46 MiB, OWASP alternative profile
parallelism=1,
hash_len=32,
salt_len=16,
)
hashed = ph.hash("user-supplied-password")
ph.verify(hashed, "user-supplied-password") # raises on mismatch
Sample Implementation: scrypt in Node.js
Node’s built-in crypto module exposes scrypt directly, using OWASP’s fallback parameters.
const crypto = require('crypto');
const salt = crypto.randomBytes(16);
crypto.scrypt('user-supplied-password', salt, 64, {
N: 131072, // 2^17, OWASP fallback
r: 8,
p: 1,
}, (err, derivedKey) => {
if (err) throw err;
console.log(derivedKey.toString('hex'));
});
Migration Guide: Moving from scrypt, bcrypt, or PBKDF2 to Argon2id
Teams sitting on an existing scrypt, bcrypt, or PBKDF2 user table rarely get to force a mass password reset. Users churn away from a product that suddenly locks them out over a backend change they never asked for, so the standard path is a rolling, verify-then-rehash migration that touches each account only when its owner actually logs in. Nobody notices it happening, which is the entire point.
- Add an Argon2id library to the stack (
argon2-cffifor Python, theargon2npm package for Node.js, or Go’sgolang.org/x/crypto/argon2) alongside the existing hasher. - Tag each stored hash with its algorithm and parameters, either by using a self-describing format like the PHC string format or by adding an explicit algorithm column.
- On every successful login, verify the password against the old algorithm first, since that is still what is stored.
- Immediately after a successful legacy verification, hash the plaintext password with Argon2id using OWASP’s current minimum or stronger profile, and overwrite the stored hash.
- Log migration progress by algorithm so the team can track what share of the user table has moved to Argon2id over time.
- Set a monitoring alert for the tail of unmigrated accounts, since inactive users may never trigger the rehash-on-login path.
- After an agreed window (commonly 6-12 months, based on typical login frequency data for the product), force a password reset for any account still on the legacy algorithm.
- Once the legacy column is empty, remove the old hashing library from the dependency tree entirely rather than leaving dead code that still needs security review.
The same pattern works in reverse for a team standardizing on scrypt because Argon2 libraries are unavailable on a constrained platform, though that direction is far less common given OWASP’s current guidance.
Argon2 Pros and Cons
- Pro: Named as OWASP’s first-choice password-hashing algorithm.
- Pro: Three variants let a team pick the right side-channel and GPU-resistance tradeoff for its environment.
- Pro: Reaches comparable protection to scrypt at a smaller memory footprint per OWASP’s own minimums.
- Pro: Standardized in RFC 9106 with explicit reference profiles for both high-memory and constrained environments.
- Con: Requires an external library on platforms (older Python, some embedded runtimes) without native support, unlike scrypt in Node.js.
- Con: Argon2d’s data-dependent addressing is unsafe on shared hardware, so teams must know to pick Argon2id or Argon2i instead.
- Con: Younger than scrypt by six years, with a correspondingly shorter real-world adversarial track record outside the password-hashing context.
scrypt Pros and Cons
- Pro: Available natively in Node.js’s standard
cryptomodule and Python’shashlib, with no extra dependency to vet. - Pro: A 17-year track record, including sustained adversarial pressure from cryptocurrency miners trying to break its cost model.
- Pro: Simple parameter model (N, r, p) that is easy to reason about and easy to scale.
- Con: Needs roughly 3-7x more memory than Argon2id to hit the same OWASP-defined security bar.
- Con: No side-channel-hardened variant equivalent to Argon2i.
- Con: OWASP now lists it as a fallback rather than a first recommendation.
- Con: Higher memory overhead per login attempt means fewer concurrent hashing operations fit in the same server RAM budget.
5 Use Cases: Which Algorithm Fits Your System
- New web application password storage: Choose Argon2id. It is OWASP’s first recommendation and the algorithm most current libraries default new users toward.
- Legacy stack without an Argon2 library available: Use scrypt through the platform’s native crypto module rather than delaying a memory-hard upgrade while waiting on a dependency review.
- Proof-of-work or blockchain protocol design: scrypt has 15 years of adversarial testing against dedicated mining hardware, which is the exact threat model that kind of protocol needs to survive.
- Resource-constrained authentication endpoint (IoT gateway, embedded login): Argon2id at OWASP’s ~19 MiB minimum profile fits tighter memory budgets than scrypt’s ~128 MiB fallback.
- Multi-tenant cloud environment with untrusted co-located workloads: Argon2i or Argon2id, since their data-independent addressing phase reduces cache-timing exposure that a shared host could otherwise observe.
- Encrypted backup or file-encryption key derivation: Either works well, and scrypt has direct precedent here through Tarsnap, the service it was designed for.
The Verdict: Argon2id Wins on Paper, scrypt Still Earns Its Place
The data points in one direction for new systems. RFC 9106 standardizes Argon2id as the mandatory-to-support default, OWASP names it the first-choice password hasher, and its OWASP-minimum memory footprint runs roughly 3-7x lighter than scrypt’s fallback profile for a comparable security target. Teams starting from zero in September 2026 should default to Argon2id, tuned somewhere between OWASP’s 19 MiB minimum and its 46 MiB stronger alternative, adjusted up if server memory allows.
scrypt has not been broken, and nothing here suggests replacing it is urgent for systems that already run it correctly with adequate parameters. Its native availability in Node.js and Python removes a dependency-management argument that Argon2 cannot fully match on every platform, and its cryptocurrency-mining stress test gives it a kind of adversarial pedigree Argon2 has not accumulated. The honest verdict: pick Argon2id for anything new, keep a correctly-tuned scrypt deployment running rather than treating migration as an emergency, and never fall back to bcrypt or PBKDF2 alone when either memory-hard option is available.
Reduce the decision to three questions and most teams land on the right answer fast. First, does a compliance requirement force FIPS-approved algorithms only, ruling out both Argon2 and scrypt? If so, PBKDF2 under NIST SP 800-132 is the practical answer regardless of the technical tradeoffs discussed here. Second, is an Argon2 library available and maintained for your language and runtime? If yes, Argon2id at or above OWASP’s minimum profile is the default choice. Third, if Argon2 is unavailable, does your platform expose scrypt natively, the way Node.js and Python both do? If so, scrypt at OWASP’s fallback parameters closes the gap without adding a new dependency. That three-question filter resolves the overwhelming majority of real deployment decisions without requiring a cryptography background to apply it.
Auditing an Existing Argon2 or scrypt Implementation
Most teams do not start this comparison from zero. They start from a production system someone else configured months or years ago, and the honest first step is checking whether that configuration still holds up. A short audit catches the gap before an incident does.
- Pull the exact algorithm, variant, and parameters currently stored for every hash format in the database, not just the one the team assumes is active.
- Compare those parameters against OWASP’s current Password Storage Cheat Sheet minimums for Argon2id or scrypt, and flag anything below the published floor.
- Confirm every hash uses a unique, randomly generated salt, and check the code path that generates it for predictable seeding.
- Verify the variant selection: Argon2d in a shared-hosting or multi-tenant environment is a finding worth fixing, not a style preference.
- Load-test the hashing endpoint at expected peak concurrency to confirm memory and CPU headroom actually exist under real traffic, not just on a developer’s laptop.
- Check whether parameters have been revisited since initial deployment, and set a recurring calendar reminder to reassess them, since hardware cost curves move even when nobody touches the code.
None of these steps require deep cryptanalysis expertise. They require reading the configuration that is already running, comparing it to a published standard, and treating a gap as a normal maintenance item rather than an emergency. Most password-hashing failures in production trace back to a parameter nobody revisited, not to a flaw in Argon2 or scrypt themselves.
Frequently Asked Questions
Is Argon2 always better than scrypt?
Not automatically. Argon2id needs less memory to hit OWASP’s target security level and carries the IETF and OWASP’s explicit first-choice recommendation, but a correctly parameterized scrypt deployment is not broken and does not need emergency replacement.
Why does Litecoin use scrypt instead of Argon2?
Charlie Lee chose scrypt for Litecoin in October 2011, four years before Argon2 existed. Argon2 was not an option at the time. It did not win the Password Hashing Competition until 2015.
What is the difference between Argon2i, Argon2d, and Argon2id?
Argon2d uses data-dependent memory addressing for strong GPU resistance but is vulnerable to cache-timing side channels on shared hardware. Argon2i uses data-independent addressing to avoid that risk. Argon2id combines both approaches and is the variant RFC 9106 requires every implementation to support.
How much memory should I allocate for Argon2id in production?
OWASP’s Password Storage Cheat Sheet lists a minimum of 19,456 KiB (about 19 MiB) at two iterations and one degree of parallelism, with a stronger alternative at about 46 MiB and one iteration. RFC 9106 also defines a high-security 2 GiB profile for systems that can afford it. Pick a setting your server’s concurrency and latency budget can sustain, then increase it as hardware allows.
Can I run Argon2 and scrypt hashes in the same user database?
Yes, and it is the standard migration pattern. Store which algorithm and parameters each hash uses, verify against the stored algorithm at login, then rehash with Argon2id and overwrite the record on a successful login.
Does Django support Argon2?
Yes. Django ships an Argon2 password hasher and documents installing the argon2-cffi package to enable it. Django also supports a scrypt-based hasher for teams that cannot add the Argon2 dependency.
Is scrypt still safe to use for new projects in 2026?
It has no known break as of September 2026 and remains standardized under RFC 7914. OWASP lists it as a fallback rather than a first recommendation mainly because it needs more memory than Argon2id to reach the same protection level, not because of a security flaw.
What should I use instead of MD5 or unsalted SHA-256 for passwords?
Neither MD5 nor SHA-256 is a password-hashing function. Both are deliberately fast general-purpose hashes, which is exactly the wrong property for password storage since it lets an attacker test billions of guesses per second. Use Argon2id, or scrypt if Argon2 is unavailable on your platform.
Does increasing Argon2 or scrypt parameters slow down my whole application?
Only the login and password-change code paths call the hashing function, so the rest of the application sees no change. The tradeoff lands entirely on those two operations, which is why measuring actual login latency and server memory headroom before raising parameters matters more than guessing at a “safe” number from another team’s blog post.




