[erlang-questions] Scaling bcrypt

Richard Jonas richard.jonas@REDACTED
Wed Jul 6 09:45:44 CEST 2016

Hey guys,

last time I wrote about some problems how bcrypt (at least current erlang
bcrypt implementations) cannot be scale. The original problem what that
bcrypt driver (github chef/erlang-bcrypt) is using port and nif
implementation. The nif implementation behind the scenes it uses a
gen_server which serializes all the requests are coming. The port
implementation uses a port pool which can be configured.

Our problem comes from the fact that a good hashing algorithm should be
slow by design. bcrypt uses a round parameter (3-16) with which one can say
that bcrypt should use 2^(3-16) cycles during computing. According to
security guidelines a good hashing algorithm should take 0.1-0.5 seconds to
be computed, so now bcrypt should run with round 10-12 depending on the
hardware. It needs to be slow in order that one cannot find a
hash-collision easily.

Now you can imagine the problem. With load tests we easily made message
queues and the problem is that the computing has sometimes very very big
latencies (50-60 seconds depending on the number of concurrent users). The
nif implementation spoils one scheduler thread but if I have 32 cores I
cannot scale the computing.

The problem I wanted to solve is to split the bcrypt_hashpw nif into 3
parts: initialization, computing some predefined number of rounds,
encryption. I used enif_schedule_nif to schedule the computing of the next


The implementation is based on chef/erlang-bcrypt and vinoski/bitwise. The
first loadtests are promising since latencies are much more even. With 10
concurrent users (basho bench + bcrypt driver) the latency was (500ms
1100ms / mean median), with 50 users (2800ms ~6000ms) which 5x increase,
let us say.

My questions are:
- how can I measure if my nif "slices" took no longer than 1ms
- how can I implement some kind of adaptive computing? My bcrypt_compute
computes 64 rounds which sometimes below 1ms, sometimes above 1ms.


If I use some kernel gettime function, can it cause blocking?

- how can I be sure that no garbage left in memory. I try to watch out
putting release functions in correct places but it would be good to measure.


Richard Jonas
Erlang Solutions Hungary Kft

  Riverpark Office K.32
  Közraktár street 32. 3/1.
  1093 Budapest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160706/e809b70c/attachment.htm>

More information about the erlang-questions mailing list