When building browser games, developers often default to localStorage.setItem() for saving high scores. But as games evolve to support ghost replays (storing every millisecond coordinate of your personal record), LocalStorage quickly hits a wall.
LocalStorage is synchronous and blocking. Writing a 2MB telemetry replay to LocalStorage freezes the main UI thread, dropping frames mid-game. In this guide, we explore how IndexedDB provides asynchronous, high-capacity structured storage for modern web games.
🏎️ Ghost Replay Technology in TypeCrate
When you hit a personal best in TypeCrate, your entire run is saved locally in IndexedDB as a playable ghost car that you can race against forever—even while offline on an airplane.
LocalStorage vs. IndexedDB: Feature Breakdown
| Feature | LocalStorage | IndexedDB |
|---|---|---|
| Execution Mode | Synchronous (Blocks render thread) | Asynchronous (Non-blocking) |
| Storage Capacity | ~5 Megabytes | Gigabytes (Up to 60% free disk) |
| Data Types | Strings only (JSON serialization overhead) | TypedArrays, Blobs, Objects, ArrayBuffers |
| Web Worker Access | No (Window context only) | Yes (Usable inside background threads) |
Storing Ghost Telemetry as Compact ArrayBuffers
Storing an array of 500 JSON objects like { time: 1420, char: 'a', wpm: 95 } in LocalStorage wastes thousands of bytes on repetitive string keys.
In IndexedDB, game developers pack ghost runs into raw binary Uint16Array buffers. A complete 60-second typing race consumes just 1.2 Kilobytes of binary storage, allowing players to store thousands of historical race ghosts with instantaneous query retrieval.
