To limit memory use when paginating a large result set in IndexedDB (especially with 10,000+ records), avoid loading all data into memory (.toArray()) and instead use
streamed access via cursors or Dexie.js pagination.
Here’s how you do it efficiently:
Strategy: Page data without loading everything
Avoid This:
// Bad: loads everything into memory
const all = await db.users.toArray();
const page = all.slice(offset, offset + limit);
Solution 1: Pagination with Dexie.js (Efficient)
If you're using Dexie.js, use offset().limit():
const pageSize = 100;
const currentPage = 2; // (starts from 0)
const pageData = await db.users
.orderBy('id') // must be indexed
.offset(currentPage * pageSize)
.limit(pageSize)
.toArray();
Only loads 1 page worth of records into memory
Uses indexed cursor internally
Very fast and memory-safe
Solution 2: Using a Cursor in Vanilla IndexedDB
Cursors allow you to stream records without full memory load:
function paginateWithCursor(db, storeName, page, pageSize) {
return new Promise((resolve, reject) => {
const tx = db.transaction([storeName], "readonly");
const store = tx.objectStore(storeName);
const request = store.openCursor();
const start = page * pageSize;
const end = start + pageSize;
let result = [];
let count = 0;
request.onsuccess = function (event) {
const cursor = event.target.result;
if (!cursor) return resolve(result);
if (count >= start && count < end) {
result.push(cursor.value);
}
count++;
if (count < end) {
cursor.continue();
} else {
resolve(result); // stop early
}
};
request.onerror = () => reject(request.error);
});
}
Loads only a page-sized portion
Prevents high memory use
No need for .toArray()
Tips for Optimal Pagination
Tip
Why
Use .offset().limit() on indexed field
Indexed traversal avoids full scan
Use orderBy() only on indexed columns
Otherwise, Dexie can’t paginate efficiently
Use .count() to get total items without loading them
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy.
To limit memory use when paginating a large result set in IndexedDB (especially with 10,000+ records), avoid loading all data into memory (
.toArray()) and instead use streamed access via cursors or Dexie.js pagination.Here’s how you do it efficiently:
Strategy: Page data without loading everything
Avoid This:
Solution 1: Pagination with Dexie.js (Efficient)
If you're using Dexie.js, use
offset().limit():Solution 2: Using a Cursor in Vanilla IndexedDB
Cursors allow you to stream records without full memory load:
.toArray()Tips for Optimal Pagination
.offset().limit()on indexed fieldorderBy()only on indexed columns.count()to get total items without loading them.filter()or.map()after.toArray()Optional: Count Total Items
For pagination UI:
Summary
Would you like this turned into a reusable Dexie pagination function with total count?