Comparing Persistent Storage Options in iOS
This post provides a concise overview of four popular database management solutions: SharingGRDB, GRDB, Core Data, and Realm. By understanding these solutions, you can make informed decisions about when and why to choose one over another.
Intro #
Choosing the appropriate persistent storage solution is a crucial decision for any iOS app. Each option has its unique strengths, weaknesses, and ideal use cases. Let’s explore the differences between SharingGRDB, GRDB, Core Data, and Realm in depth.
SharingGRDB #
Pros
- Offers an async/await and Combine-friendly wrapper (
SharedDatabase). - Simple API that is easy to work with.
- Dependency-friendly, especially inside modular architectures.
Cons
- Adds an extra abstraction layer on top of GRDB, which can increase complexity.
- Part of the Point-Free ecosystem, so it may require additional learning.
Minimum iOS Version
- iOS 13
Where to Use
- Projects already using Point-Free libraries (e.g., Composable Architecture).
- Apps targeting iOS 13–16 that want a modern, async/await-friendly API similar to SwiftData but without requiring iOS 17+.
- Medium to large codebases with modular architecture where dependency injection and testability are priorities.
Where NOT to Use
- Very small apps or prototypes where adding the Point-Free dependency stack feels like overkill.
- Teams unfamiliar with functional programming concepts or the Composable Architecture.
- Projects that need the absolute maximum performance and want to avoid any additional abstraction overhead.
Comments SharingGRDB is a good alternative to SwiftData, especially because SwiftData requires iOS 17 or later. It works well for teams already familiar with Point-Free tools.
GRDB #
Pros
- Provides full access to SQLite features.
- Supports clear and explicit database migrations.
- Lightweight, fast, and battle-tested.
Cons
- Still requires developers to think about concurrency, even though it provides safer patterns than raw SQLite.
- No built-in reactive notifications (you have to implement them yourself or use additional wrappers).
Where to Use
- Apps that need maximum performance and fine-grained control over SQLite.
- Projects with complex queries or large datasets where raw SQL power is beneficial.
- Teams that prefer writing explicit migrations and value transparency over magic.
Where NOT to Use
- Rapid prototyping or small apps where writing SQL and migrations feels too low-level.
- Projects targeting a modern async/await-only codebase and wanting zero boilerplate around concurrency.
- Teams that want live/reactive objects out of the box without extra work.
Comments GRDB is ideal for developers who want strong control over their database, high performance, and a relatively simple architecture.
Core Data #
Pros
- Includes a visual model editor, which helps with schema design.
- First-party Apple framework with deep integration across iOS, macOS, watchOS, tvOS.
- Supports CloudKit sync out of the box (with NSPersistentCloudKitContainer).
Cons
- Contains Objective-C legacy components beneath the surface.
- Has a complex API that can be hard to master.
- Performance can be unpredictable with large datasets if not tuned properly.
Where to Use
- Enterprise or long-lived apps that benefit from Apple’s official stack and tooling.
- Apps that require CloudKit synchronization with minimal custom code.
- Projects where team members are already familiar with Core Data or the visual model editor is a big productivity win.
Where NOT to Use
- New greenfield projects targeting only iOS 15+ where SwiftData offers a simpler, Swift-native API.
- Performance-critical apps with very large local datasets (Core Data can become a bottleneck).
- Teams that strongly prefer pure Swift solutions and want to avoid any Objective-C runtime dependencies.
Comments Core Data can store information in different formats:
- SQLite
- Binary
- In-memory
- CloudKit (with Core Data + CloudKit integration)
Realm #
Pros
- Very easy to set up and use, with a clean and intuitive API.
- High-performance database engine optimized for mobile.
- Built-in support for reactive updates (e.g., auto-updating objects and notifications).
- Cross-platform—works on iOS, Android, and other environments.
Cons
- Adds a non-standard database format (not SQLite), which can limit interoperability and debugging.
- Can increase app size because it brings its own database engine.
- Some advanced features (sync, etc.) may require a paid Realm/MongoDB Atlas service.
Where to Use
- Apps that need fast local storage combined with reactive UI updates (live objects).
- Cross-platform projects (shared codebase between iOS and Android using Xamarin, Kotlin Multiplatform, Flutter + Realm, etc.).
- Rapid development scenarios where you want to avoid writing SQL or migration code.
Where NOT to Use
- Apps that must use SQLite as the underlying store (e.g., for regulatory reasons, existing tooling, or interoperability with server-side SQLite).
- Projects with strict app-size requirements (Realm’s engine adds several MB).
- Situations where you need complex SQL queries or joins that Realm’s query language can’t express efficiently.
Minimum iOS Version
- iOS 11 (Realm generally supports older versions than GRDB-based solutions)
Comments Realm is often chosen when developers want strong performance and minimal setup. Its object-based model is easy to learn, making it good for teams who prefer a simple and flexible data layer.
Conclusion #
Each storage option serves a different type of project:
- SharingGRDB: Good balance between simplicity and flexibility, especially for teams using Point-Free tools and targeting iOS 13–16.
- GRDB: Best choice for developers who want control, speed, and full access to SQLite.
- Core Data: Strong Apple integration with powerful tooling and CloudKit sync, but with a steeper learning curve.
- Realm: Easy to use, high-performance, reactive, and ideal for cross-platform or rapid-development apps.
By understanding the pros, cons, ideal use cases, and scenarios to avoid for each tool, you can select the solution that best fits your app’s architecture, team expertise, deployment targets, and long-term needs.