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

Click "Run query" to see results.

timing comparison

getAllRecords()
Time:
Records:
Code: 1 await, IDBKeyRange inline
Cursor loop
Time:
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