-
Notifications
You must be signed in to change notification settings - Fork 27
Performance issues after updating to sqlcipher-android from android-database-sqlcipher #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @eygraber, It appears your application is opening many connections to the same, or different databases. The log statement for keying operation returning Do you have a large number of database files you maintain connections to? If you only have a single database, it would be good to review why the application appears to open the connection repeatedly. |
I only have one database file and access to it is managed by a singleton that opens the connection when it is instantiated. There is a 3rd party layer in between that I'm investigating. Is the design of sqlcipher-android different than android-database-sqlcipher in this regard? Because there's no performance issue with the same code using android-database-sqlcipher. |
Hi @eygraber, Yes,
|
That sounds like it may be it. I'm using WAL and when the app starts it makes a bunch of parallel API calls and writes their responses to the db. Is there any way to configure the pooling so I can test if that's the issue? |
Hi @eygraber, The connection pool isn't configurable currently. Can you try disabling WAL mode to see if your performance behavior changes? |
Yes disabling WAL resolves the performance issues. I still see |
Hi @eygraber, Do you have a small example where that is occurring with a single connection and WAL mode disabled? The connection pool does distinguish between a primary and non-primary connection based on the connection flags. |
I'm sorry I don't. This is a pretty large app that I can't share. I'll see if I can get it to happen in a repro project. |
Hi @developernotes, I'm also facing this issue after migrating to sqlcipher. Any suggestions to resolve the issue unblock us. Please check this android example where I've implementated sqlcipher and observing JNI issue. Logs from this sample: 2024-04-17 17:51:33.993 9710-9710 SQLiteConnection com.ex.myapplication I Database keying operation returned:0 |
Hey @developernotes after migrating to sqlcipher-android I can clearly see that, it is taking much time to return result. Steps -
|
Hi @EpariNigam, I believe what you are seeing can be attributed to key derivation within your sample. If you adjust your
|
Hey @developernotes Is there no other solution, other than this? Is it like on new library the key derivation is slower compared to old library or was there no key derivation technique used in old library? |
@EpariNigam The number of key derivation rounds was increased in SQLCipher 4 by a factor of 4x. This was to increase security against brute force and dictionary attacks. You have a couple options:
Regardless, before doing either of those, you should review the general performance optimization guidelines for your application. If you are adhering to the guidelines and using long running connections the impact of key derivation should be very minimal, since it only happens once per connection. |
@EpariNigam disregard my earlier comment. It was directed more at general performance of key derivation, which I now recognize is different than the issue you're facing. We can take a look at this a bit closer, however, I cannot provide a time frame for an update at the moment. |
Hey @sjlombardo, Thanks for your reply. Will look forward on further insights on this. |
Hey @developernotes @sjlombardo, Any update on this? |
Hey @sjlombardo @developernotes any update on this? |
Hey @sjlombardo @developernotes any update on this, still waiting to migrate our app to latest version. It is blocking us for android 15 compatible as well. |
Hello @EpariNigam we're still investigating this. We'll provide an update once we have additional information. |
Hello @EpariNigam - after reviewing your reference project, we have determined that the library is working as expected. When using the default configuration with WAL mode, at least 2 connections will be established in the connection pool. This involves performing key derivation more than once, which increases the time required to execute the first connection. On the other hand, this can substantially increase performance for concurrent database access. If you want to disable pooling, you can turn off WAL mode, which should make first-execution performance about equivalent to the previous library. You can do this by calling
That will restrict the library to using a single connection. The other options would be to adjust key derivation so it takes less time, or perhaps try out the official Commercial Edition packages which have an optimized cryptographic library and may offer better performance. |
@sjlombardo would it be possible to make the pool configurable to help address this? Start up time is a critical metric for Android apps, and this is a real killer. |
@eygraber It is something we could look into it. That said, what would you envision configuring on the pool, just the max connections? It's worth noting that adjusting the max connections on the pool would not impact the startup time for the example just posted. |
I imagine it would help for my original issue though, right? |
Right @sjlombardo it might not help. But, giving an option to set pool count would be helpful. |
I'm facing the same issue. I'm migrating from the old library, net.zetetic:android-database-sqlcipher:4.5.4. In my case, the performance drop is abysmal when using net.zetetic:sqlcipher-android:4.6.1. I'm using a SQLiteOpenHelper subclass. Disabling WAL mode in the constructor did not help. My class has methods that use this format (all of them):
One thing I've noticed, is that if I do not close the database in those methods, performance is back to normal. I suppose that getReadableDatabase() is reusing the instance in multiple calls. If not, there might be a problem in the close() method. |
Hi @jcrabanal, You typically do not want to close the database connection returned from either |
Hi, I've removed the close() method calls on my SQLiteOpenHelper subclasses. Several stackoverflow posts say that it should not be necessary, but the reason it is there is because I'm worried about database corruption, if the process goes away with db connections not closed. Do you have any info on this? Is this also true for regular SQLiteDatabase.open() calls? Is closing the database necessary there? |
Hello @jcrabanal, It is desirable to leave the connection open for the lifetime of the application, if possible. This is to prevent repeated key derivation from occurring. You should close the connection when the application is exiting. SQLite has documented various ways a database can become corrupt 1. Footnotes |
Hey @developernotes and @sjlombardo, Can you share an example on how to reduce key derivation on Android, especially using room? |
@EpariNigam See this section of the performance optimization guide: https://www.zetetic.net/sqlcipher/performance/#adjust-key-derivation |
@sjlombardo That I understood, but when to execute that is the question using Room database? |
@EpariNigam - To adjust KDF iterations, use a
To use a Raw Key you just need to format it properly. |
@eygraber - the next release will allow you to modify the pool size for use with WAL mode. |
Hey I noticed that this thread is used often for performance issues related to updating the different libraries. I am seeing the same kind of issues here. We upgraded to the new library and found similar performance issues. Specifically on older Android API version devices. We basically were getting app starts that are over the 5 second threshold for cold starts. So we had an engineer with Android 10 test out some numbers. Might be useful So it appears its known that the non WAL mode is known to be slower on app start but the thought is its faster after that. Is there a way we can get documentation and measurement towards this? Then also set an appropriate default based on that. Like just updating to WAL seems to put old API versions at risk of being super slow start which might not be what you set as the default until the WAL configuration is figured out on how to improve app start time. Let me know what you are thinking. In the mean time disabling WAL is what we are doing. |
Should we add this WAL disabling to the performance considerations? It seems like if we use a random hash we also do not need the key derivation too right? |
Hi @DavidCorrado, We are considering some changes for the next release of SQLCipher which would adjust the default connection handling behavior within SQLCipher for Android along with support for adjusting the connection pool size. In addition, we plan to include some documentation updates to the SQLCipher performance guidance to further clarify the needs when using the Room API in conjunction with SQLCipher. |
Hey @sjlombardo I tested, I can see some improvements. But it is not working for existing databases, how to handle them? |
You would need to use https://www.zetetic.net/sqlcipher/sqlcipher-api/#sqlcipher_export This is an advanced operation that is outside the realm of standard public support. The operations are all documented, but this is not something we would provide step-by-step support for on this ticket. |
Hi @DavidCorrado,
If you provide a raw key 1, key derivation will not occur. Footnotes |
Hey @developernotes any timeline for setting number of DB connections? |
Hi @EpariNigam, Changes will be included in the next public release of SQLCipher. We do not have a date to share at this time, however, we will post on our blog as well as the SQLCipher Discuss site upon release. |
The recent release of SQLCipher 4.7.0 includes changes to the default connection handling behavior within SQLCipher for Android which should improve initial performance. You can also adjust connection pool size via |
I updated my app from android-database-sqlcipher 4.5.4 to sqlcipher-android 4.5.5 (I also tried sqlcipher-android 4.5.4 and have the same issue).
When my app starts I make a few network calls and store the responses in the db. After the update to sqlcipher-android the startup performance of my app is absolutely trashed. It takes multiple seconds for my UI to render. I see the following in the logs:
This only seems to happen on a cold app open, and happens on both debug and release builds.
I'm trying to profile the build to see what's going on, but Android Studio isn't cooperating at the moment.
The text was updated successfully, but these errors were encountered: