v141 · indexeddb
Index Range Query
getAllRecords() accepts a secondary index and an IDBKeyRange, making date-range and category-filter queries a single async call. Previously this required a cursor loop with manual accumulation.
Feature detection: checking…
500 order records are seeded across 3 categories and 180 days of dates. Use the filters below to slice by date range or category, then compare how the new API stacks up against a cursor loop.
query filters
timing comparison
getAllRecords()
Time: —
Records: —
Code: 1 await, IDBKeyRange inline
Records: —
Code: 1 await, IDBKeyRange inline
Cursor loop
Time: —
Records: —
Code: cursor + continue() loop
Records: —
Code: cursor + continue() loop
// Chrome 141: index range query via getAllRecords()
const tx = db.transaction('orders', 'readonly');
const idx = tx.objectStore('orders').index('by-date');
const range = IDBKeyRange.bound('2026-01-01', '2026-03-31');
const records = await idx.getAllRecords({ query: range, count: 50 });
// records[0] === { key: '2026-01-04', value: { id, date, amount, category } }
// Before Chrome 141 — cursor accumulation loop
const results = [];
await new Promise((resolve, reject) => {
const req = idx.openCursor(range);
req.onsuccess = e => {
const cursor = e.target.result;
if (!cursor || results.length >= 50) return resolve(results);
results.push({ key: cursor.key, value: cursor.value });
cursor.continue();
};
req.onerror = reject;
});
see also
- getAllRecords — basic usage
- Pagination Demo — forward and reverse paging
- Bulk Export/Import — JSON snapshot via getAllRecords
- ChromeStatus entry