gxhash: a fast non-cryptographic hash with no fallback path
Unsafely fast hashing algorithm 📈
At a glance
- What is it?
- GxHash is a Rust hashing algorithm built on hardware AES instructions, SIMD intrinsics and instruction level parallelism, with no cargo dependencies at all. The trade it makes is explicit: it requires AES-NI or ARM AES and NEON, it has no fallback for other platforms, it contains unsafe code, and the README says plainly that it is not intended for safety critical applications.
- Who is it for?
- Adopt gxhash if you have a workload where hashing dominates the profile, on x86 with AES-NI or ARM with AES and NEON, and if you can live with a hash that is explicitly not cryptographic and is not intended for safety critical use. Do not adopt it if your build must run on a CPU without hardware AES, because the crate will not compile there, and do not adopt it to replace a keyed hash where denial of service resistance matters.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 25 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
AES instructions as the mixing function
GxHash is described as a non-cryptographic hashing algorithm, and the README's two headline claims are about speed and robustness.
The robustness comes from the mechanism rather than from a clever design. GxHash uses several rounds of hardware-accelerated AES block cipher for efficient bit mixing. The consequence is that the bit mixing is close to free on a CPU that has AES instructions, and the README reports that GxHash passes all SMHasher tests, which it calls the de facto quality benchmark for non-cryptographic hash functions, gathering most of the existing algorithms. It also reports low collisions, uniform distribution and high avalanche properties. There is a paper linked for the technical details, in the gxhash-rust repository.
The speed comes from three things the README names. Heavy usage of SIMD intrinsics, a high ILP construction where the instructions in the critical path are independent so the processor can overlap them, and a small bytecode, described as easily inlined and cached. And then there is the fourth item, described as some outrageously unsafe tricks, with a link to an article called unsafe read beyond of death.
That last item is not incidental. The README is direct about it. In order to achieve this magnitude of performance, the crate contains unsafe code as well as a rather aggressive optimization technique, and for this reason the crate is not intended for use in safety-critical applications, but rather for applications that require extreme hashing performance and that are less concerned about this aspect.
The dependency story is clean. GxHash has 0 cargo dependencies, and the Hasher and HashSet/HashMap convenience types require the standard library, enabled by default with the std feature. The only runtime dependency in the manifest is rustversion 1.0, which is there for compile-time cfg based on the rustc version.
The package is MIT licensed, authored by Olivier Giniaux, at version 4.0.0 with edition 2021, and the last push was on 2026-09-28.
No fallback: the crate will not build without AES
The hardware acceleration section is the one to read before anything else, because the requirement is absolute.
GxHash requires a few specific hardware acceleration features, which are supported on most modern processors but not all of them. For x86 processors, that means the AES-NI and SSE2 intrinsics, and for ARM processors, the AES and NEON intrinsics. Then the warning: other platforms are currently not supported, there is no fallback, and GxHash will not build on these platforms.
There is no software path and no portable path. A crate that will not compile on a given CPU is a different proposition from one that compiles slowly, and the difference shows up at the worst possible moment, when somebody tries to build your service on a platform you did not test.
The failure is at least legible. If you build gxhash without the required features, the crate fails to build with an error message like this, even if you know your target supports the required features:
Gxhash requires aes and sse2 intrinsics. Make sure the processor supports it and build with RUSTFLAGS="-C target-cpu=native" or RUSTFLAGS="-C target-feature=+aes,+sse2"The fix is to follow the instructions in the error, and the README says that setting RUSTFLAGS to -C target-cpu=native should work if your CPU is properly recognized by rustc, which is the case most of the time.
That is a real operational detail rather than a footnote. The cross_compile workflow in the repository, and the rust_version workflow that checks compatibility, both exist because this kind of crate has to be built and tested on several targets, and the RUSTFLAGS have to be set per target rather than once in a config file. The Cargo.toml lists the categories as algorithms, data-structures and no-std, and the keywords include no-std, so a no_std build for an embedded target is an intended use, which means the AES requirement has to be satisfied on the target device as well.
Stable hashes per major version, and a deliberate inconsistency
Two properties of the hash values matter to anyone storing them or comparing them across systems.
The first is stability. All generated hashes for a given major version of GxHash are stable, meaning that for a given input the output hash will be the same across all supported platforms. The second half of the statement is the one to plan around: the hash may change between major versions, with the example given being gxhash 3.x and 4.x.
So a hash written into a database, a file name, a partition key or a cache key on disk is tied to a major version, and a major version upgrade is a data migration. The current version in the manifest is 4.0.0, so the boundary to be careful of is 4.x to 5.x.
The second property is a documented inconsistency inside the crate. The Hasher trait defines methods to hash specific types, and this allows the implementation to circumvent some of the tricks used when the size is unknown. For this reason, hashing four u32 using a Hasher will return a different hash compared to using the gxhash128 method directly with those same four u32 represented as sixteen u8.
The rationale given is that the Hasher, which is mostly used for things like HashMap or HashSet, and gxhash128 are used in two different scenarios, and both ways are independently stable.
That is a reasonable design, and it is also a trap for a reader who assumes one function is interchangeable with another. If you hash a value by hand with gxhash128 and also put it in a HashMap built on the Hasher, the two hashes are not comparable, and nothing in the types will stop you from comparing them.
Seeded for DoS resistance, and not a cryptographic hash
The security section of the README is short and it is careful, and it separates two different things that the word secure tends to blur.
GxHash is seeded, with seed randomization, to improve DoS resistance, and it uses a wide, 128-bit internal state to improve multicollision resistance. But such resistances are just basic safeguards and do not make GxHash secure against all attacks.
For use cases that require deterministic repeatability, you can disable random seeding with the feature called deterministic, but this of course disables DoS mitigation. That trade is stated plainly, and it is the trade every hash function that seeds from a random source makes: you get unpredictability against an attacker who floods your map with chosen keys, at the cost of the same input hashing differently in different processes.
And then the sentence that settles the scope: GxHash is not a cryptographic hash function and should not be used for cryptographic purposes.
The library's own metadata is consistent with that. The keywords include hash, hasher, hashmap, no-std and crypto, and the categories are algorithms, data-structures and no-std. The crypto keyword is the only place where the word appears, and it is there because the algorithm uses the AES block cipher as a mixing primitive, not because it is a cryptographic construction.
The mechanism is worth understanding on its own. Using an AES round as the mixing function is why the algorithm can claim strong avalanche and low collision rates at high speed: the diffusion properties of AES are already well studied, and the hardware does it in a few cycles. What that buys is a good distribution for hash tables, and what it does not buy is any of the properties you would need from a hash that an adversary cannot predict.
The hybrid feature and the rest of the flags
The flags section is small, and each flag does one thing.
The std feature flag enables the HashMap and HashSet container convenience type aliases, and it is on by default. To make the crate no_std you disable it:
[dependencies.gxhash]
...
default-features = falseThe hybrid feature flag enables a hybrid implementation of GxHash. It is disabled by default. When it is enabled and for CPUs that support it, GxHash will use wider registers and instructions, VAES and AVX2, which can lead to a throughput increase for large inputs. The important property is that this preserves hash stability, meaning that hashes generated with or without the hybrid feature are the same for a given input and seed.
That last point is the reason the feature is safe to experiment with. A performance optimisation that changes the output would be a trap, because every stored hash would have to be recomputed. Here the output is invariant and only the instruction selection changes.
The advice attached to it is sensible as well. It says that even without the feature enabled GxHash is already the fastest option out there, and recommends enabling it only when inputs can be larger than a few hundred bytes, and to make sure to run benchmarks in your own context.
The remaining flags are for the benchmark harness rather than for users. bench-csv, bench-md and bench-plot add output formats, and the manifest lists six benchmark targets: throughput, throughput_criterion, ilp, hashset, quality and read_beyond. The last one is named after the unsafe optimisation, and the ilp one after the instruction level parallelism construction, so the benchmark suite is testing the specific claims the README makes.
Benchmark it in your own context
The benchmark section is the most useful part of the README for anybody deciding whether to adopt this, and it is mostly a warning.
GxHash is continuously benchmarked on x86 and ARM GitHub runners, and the important note says that if performance is a critical feature for your application, you should not forget to benchmark the cost of hashing in your own context, because numbers shared here may be radically different in your environment and with your hardware.
The same caution appears on the hybrid feature, and it is echoed by the way the benchmark suite is built. The dev dependencies list every other hash function worth comparing against, ahash, t1ha, twox-hash, highway, seahash, metrohash, fnv, foldhash and rustc-hash, and the benchmarks run against all of them on the same harness, with criterion 0.5.1 and plotters for the plots. The bench targets are wired up explicitly with harness = false, which is what criterion requires.
To run them yourself:
# Benchmark throughput
# Add --features bench-md for markdown output or --features bench-plot for .svg plots
cargo bench --bench throughputTwo more things in the repository support the same point. There is an article/ directory, which the manifest excludes from the published package, and which holds the paper. And there is an ffi/ directory, which is not mentioned in the README at all, so what it contains is a question the documentation does not answer.
The last push was on 2026-09-28 and the package version is 4.0.0. There are no GitHub releases, so the version in the manifest is the record of what has shipped.
Editorial conclusion
Adopt gxhash if you have a workload where hashing dominates the profile, on x86 with AES-NI or ARM with AES and NEON, and if you can live with a hash that is explicitly not cryptographic and is not intended for safety critical use. Do not adopt it if your build must run on a CPU without hardware AES, because the crate will not compile there, and do not adopt it to replace a keyed hash where denial of service resistance matters. Verify first that the hash values you persist are re-derived rather than stored, since the output may change between major versions, and that your own benchmarks confirm the gain in your context, which the README asks you to do.
Frequently asked questions
What hardware does gxhash require?
X86 processors with the AES-NI and SSE2 intrinsics, and ARM processors with the AES and NEON intrinsics. The README warns that other platforms are currently not supported, that there is no fallback, and that GxHash will not build on them, with an error suggesting RUSTFLAGS="-C target-cpu=native".
Is gxhash safe to use for cryptographic purposes?
No. The README states that GxHash is not a cryptographic hash function and should not be used for cryptographic purposes. It is seeded with seed randomization to improve DoS resistance and uses a 128-bit internal state for multicollision resistance, but the README says these are just basic safeguards.
Are gxhash hash values stable across versions and platforms?
For a given major version the hashes are stable, and the output for a given input is the same across all supported platforms. The hash may change between major versions, with 3.x and 4.x given as the example, so a stored hash is tied to the major version it was produced by.
Why does hashing the same bytes give different results through Hasher and gxhash128?
The Hasher trait defines methods to hash specific types, which allows the implementation to circumvent some of the tricks used when the size is unknown. The README notes that hashing four u32 through a Hasher returns a different hash than gxhash128 on the same four u32 represented as sixteen u8, and that both ways are independently stable.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ogxd-gxhash)Was this useful?