Balancing CPU cost when using BCrypt
You need to take care when setting the cost parameter for BCrypt. Brute-force cracking of passwords becomes harder when the cost parameter is higher. Unfortunately it also makes checking passwords more expensive.
When choosing a cost parameter for your code, you need to realize how it impacts performance. This is directly related to how often you verify the password. Broadly speaking there are two situations:
Password is only checked when creating the authenticated session
A lot of authentication systems give you an authentication token in exchange for valid authentication credentials. The token is either stored in a cookie for further requests or it's returned for use in API access.
In this situation you can use a relatively high cost because the password only needs to be checked during authentication and possibly when changing the password. This is likely to only happen once every 100 requests.
Password is checked with every request
Some authentication systems need the user's credentials with every request (i.e. HTTP Basic Authentication). In this case the password is verified in every request. You will need to determine how much of a performance penalty you're willing to take with every request.
A workaround could be to cache the password value to speed up this check.
Benchmark!
Whatever you come up with, always benchmark your solution. You should start by getting an idea about how long it takes to create a crypted password on your production server. Add that to the current response time for an authentication request and figure out how far you're willing to go.
In this example 10 is probably a bit too high and 5 is too low. 7 is around 32 milliseconds, a penalty I'm willing to take when creating a session.
Slowing down test suites
Using a high cost parameter can be acceptable for your super-duper fast production servers, but it can definitely slow down your test suite. A solution is to configure the cost differently for various environments: 7
for production, 1
for development and test.
Some pitfalls
Note that the cost needs to be configured globally because you use the same cost parameter when creating and verifying the crypted password.
Computers become faster so to stay safe you will need to set higher costs in the future. To ease this transition you can decide to store the cost with the password so you can change the default in the future without breaking older crypted passwords.