Skip to main content

Overview

What It Is

Database and caching in frontend system design means storing, reusing, and organizing data across different layers of the application.

Frontend applications use caching and client-side storage to reduce latency, improve responsiveness, decrease server load, and support a more reliable user experience.

Database & Caching = Store useful data closer to the user and reuse it safely

Why It Matters

Modern frontend apps do not fetch everything from the server every time.

They use multiple caching and storage layers to make the app feel faster and more stable.

Caching helps with:

  • faster page loads
  • fewer network requests
  • reduced backend load
  • better scalability
  • better performance during unstable networks
  • smoother user experience

The main challenge is not only storing data.

The harder part is keeping cached data correct and up to date.


Caching Strategy Overview

Caching should be treated as a hierarchy, not as one single mechanism.

The same data may exist in multiple places:

  • browser HTTP cache
  • service worker cache
  • API cache
  • application state store
  • persistent browser storage
Caching Strategy = Know which layer owns which data

If ownership is unclear, the app can show stale, duplicated, or inconsistent data.


Main Caching Layers

LayerMain Purpose
HTTP CacheCache static assets before app code runs
Service Worker CacheProgrammatically control cache and offline behavior
API Response CacheStore previously fetched server responses
State Management CacheKeep shared data in memory for fast UI access
Browser StoragePersist data locally in the browser
Normalized StoreOrganize entities to avoid duplication

HTTP Caching

HTTP caching is the browser's first optimization layer.

It works before application JavaScript executes.

It is commonly used for static assets like:

  • JavaScript bundles
  • CSS files
  • fonts
  • images

The browser can reuse these files across multiple visits instead of downloading them every time.

HTTP Cache = Browser reuses already downloaded resources

Important Headers

HTTP caching is controlled using headers such as:

HeaderPurpose
Cache-ControlDefines how and how long a resource can be cached
ETagHelps validate whether the cached resource changed
ExpiresDefines when a cached resource becomes stale

In production, static assets are often versioned using content hashes.

app.abc123.js
style.def456.css

This allows aggressive caching while still making sure users get updated files after deployment.


Service Worker Caching

Service workers provide a programmable caching layer between the browser and the network.

Unlike HTTP caching, developers can directly control how requests are handled.

Service workers can use strategies like:

  • Cache First
  • Network First
  • Stale While Revalidate
Service Worker Cache = Developer-controlled cache between app and network

This is useful for balancing freshness, speed, and offline support.


Offline Support

Offline support is one of the most valuable service worker use cases.

When the network is unavailable, the app can still serve cached resources.

This helps create:

  • offline-first experiences
  • Progressive Web App behavior
  • faster repeat visits
  • better resilience during network failure

Large-scale applications use service workers to reduce perceived latency and improve reliability.


API Response Caching

API response caching stores previously fetched backend responses inside the application layer.

This avoids requesting the same data again and again.

Common tools include:

  • React Query
  • SWR
  • RTK Query

These tools help with:

  • automatic caching
  • background revalidation
  • stale data handling
  • cache invalidation
API Cache = Store fetched API data and reuse it across the app

Main Challenge

The hard part of API caching is not saving the response.

The hard part is deciding when the cached data should be considered outdated.

A good API cache should define:

  • who owns the data
  • when data expires
  • when data should refresh
  • what action invalidates the cache

Without clear rules, the UI may show stale or inconsistent information.


State Management as Cache

State management often works like an in-memory cache.

Data fetched from APIs can be stored and shared across components.

This avoids repeated backend calls and improves UI responsiveness.

Examples of state/cache layers:

  • Redux store
  • Zustand store
  • Context state
  • React Query cache
  • RTK Query cache
State Store = Fast in-memory access for UI data

Scaling Problem

As apps grow, state management becomes less about simply sharing data.

It becomes about synchronizing:

  • UI state
  • cached API responses
  • backend data
  • persistent browser storage

Poorly designed state stores can create:

  • stale data
  • duplicated data
  • hard debugging
  • inconsistent UI

Data Normalization

Normalization means organizing data into predictable structures to reduce duplication.

Instead of storing deeply nested objects everywhere, entities are stored separately and linked using IDs.

Normalization = Store entities once and reference them by ID

Example idea:

users by ID
posts by ID
comments by ID

This makes updates easier because one entity can be updated in one place.


Why Normalization Helps

Normalization improves large frontend apps by reducing duplicated state.

It helps with:

  • efficient updates
  • easier cache management
  • lower memory usage
  • predictable data structure
  • fewer inconsistent copies

Enterprise state systems and GraphQL caching solutions often rely on normalized data models.


Browser Storage Mechanisms

