(updated)
|
min. read

How Fast Is PowerSync? Performance Benchmarks For Flutter

Ralf Kistner

Performance is critical for developers building modern, data-intensive applications. This post looks at performance benchmarks of our Flutter Client SDK, focusing on two key metrics: initial sync time and incremental sync latency.

These benchmarks are designed to help developers assess PowerSync’s client-side performance across different types of devices and client environments.

Where Performance Matters in Sync

When implementing a sync engine with a client-server architecture, two important performance metrics stand out:

  1. Initial Sync Time: How quickly can a user start interacting with their data after logging in? 
  2. Incremental Sync Latency: How quickly are changes propagated to devices via the server?

We benchmarked the PowerSync Flutter SDK on these dimensions to provide transparency into its performance across desktop, mobile, and web environments.

Benchmark Setup: Testing for Real-World Relevance

Our tests aim to isolate client-side performance while minimizing server-side variability. Here’s how we set up the benchmarks:

  • Client ↔ Server Latency and Server-Side Overhead: Minimized by running the server stack locally.
  • Data Volume: Benchmarked with datasets ranging from 10,000 to 10 million rows.
  • Devices Tested:
    • Linux Desktop (Ryzen 9 7900X, ext4 filesystem)
    • Android (Pixel 8a, Android 14)
    • Web (Flutter web with IndexedDB and OPFS storage)

Note: iOS benchmark tests are not yet available but will be included in an upcoming update to this post.

The metrics represent the mean of 10 test runs.

Key Metrics

1. Initial Sync Time

Initial sync time measures the duration from when the sync connection opens to when all data is available locally. This is crucial for ensuring fast app load times, especially for users syncing large datasets.

  • Desktop: Up to 27.6k rows/sec
  • Mobile: Slower throughput, averaging 7.1k rows/sec on Android for 10k rows synced.
  • Web: Performance varies significantly based on storage backends, with OPFS outperforming IndexedDB.

Note: Throughput decreases slightly as more rows are synced. See the table at the end of this post for the full dataset.

Click to enlarge

2. Incremental Sync Latency

Incremental sync latency tracks the round-trip time for updates to propagate through the system:

  • Client creates a new record in its local database.
  • Record is uploaded to the server, persisted in the backend database (Postgres in the case of these benchmarks) and the change is processed by PowerSync.
  • Record is streamed back to the client. We include a default value for one of the columns populated by Postgres, which allows the client to detect that the roundtrip has completed and measure the latency.

We tested 1 update, 100 updates and 1,000 updates. For the 100 and 1,000 cases, the updates are uploaded as a single batch API call and persisted to Postgres using a single transaction.

The benchmarks showed that incremental syncing is quite fast. On Android, syncing 100 updates takes ~200ms for the full round-trip. On desktop, it’s even faster, clocking in at ~40ms.

Note: As app queries run locally, user interactions have zero network latency: the UI instantly updates, in the next frame.

Summarized Benchmark Results

Client Rows Synced Initial Sync Time Throughput Incremental Sync Latency (100 updates)

Flutter, Linux desktop

100k

4.2s

23.8k/s

39.7ms

Flutter, Android

100k

21.8s

4.6k/s

229.0ms

Flutter-Web (IndexedDB)

100k

17.8s

5.6k/s

146ms (100-200ms)

Flutter-Web (OPFS)

100k

10.4s

9.6k/s

121ms (110-130ms)

For the complete dataset, see the table at the end of this post.

Insights from the Benchmarks

Initial Sync

  • Throughput changes relative to dataset volume: Throughput is highest on native desktop environments but decreases with larger datasets and on web/mobile platforms.
  • OPFS vs. IndexedDB: Flutter-Web using OPFS delivers faster performance compared to IndexedDB, especially with datasets over 100k rows.

Incremental Sync

  • Consistent latency: Even with 1M+ rows, incremental sync latency remains consistent, demonstrating efficiency in managing large datasets.
  • Web challenges: Concurrency limitations in Flutter-Web affect responsiveness during incremental updates.

Conclusion

PowerSync is engineered to handle demanding sync scenarios efficiently, across platforms. Benchmarks demonstrate that PowerSync delivers consistent performance, even with high client-side data volumes.

Full Benchmark Results

Client Rows Synced Initial Sync Time Throughput (calculated) Incremental Sync Latency (1 update) Incremental Sync Latency (100 updates) Incremental Sync Latency (1000 updates)
Flutter, Linux desktop 10k0.36s27.6k/s18.5ms42.3ms223ms
100k4.2s23.8k/s16.9ms39.7ms218ms
1M60.6s16.5k/s16.6ms41.0ms218ms
10M724s13.8k/s17.3ms46.5ms251ms
Flutter, Android, Pixel 8a 10k1.4s7.1k/s 183.9ms
(70-300ms)
178.5ms 528ms
100k21.8s4.6k/s 200.0ms 229.0ms 613ms
1M344s2.9k/s 143.8ms 162.6ms 544ms
Flutter-Web, Linux desktop, Chrome, IndexedDB 10k2.5s4k/s 147ms
(60-240ms)
120ms
(90-150ms)
800ms
(300-3000ms)
100k17.8s5.6k/s 72ms
(60-100ms)
146ms
(100-200ms)
913ms
(350-3000ms)
Flutter-Web, Linux desktop, Chrome, OPFS 10k~0.6s16.7k/s 151ms
(70-230ms)
98ms
(80-120ms)
300ms
100k10.4s9.6k/s 171ms
(70-260ms)
117ms
(70-200ms)
296ms
1M254s3.9k/s 172ms
(90-290ms)
121ms
(110-130ms)
336ms