{"id":26125983,"url":"https://github.com/powersync-ja/flutter-database-benchmarks","last_synced_at":"2025-04-13T16:11:13.943Z","repository":{"id":161544413,"uuid":"636236810","full_name":"powersync-ja/flutter-database-benchmarks","owner":"powersync-ja","description":"Benchmarks for SQLite, Isar and ObjectBox on Flutter","archived":false,"fork":false,"pushed_at":"2024-08-06T13:57:44.000Z","size":815,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-04-12T02:39:26.613Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/powersync-ja.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-05-04T12:03:12.000Z","updated_at":"2024-05-31T08:51:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"400522d5-8b07-46ad-afa8-fa0f4f2f3c22","html_url":"https://github.com/powersync-ja/flutter-database-benchmarks","commit_stats":null,"previous_names":["powersync-ja/flutter-database-benchmarks"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fflutter-database-benchmarks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fflutter-database-benchmarks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fflutter-database-benchmarks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fflutter-database-benchmarks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/powersync-ja","download_url":"https://codeload.github.com/powersync-ja/flutter-database-benchmarks/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741198,"owners_count":21154255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-10T17:27:29.262Z","updated_at":"2025-04-13T16:11:13.919Z","avatar_url":"https://github.com/powersync-ja.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Flutter Database Benchmarks\n\nA project to compare performance between various databases on Flutter.\n\nThe benchmarks are loosely based on old [SQLite benchmarks](https://www.sqlite.org/speed.html).\n\n## Test Notes\n\nSince the tests are based on ones from SQLite, the operations used may favor SQLite in some cases.\nFor example, copying data from one table to another (Test 11) is a native operation using a single query in SQLite,\nwhile this requires separately querying and inserting data in Isar and ObjectBox.\n\nOn specific tests:\n\nTest 1: This does individual inserts - no batching or transactions. This is not recommended for large volumes,\nbut does demonstrate the overhead per transaction.  The WAL journal mode on SQLite gives it an advantage on this test.\n\nTest 6: Not present, since it only creates indexes, which are avoided in these benchmarks.\n\nTest 7: This tests a \"between\" operation on an indexed column - `WHERE b \u003e= ? AND b \u003c ?`.\nThis is one test where ObjectBox does not perform as well as the others - it's possible that this operation\ndoes not currently use indexes in ObjectBox.\n\n## Benchmark Details\n\nSome differences from the SQLite benchmarks:\n1. Tables and indexes are pre-created, to better match typical usage, and to allow fair comparison\n   with databases that don't support dynamic tables and indexes.\n2. Tables have an explicit integer primary key \"id\", auto-populated by the respective databases. This is not directly used in the tests.\n3. Clear instead of drop tables.\n4. The exact queries may be different, but the outcome should be roughly the same.\n\nThe relative runtime is expected to roughly match the SQLite performance from above, but will be slightly\ndifferent because of the differences mentioned.\n\nFor the implementation, most benchmarks have two versions:\n1. The default \"obvious\" implementation. Focus on ease of implementation rather than performance.\n   * Only very simple performance optimizations are considered, for example combining writes into a single optimization.\n2. A \"batched\" implementation that aims to minimize the performance overhead of individual async operations.\n   * This may introduce some additional complexity to batch operations, but increases performance.\n   * Only performance optimizations readily available in the library's documentation or examples are considered.\n   * This is done by either using a batch API provided by the library, or running synchronous operations in a separate Isolate.\n\nOnly asynchronous/non-blocking APIs are used, unless the code runs in a background Isolate.\nSynchronous calls have the ability to block the UI / introduce stutter, so we believe it best to avoid them completely.\n\n## Benchmark limitations\n\n1. Does not measure UI performance during database operations yet. Despite the database operations being async, it may still\n   block the UI Isolate in some cases.\n2. Only a single run of each test is recorded.\n3. No UI yet - all results are logged to the console.\n4. Does not test concurrent operations.\n\n## Database-specific notes\n\nNotes on implementations:\n\n### sqlite_async\n\nOnly async operations are directly supported.\n\nUses WAL journal mode (library default). `PRAGMA wal_checkpoint(RESTART)` is run at the end of\nevery test, to better allocate write time to the relevant test.\n\nBatched mode: Uses prepared statements internally.\n\n### Sqflite\n\nUses DELETE journal mode (library default).\n\n[sqflite_ffi](https://github.com/tekartik/sqflite/blob/master/sqflite_common_ffi/doc/using_ffi_instead_of_sqflite.md) is used for all tests.\nThis has much better performance than the default implementation, and is a simple change.\n\n### Isar\n\nRuns in \"relaxed durability\" mode. According to the docs:\n\n\u003e relaxedDurability\tRelaxes the durability guarantee to increase write performance. In case of a system crash (not app crash), it is possible to lose the last committed transaction. Corruption is not possible.\n\nThis makes it the same guarantees as SQLite in WAL mode with `synchronous = NORMAL`, as used for sqlite_async.\n\n### ObjectBox\n\nObjectBox does support async operations from version 2.0, but not in a transaction.\n\nFor async transactions, everything in the transaction must run in a separate isolate.\nIt doesn't cause any issues in these benchmarks, but would potentially complicate code in real-world applications.\n\nSince there is no way to run an async transaction without running in a separate Isolate, only one implementation is provided.\n\n## Acknowledgements\n\n * Some portions inspired by another Flutter database benchmarks project: https://github.com/o-ifeanyi/db_benchmarks\n * Implementation of the SQLite tests are adapted from the benchmarks in https://github.com/rhashimoto/wa-sqlite\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpowersync-ja%2Fflutter-database-benchmarks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpowersync-ja%2Fflutter-database-benchmarks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpowersync-ja%2Fflutter-database-benchmarks/lists"}