First encrypted Room database unlock is up to ~4x slower after upgrading Room 2.5.2 → 2.8.4 and sqlcipher-android 4.11.0 → 4.17.0
Summary
After upgrading Room from 2.5.2 to 2.8.4 and net.zetetic:sqlcipher-android from 4.11.0 to 4.17.0, opening existing encrypted Room databases became up to approximately four times slower during application startup.
The slowdown is concentrated in the first SQL statement executed after SQLiteDatabaseHook.postKey(). Queries issued after the connection is fully open do not show the same regression.
Environment
- Platform: Android
- Database integration: Room with a SQLCipher-backed
SupportSQLiteOpenHelper.Factory
- Database type: existing SQLCipher-encrypted Room databases
- Journal mode: WAL
- Password, database files, device and build configuration: unchanged between measurements
- Device /RMX6688
Dependency change
| Configuration |
Room |
sqlcipher-android |
Observed first-unlock cost |
| Before |
2.5.2 |
4.14.0 |
Baseline |
| After |
2.8.4 |
4.17.0 |
Up to approximately 4x slower |
Additional controlled measurements
We also held Room at 2.8.4 and compared sqlcipher-android 4.11.0 with 4.17.0 on the same test setup. This independently shows a substantial regression on the SQLCipher version axis:
| Room |
sqlcipher-android |
Samples |
Mean |
Median |
P90 |
Min–max |
| 2.8.4 |
4.11.0 |
80 |
529.46 ms |
494.30 ms |
809.51 ms |
197.19–1,011.59 ms |
| 2.8.4 |
4.17.0 |
137 |
1,588.07 ms |
1,314.43 ms |
2,919.85 ms |
654.63–3,519.30 ms |
The 4.17.0 result is:
3.00x higher by mean;
2.66x higher by median;
3.61x higher at P90.
Representative log entries:
# Room 2.8.4 + sqlcipher-android 4.17.0
SQLCipher key derivation and verification cost: 2775.801539ms
SQLCipher key derivation and verification cost: 3244.882154ms
SQLCipher key derivation and verification cost: 3519.295308ms
# Room 2.8.4 + sqlcipher-android 4.11.0
SQLCipher key derivation and verification cost: 346.516385ms
SQLCipher key derivation and verification cost: 478.817230ms
SQLCipher key derivation and verification cost: 562.362538ms
Instrumentation
The measurements were collected with the following SQLiteDatabaseHook:
internal class SqlCipherDebugLogHook private constructor(
private val delegate: SQLiteDatabaseHook?,
) : SQLiteDatabaseHook {
override fun preKey(connection: SQLiteConnection) {
delegate?.preKey(connection)
}
override fun postKey(connection: SQLiteConnection) {
delegate?.postKey(connection)
val startNs = System.nanoTime()
runCatching {
connection.executeForLong(
"SELECT COUNT(*) FROM sqlite_schema;",
null,
null,
)
}.onSuccess {
val elapsedMs = (System.nanoTime() - startNs) / 1_000_000.0
logd(TAG, "SQLCipher key derivation and verification cost: ${elapsedMs}ms")
}
}
}
SQLCipher performs key derivation lazily. Therefore, the measured interval is not the duration of the postKey() callback itself and should not be interpreted as isolated PBKDF time. It measures the first schema query after postKey(), which forces lazy KDF, first-page decryption, and key verification. The trivial COUNT(*) query overhead is also included.
Steps to reproduce
- Create an encrypted Room database, then close it or kill the application process.
- Configure Room with a SQLCipher-backed
SupportSQLiteOpenHelper.Factory and WAL.
- Install a
SQLiteDatabaseHook that runs and times SELECT COUNT(*) FROM sqlite_schema; in postKey().
- Open the existing database during application startup.
- Record the first-query duration logged by the hook.
- Repeat across fresh process starts using the same device, database, passphrase, and build configuration.
- Compare the old and new dependency combinations.
Expected behavior
First unlock/open performance should remain close to the earlier version when the database, passphrase, cipher settings, device, and build configuration are unchanged.
Actual behavior
The first SQL statement that forces key derivation and verification is substantially slower on sqlcipher-android 4.17.0. The original joint Room/SQLCipher upgrade showed an increase of up to approximately 4x; the controlled Room 2.8.4 measurements show a 3.00x mean and 3.61x P90 increase from SQLCipher 4.11.0 to 4.17.0.
Isolation matrix
The following matrix would separate the Room and SQLCipher effects for the exact versions in the original report:
| Room |
sqlcipher-android |
Status |
| 2.8.4 |
4.11.0 |
Measured: mean 529.46 ms, P90 809.51 ms |
| 2.8.4 |
4.17.0 |
Measured: mean 1,588.07 ms, P90 2,919.85 ms |
Questions
- Were there changes between
sqlcipher-android 4.11.0 and 4.17.0 that could increase lazy KDF, first-page decryption, or key verification time for an existing database?
- Did any default cipher, KDF, compatibility, or native build settings change across these versions?
- Could
4.17.0 derive or verify the key more than once when Room opens multiple WAL connections?
- Is timing the first trivial schema query from
postKey() a valid way to compare SQLCipher first-unlock cost across versions?
- Which safe diagnostics or PRAGMA values would help isolate the increase without exposing the database key?
First encrypted Room database unlock is up to ~4x slower after upgrading Room 2.5.2 → 2.8.4 and sqlcipher-android 4.11.0 → 4.17.0
Summary
After upgrading Room from
2.5.2to2.8.4andnet.zetetic:sqlcipher-androidfrom4.11.0to4.17.0, opening existing encrypted Room databases became up to approximately four times slower during application startup.The slowdown is concentrated in the first SQL statement executed after
SQLiteDatabaseHook.postKey(). Queries issued after the connection is fully open do not show the same regression.Environment
SupportSQLiteOpenHelper.FactoryDependency change
4xslowerAdditional controlled measurements
We also held Room at
2.8.4and comparedsqlcipher-android4.11.0with4.17.0on the same test setup. This independently shows a substantial regression on the SQLCipher version axis:The
4.17.0result is:3.00xhigher by mean;2.66xhigher by median;3.61xhigher at P90.Representative log entries:
Instrumentation
The measurements were collected with the following
SQLiteDatabaseHook:SQLCipher performs key derivation lazily. Therefore, the measured interval is not the duration of the
postKey()callback itself and should not be interpreted as isolated PBKDF time. It measures the first schema query afterpostKey(), which forces lazy KDF, first-page decryption, and key verification. The trivialCOUNT(*)query overhead is also included.Steps to reproduce
SupportSQLiteOpenHelper.Factoryand WAL.SQLiteDatabaseHookthat runs and timesSELECT COUNT(*) FROM sqlite_schema;inpostKey().Expected behavior
First unlock/open performance should remain close to the earlier version when the database, passphrase, cipher settings, device, and build configuration are unchanged.
Actual behavior
The first SQL statement that forces key derivation and verification is substantially slower on
sqlcipher-android4.17.0. The original joint Room/SQLCipher upgrade showed an increase of up to approximately4x; the controlled Room2.8.4measurements show a3.00xmean and3.61xP90 increase from SQLCipher4.11.0to4.17.0.Isolation matrix
The following matrix would separate the Room and SQLCipher effects for the exact versions in the original report:
Questions
sqlcipher-android4.11.0and4.17.0that could increase lazy KDF, first-page decryption, or key verification time for an existing database?4.17.0derive or verify the key more than once when Room opens multiple WAL connections?postKey()a valid way to compare SQLCipher first-unlock cost across versions?