---
title: "How do you optimize large queries in IndexedDB (e.g., 10,000+ records)?"  
description: "How do you optimize large queries in IndexedDB (e.g., 10,000+ records)?"  
author: "ICSM Computer"  
published: 2025-07-07  
updated: 2025-07-07  
canonical: https://www.mindstick.com/interview/34325/how-do-you-optimize-large-queries-in-indexeddb-e-g-10-000-records  
category: "IndexedDB"  
tags: ["indexeddb"]  
reading_time: 5 minutes  

---

# How do you optimize large queries in IndexedDB (e.g., 10,000+ records)?

Optimizing large queries (10,000+ records) in [**IndexedDB**](https://www.mindstick.com/interview/34289/what-is-indexeddb) requires strategic use of indexes, efficient querying, and memory management.

## 1. Use Indexes Properly

[Define indexes](https://www.mindstick.com/interview/34308/what-are-indexes-in-indexeddb-and-how-do-you-use-them) on frequently queried fields to prevent full scans.

```javascript
db.version(1).stores({
  users: '++id, name, email, age, [email+age]' // compound index example
});
```

Then use:

```javascript
db.users.where('email').equals('a@example.com').toArray();
```

Avoid `.filter()` or `.toArray().filter()`, which loads everything into memory.

## 2. Query in Chunks ([Pagination](https://www.mindstick.com/interview/34318/what-are-some-best-practices-for-working-with-indexeddb-in-production) or Batching)

Instead of loading 10,000 records at once:

### Paginated Query (by offset and limit):

```javascript
const pageSize = 1000;
const page = 0; // or 1, 2, 3...
const results = await db.users.offset(page * pageSize).limit(pageSize).toArray();
```

### Cursor with batching:

```javascript
const results = [];
let count = 0;

db.users
  .orderBy('id')
  .each((item, cursor) => {
    results.push(item);
    count++;
    if (count >= 1000) {
      cursor.stop(); // break the loop early
    }
  });
```

## 3. Use Compound Indexes

If your queries use multiple conditions, define [compound indexes](https://www.mindstick.com/interview/34308/what-are-indexes-in-indexeddb-and-how-do-you-use-them):

```javascript
db.users.where('[status+createdAt]').between([1, from], [1, to]);
```

This avoids filtering in memory and leverages B-tree search.

## 4. Avoid `.toArray().filter(...)` on Large Data

This loads all data into memory and is slow for 10K+ records. Instead, use `where`, `equals`, `between`, `startsWith`, or `anyOf` when possible.

Bad:

```javascript
const results = (await db.users.toArray()).filter(u => u.age > 25);
```

Good:

```javascript
const results = await db.users.where('age').above(25).toArray();
```

## 5. Use `eachPrimaryKey` or `keys()` if Only IDs Are Needed

Faster than retrieving full objects:

```javascript
await db.users.where('status').equals('active').primaryKeys();
```

## 6. Use `.modify()` Instead of Fetch + Update

Bulk modify records efficiently:

```javascript
await db.users.where('age').below(18).modify(user => {
  user.status = 'minor';
});
```

## 7. Use Lazy Iteration or Generators (Memory Friendly)

Process records one-by-one instead of loading all at once.

```javascript
await db.users.each(user => {
  // Process user
});
```

## 8. Compact Data (Avoid Overhead)

If you store large payloads (e.g., images, logs), consider:

- Storing metadata in IndexedDB and actual files/blobs in `Blob` or file system (browser-permitting)
- Compressing large JSON payloads before saving

## 9. Upgrade to Dexie.js for Performance Features

Dexie optimizes IndexedDB internally and offers:

- Transaction support
- Easier compound query syntax
- Observable support for live updates

## 10. Measure and Profile

Use **Chrome DevTools > Application > IndexedDB** tab to inspect query time, or log time manually:

```javascript
const start = performance.now();
const data = await db.users.where('active').equals(true).toArray();
console.log("Query time:", performance.now() - start);
```

## Summary Table

| Optimization | Use Case |
| --- | --- |
| Indexed fields | For fast lookup |
| Pagination / Cursors | For large datasets |
| Compound indexes | For multi-field queries |
| `.each()` or `.modify()` | Low-memory processing |
| Avoid `.toArray().filter()` | Prevent memory overload |
| Dexie.js | Easier + faster queries |

## Answers

### Answer by ICSM Computer

Optimizing large queries (10,000+ records) in [**IndexedDB**](https://www.mindstick.com/interview/34289/what-is-indexeddb) requires strategic use of indexes, efficient querying, and memory management.

## 1. Use Indexes Properly

[Define indexes](https://www.mindstick.com/interview/34308/what-are-indexes-in-indexeddb-and-how-do-you-use-them) on frequently queried fields to prevent full scans.

```javascript
db.version(1).stores({
  users: '++id, name, email, age, [email+age]' // compound index example
});
```

Then use:

```javascript
db.users.where('email').equals('a@example.com').toArray();
```

Avoid `.filter()` or `.toArray().filter()`, which loads everything into memory.

## 2. Query in Chunks ([Pagination](https://www.mindstick.com/interview/34318/what-are-some-best-practices-for-working-with-indexeddb-in-production) or Batching)

Instead of loading 10,000 records at once:

### Paginated Query (by offset and limit):

```javascript
const pageSize = 1000;
const page = 0; // or 1, 2, 3...
const results = await db.users.offset(page * pageSize).limit(pageSize).toArray();
```

### Cursor with batching:

```javascript
const results = [];
let count = 0;

db.users
  .orderBy('id')
  .each((item, cursor) => {
    results.push(item);
    count++;
    if (count >= 1000) {
      cursor.stop(); // break the loop early
    }
  });
```

## 3. Use Compound Indexes

If your queries use multiple conditions, define [compound indexes](https://www.mindstick.com/interview/34308/what-are-indexes-in-indexeddb-and-how-do-you-use-them):

```javascript
db.users.where('[status+createdAt]').between([1, from], [1, to]);
```

This avoids filtering in memory and leverages B-tree search.

## 4. Avoid `.toArray().filter(...)` on Large Data

This loads all data into memory and is slow for 10K+ records. Instead, use `where`, `equals`, `between`, `startsWith`, or `anyOf` when possible.

Bad:

```javascript
const results = (await db.users.toArray()).filter(u => u.age > 25);
```

Good:

```javascript
const results = await db.users.where('age').above(25).toArray();
```

## 5. Use `eachPrimaryKey` or `keys()` if Only IDs Are Needed

Faster than retrieving full objects:

```javascript
await db.users.where('status').equals('active').primaryKeys();
```

## 6. Use `.modify()` Instead of Fetch + Update

Bulk modify records efficiently:

```javascript
await db.users.where('age').below(18).modify(user => {
  user.status = 'minor';
});
```

## 7. Use Lazy Iteration or Generators (Memory Friendly)

Process records one-by-one instead of loading all at once.

```javascript
await db.users.each(user => {
  // Process user
});
```

## 8. Compact Data (Avoid Overhead)

If you store large payloads (e.g., images, logs), consider:

- Storing metadata in IndexedDB and actual files/blobs in `Blob` or file system (browser-permitting)
- Compressing large JSON payloads before saving

## 9. Upgrade to Dexie.js for Performance Features

Dexie optimizes IndexedDB internally and offers:

- Transaction support
- Easier compound query syntax
- Observable support for live updates

## 10. Measure and Profile

Use **Chrome DevTools > Application > IndexedDB** tab to inspect query time, or log time manually:

```javascript
const start = performance.now();
const data = await db.users.where('active').equals(true).toArray();
console.log("Query time:", performance.now() - start);
```

## Summary Table

| Optimization | Use Case |
| --- | --- |
| Indexed fields | For fast lookup |
| Pagination / Cursors | For large datasets |
| Compound indexes | For multi-field queries |
| `.each()` or `.modify()` | Low-memory processing |
| Avoid `.toArray().filter()` | Prevent memory overload |
| Dexie.js | Easier + faster queries |


---

Original Source: https://www.mindstick.com/interview/34325/how-do-you-optimize-large-queries-in-indexeddb-e-g-10-000-records

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
