ENGINEERING NOTE
Jump consistent hashing: from text to a repeatable bucket
Follow the JUMPHASH demo from UTF-8 text through FNV-1a to a bucket, with exact examples and practical limits.
A small, testable promise
The homepage demonstration takes a text key and selects one of 96 numbered buckets. Entering the same text again produces the same bucket because the byte encoding, arithmetic and bucket count stay fixed. This is a narrow, observable example of determinism; it says nothing about the reliability of a network or the correctness of an entire application.
John Lamping and Eric Veach introduced jump consistent hash in their 2014 paper. JUMPHASH is the company name; the algorithm is the authors’ work. Our demonstration combines a text hash with an integer implementation of their bucket-selection approach.
Keep the two steps separate
First, TextEncoder turns the text into UTF-8 bytes. FNV-1a starts at the 64-bit offset basis, XORs each byte into the current value, multiplies by its prime and masks the result to 64 bits. Second, jumpHash takes that integer and the bucket count. It advances candidate bucket positions until the next candidate would be outside the range.
The implementation uses JavaScript BigInt for integer arithmetic. The mask makes the intended 64-bit wraparound explicit; integer division discards the fractional part. The bucket number is converted to Number only at the end.
const key = fnv1a64("jumphash");
hexOf(key); // 0x7EC173F1A74C4759
jumpHash(key, 96); // 90
jumpHash(key, 1024); // 975Examples you can reproduce
The displayed bucket is zero-based: 90/96 means bucket 90 in the range 0 through 95. These examples are checks of our implementation, not a statistical benchmark.
| Input text | Bucket count | Expected bucket |
|---|---|---|
| jumphash | 96 | 90 |
| jumphash | 1024 | 975 |
| berza | 96 | 77 |
| krov | 96 | 50 |
The interface also has a contract
An empty input in the homepage demo uses the example word jumphash. That is a user-interface choice, not a property of FNV-1a or jump consistent hash. The demo also limits entered text to 64 JavaScript string units and makes truncation visible.
Text that looks the same can have different Unicode encodings. This example does not normalize Unicode, change case or remove whitespace. Systems that need those transformations should define them before hashing and test the exact bytes that every consumer uses.
Where the guarantee stops
The original algorithm expects sequential bucket numbers. Arbitrarily removing a named server is a different membership problem; do not substitute a bucket-count change for a complete storage or routing design.
FNV is non-cryptographic. Neither a bucket nor an FNV digest is an authentication token, a secret, a proof of identity or a privacy-preserving identifier. Different inputs can share a bucket, and digest collisions are possible. The demonstration does not test load balance, collision resistance, membership recovery or application throughput.
Before using this code elsewhere, validate positive integer bucket counts, define encoding and normalization, compare expected vectors across languages, and test the application’s actual membership changes. The homepage keeps its count fixed at 96.