Home
Dart
OOP
Flutter
Contact

Local Data Persistence

Choose between sqflite and Hive for offline-first data caching in Flutter.

Overview

Most Flutter apps need to persist data locally — whether it's user settings, cached API responses, bookmarks, or offline-first content. Choosing the right storage solution depends on your data's complexity, how often it changes, and whether you need to query it with complex filters.

Flutter offers several local storage options depending on your data complexity:

OptionTypeBest For
SharedPreferencesKey-valueSimple settings, flags
sqfliteRelational SQLComplex queries, relations
HiveNoSQL key-valueFast read/write, simple models
IsarNoSQL (typed)High-performance queries

sqflite (SQLite)

A relational database with full SQL support. Great for structured data with complex queries:

bookmark_db.dart
import 'package:sqflite/sqflite.dart';

class BookmarkDatabase {
  static Database? _db;

  static Future<Database> get database async {
    _db ??= await openDatabase(
      'bookmarks.db',
      version: 1,
      onCreate: (db, version) async {
        await db.execute('''
          CREATE TABLE bookmarks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            title TEXT NOT NULL,
            url TEXT NOT NULL,
            category TEXT DEFAULT 'general',
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
          )
        ''');
      },
    );
    return _db!;
  }

  static Future<int> insert(Map<String, dynamic> bookmark) async {
    var db = await database;
    return db.insert('bookmarks', bookmark);
  }

  static Future<List<Map<String, dynamic>>> getByCategory(String category) async {
    var db = await database;
    return db.query('bookmarks',
      where: 'category = ?',
      whereArgs: [category],
      orderBy: 'created_at DESC',
    );
  }

  static Future<int> delete(int id) async {
    var db = await database;
    return db.delete('bookmarks', where: 'id = ?', whereArgs: [id]);
  }
}

Hive (NoSQL)

A lightweight, extremely fast key-value database with no native dependencies:

hive_bookmark.dart
import 'package:hive/hive.dart';

@HiveType(typeId: 0)
class Bookmark extends HiveObject {
  @HiveField(0)
  late String title;

  @HiveField(1)
  late String url;

  @HiveField(2)
  String category = 'general';

  @HiveField(3)
  DateTime createdAt = DateTime.now();

  Map<String, dynamic> toJson() => {
    'title': title, 'url': url,
    'category': category, 'createdAt': createdAt.toIso8601String(),
  };
}

// Initialize and use
void initHive() async {
  await Hive.initFlutter();
  Hive.registerAdapter(BookmarkAdapter());
  await Hive.openBox<Bookmark>('bookmarks');
}

// CRUD operations
var box = Hive.box<Bookmark>('bookmarks');
await box.add(bookmark);          // Insert
var all = box.values.toList();     // Read all
await box.deleteAt(0);            // Delete first

Detailed Comparison

FeaturesqfliteHive
Storage TypeSQLite relational DBNoSQL key-value store
Query LanguageSQLMethod chaining
PerformanceGood for complex queriesBlazing fast for simple reads/writes
Data SizeNo practical limitBest for < 100MB
SchemaDefined via CREATE TABLEAdaptive (no migrations needed)
Best ForRelational data, complex joinsSettings, caches, simple lists
💡 Decision Framework
  • Use Hive for: user settings, app preferences, simple caching, offline bookmarks
  • Use sqflite for: chat messages, transaction logs, user-generated content, anything with relationships
  • Use both for: Hive for fast access + sqflite as the source of truth

sqflite vs Hive

FeaturesqfliteHive
Data ModelRelational (tables)NoSQL (boxes)
Query LanguageSQLAPI methods
PerformanceGood for complex queriesExcellent for simple reads
SetupModerate (schema)Simple (adapters)
Best ForRelations, joins, filteringFast caching, key-value

Real-World Example: Offline Bookmarking Cache

bookmark_service.dart
class BookmarkService {
  final _box = Hive.box<Bookmark>('bookmarks');

  // Add bookmark
  void addBookmark(String title, String url, {String category = 'general'}) {
    var bookmark = Bookmark()
      ..title = title
      ..url = url
      ..category = category;
    _box.add(bookmark);
  }

  // Search bookmarks
  List<Bookmark> searchBookmarks(String query) {
    return _box.values
        .where((b) => b.title.toLowerCase().contains(query.toLowerCase()))
        .toList();
  }

  // Get by category
  List<Bookmark> getByCategory(String category) {
    return _box.values.where((b) => b.category == category).toList();
  }

  // Delete
  void removeBookmark(int index) {
    _box.deleteAt(index);
  }

  // Export to JSON for cloud sync
  List<Map<String, dynamic>> exportAll() {
    return _box.values.map((b) => b.toJson()).toList();
  }
}

Summary

  • SharedPreferences for simple key-value settings
  • sqflite for relational data with complex queries
  • Hive for fast, lightweight NoSQL storage
  • Use Hive as a cache layer, sync to cloud when online
🚀 Next Step Continue to API Integration & JSON.
K
Kesavaraja Murugesan
Flutter Developer & Educator

Flutter developer with 3 years of experience building production-grade mobile applications. Passionate about teaching clean architecture patterns and helping developers write maintainable, scalable code.

← Navigation Next: API Integration →