Frontend apps can also persist data inside the browser.

Common browser storage options:

StorageMain Use
Local StoragePersistent key-value data
Session StorageTemporary tab-level data
CookiesSmall request-attached data
IndexedDBLarge structured browser database

Each storage option has different behavior, limits, and security considerations.


Local Storage

Local Storage provides persistent key-value storage.

Data remains available even after the browser is closed and reopened.

Good use cases:

  • user preferences
  • application settings
  • feature flags
  • lightweight cached data
Local Storage = Persistent browser key-value storage

Do not store sensitive data in Local Storage because it is accessible through JavaScript.

If the app has an XSS vulnerability, the data can be exposed.


Session Storage

Session Storage is similar to Local Storage but scoped to a single browser tab.

It is cleared when the tab or session ends.

Good use cases:

  • temporary workflow data
  • multi-step form data
  • session-specific UI state
Session Storage = Temporary storage for one tab session

Use it when data should not persist forever.


Cookies

Cookies store small amounts of data that can be automatically sent with HTTP requests.

They are commonly used for authentication-related flows when configured securely.

Important cookie attributes:

  • HttpOnly
  • Secure
  • SameSite
Cookies = Small storage that can travel with HTTP requests

Cookies should be used carefully because they are sent with requests.

Too many or too large cookies can negatively affect network performance.


IndexedDB

IndexedDB is a browser-native database for storing large amounts of structured data.

Compared to Local Storage, IndexedDB supports:

  • larger storage capacity
  • indexes
  • transactions
  • complex queries
  • structured data
IndexedDB = Browser database for large and structured client-side data

Apps like Figma, Notion, and Google Docs use IndexedDB-style storage patterns to support offline functionality, synchronization, and local persistence.

Use IndexedDB when app requirements start looking like a real client-side database.


Architectural Considerations

Caching improves performance, but it also increases system complexity.

Before adding caching layers, engineers should define:

  • cache ownership
  • expiration policy
  • invalidation rules
  • synchronization mechanism
  • security boundaries
  • consistency expectations
Caching is easy to add.
Correct caching is hard to maintain.

Security Considerations

Client-side storage needs careful security decisions.

Important rules:

  • avoid storing sensitive data in Local Storage
  • use secure cookies for authentication when needed
  • use HttpOnly, Secure, and SameSite cookie attributes
  • consider encryption for sensitive local data
  • choose storage based on risk and access requirements
  • remember that JavaScript-accessible storage can be exposed by XSS

The more data stored on the client, the more carefully security must be handled.


Database and Caching Table

AreaMain Idea
HTTP CacheBrowser caches static resources
Service Worker CacheDeveloper controls request and cache behavior
API CachePreviously fetched responses are reused
State ManagementIn-memory cache for UI data
NormalizationStore entities once and reference by ID
Local StoragePersistent key-value data
Session StorageTemporary tab-scoped data
CookiesSmall data sent with HTTP requests
IndexedDBLarge structured browser database

Basic Checklist

Use HTTP caching for static assets
Use content hashes for production assets
Use service workers for offline support and custom caching
Use API caching to avoid repeated backend calls
Define cache ownership clearly
Set expiration and invalidation rules
Use state management as an in-memory cache carefully
Normalize duplicated entity data
Use Local Storage only for non-sensitive persistent data
Use Session Storage for temporary tab-specific data
Use secure cookies for authentication
Use IndexedDB for large structured offline data
Always think about stale data and consistency

Interview Style Answer

Database and caching in frontend system design means using multiple storage and caching layers to improve speed, responsiveness, scalability, and reliability. HTTP caching lets the browser reuse static assets before app code runs. Service worker caching provides programmable control over requests, offline support, and strategies like Cache First, Network First, and Stale While Revalidate. API response caching stores fetched data using tools like React Query, SWR, or RTK Query, while state management acts as a fast in-memory cache for UI data. Normalization helps reduce duplicated data by storing entities separately and linking them by ID. Browser storage options include Local Storage for persistent non-sensitive data, Session Storage for temporary tab-scoped data, cookies for small request-attached data, and IndexedDB for large structured offline data. The main challenge is keeping data consistent, secure, and up to date across all layers.


One-Line Summary

Database & Caching Overview = Use layered caching and browser storage to make frontend apps faster, more reliable, and more scalable while managing stale data carefully.

Final Mental Model

HTTP Cache -> static assets
Service Worker -> offline and custom cache logic
API Cache -> fetched server data
State Store -> fast in-memory UI data
Browser Storage -> persistent local data
Normalization -> fewer duplicates and easier updates

Fast data is useful only when it is also correct.