STATUS IS UPWEBSITE OPTIMIZATION WIKI
26Harden
Performance and delivery / Harden

Database Performance for Content and Commerce Websites

How to find costly database work, improve the paths that matter, and release performance changes without adding reliability risk.

Database Performance for Content and Commerce Websites — VISUAL GUIDE
READ
8 minutes
SOURCES
8
REVALIDATE
2027-03-27
reviewed
Database reliability reviewer with application, security, and release context
THE SHORT ANSWER

Start with the decision.

Start with the user request that is slow, then identify its database work. Measure a representative query, inspect its plan, and change one proven constraint at a time: query shape, index, pagination, cache behavior, or connection use. The result must still return the right content, price, inventory, and permissions.

For content and commerce sites, use targeted measurement and conservative delivery. Keep safely shareable read responses out of the database where appropriate, scope personalized data correctly, and preserve capacity for normal work and recovery. Test with realistic traffic, release gradually, and retain a practiced route back to a known-good application version.

VISUAL GUIDE

See the work as a system.

Use this map to connect the article’s decisions before acting on individual tactics.

SIUHarden
01Find the expensive request before changing the database
02Design indexes for the access path you actually use
03Make pagination stable and affordable
04Cache read work without serving the wrong response
01

Find the expensive request before changing the database

Begin from a user action: category load, article search, add to cart, or order submission. Capture its route, query count, database duration, returned rows, and request duration. A slow page can also wait on application code or another dependency, so do not diagnose from page-load time alone.

A query plan is the database route through tables, indexes, joins, sorts, and aggregates. In PostgreSQL, EXPLAIN shows that route. EXPLAIN ANALYZE runs the statement and reports actual rows and timings, so use a safe representative query. A large estimate-versus-actual row gap is a reason to investigate statistics or conditions, not an automatic index request.

Trace one journey

Tie a candidate query to a route and outcome, so a dashboard-only report does not outrank a slow checkout.

Keep a baseline

Record before-change timings and comparable traffic without logging customer identifiers, tokens, or card-related values.

02

Design indexes for the access path you actually use

An index is a maintained structure that can help locate rows or return them in order; it is not a universal speed switch. Start with an important query’s filters, join keys, and sort order, then confirm the proposed index in a plan. PostgreSQL documents that a matching B-tree index can satisfy ORDER BY without a separate sort, especially with a small LIMIT.

Indexes add storage and write work because inserts, updates, and deletes maintain them. For a query that needs a large fraction of a table, a sequential scan and explicit sort can be faster. Test on production-like data and keep an index only when benefit justifies its cost.

Match the access path

Use the query’s actual filters and ORDER BY, including a deterministic tie-breaker where the interface needs stable order.

Avoid speculative indexes

Review whether an index is used and what it costs during writes; recheck as data and traffic change.

03

Make pagination stable and affordable

Page-number pagination usually uses LIMIT plus OFFSET. Always impose a predictable order. PostgreSQL warns that without ORDER BY, LIMIT can return an unpredictable subset; different LIMIT or OFFSET values can yield inconsistent subsets because the optimizer may choose different plans.

Large offsets deserve scrutiny because skipped rows still have to be computed. For deep catalog, order-history, or archive browsing, consider cursor or keyset pagination: request rows after the last seen stable sort value and unique tie-breaker. Define how new or deleted records appear before changing the interface.

Set a firm page size

Return the smallest useful page rather than an unbounded result.

Separate total counts

Decide whether the interface really needs an exact total on every request.

04

Cache read work without serving the wrong response

Caching reuses a prior result instead of reconstructing it from the database. Start at the HTTP layer for public, repeatable pages and versioned assets, because a cache hit can avoid application and database work. web.dev recommends long-lived caching for versioned URLs; changing the URL is the practical invalidation mechanism.

Cache policy is a correctness decision. A shared cache can reuse one response across users, so do not share account, cart, price, or authorization-specific output unless it is designed and tested for that scope. Cache-Control private restricts reuse to a browser cache, while no-store directs caches not to retain it.

Classify responses

Separate public catalog or article output from session-specific, location-specific, and permission-sensitive output.

Test freshness

Define who may see a stale value, for how long, and the invalidation or revalidation path.

05

Protect connection capacity instead of simply raising the ceiling

A connection is a live client session to the database. Workers, cron jobs, previews, or retries can exhaust slots even when individual queries look acceptable. PostgreSQL’s max_connections controls concurrent connections, is set at server start, and a higher value allocates more resources including shared memory. Raising it without a workload model can move the failure.

Set one budget across web workers, background jobs, administration, and replicas. Use bounded pooling where it fits, preserve headroom for recovery, and apply timeouts so stranded work does not wait indefinitely. Safe numbers depend on the engine, memory, query mix, and provider limits; confirm them with the operator.

Count every client

Include web processes, queues, scheduled tasks, migrations, reporting tools, and deployment jobs.

Bound retries

Cap concurrency and use backoff so a fault does not multiply connection demand.

06

Observe query cost with context and privacy controls

Rank database work by total impact, not one slow sample. A moderately slow query called thousands of times can matter more than a rare report. PostgreSQL’s pg_stat_statements aggregates planning and execution data including calls, total and mean execution time, rows, and buffer activity. It needs server configuration and a restart to add or remove; planning tracking can add overhead.

Connect query groups to route, release version, and time window. OpenTelemetry advises collecting query text by default only after sanitization replaces literals, and using a low-cardinality query summary for grouping. This helps owners see trends without exporting customer data or creating a label for every value.

Watch tail and aggregate

Review duration, total time, calls, errors, connections, and rows; each exposes a different failure mode.

Sanitize telemetry

Use parameterized queries and verify literals are removed before traces or logs leave the application.

07

Ship database changes as reversible reliability work

Treat an index, rewrite, cache policy, pool setting, or schema change as a production change with an owner, success measure, and rollback decision. Validate in a representative environment, release to a limited slice, and watch the affected journey. Faster is not success if the change returns wrong, missing, duplicate, or stale data.

Schema changes need care because application versions can overlap. Google Cloud guidance describes a compatibility sequence: release an application that handles old and new schema, change the schema, then release the feature that uses it. This preserves an application rollback route. Locking and online-change behavior differs by engine and managed service; obtain qualified review for high-volume or payment-related systems.

Predefine guardrails

Name the route, performance and correctness signals, and threshold that stops the rollout.

Canary then expand

Verify performance and correctness in a controlled slice before widening; practice the return path outside an incident.

ACTION / VERIFY

Your practical to-do guide.

  1. 01

    Choose one journey

    Pick a page or transaction with a clear customer consequence.

    VERIFY: The route and the correct result it must preserve are named.
  2. 02

    Measure the path

    Capture request duration, query count, database duration, rows, and connection behavior.

    VERIFY: A dated baseline exists and contains no sensitive values.
  3. 03

    Rank query groups

    Use statistics and traces to rank work by total time and call volume.

    VERIFY: The team can identify the costly query tied to the journey.
  4. 04

    Inspect a safe plan

    Use the database plan tool on a representative statement.

    VERIFY: Expected versus actual rows and the costly operation are recorded.
  5. 05

    Choose one justified change

    Select a query, index, pagination, cache, or pool adjustment and its trade-off.

    VERIFY: The change has an owner and test evidence.
  6. 06

    Test correctness

    Test order, permissions, price or inventory visibility, and cache scope where relevant.

    VERIFY: Expected data is returned for relevant public and signed-in states.
  7. 07

    Budget connections

    Include web, worker, scheduled, reporting, and administrative clients.

    VERIFY: The total is below the service limit and recovery access remains.
  8. 08

    Canary and decide

    Release to a limited share, then expand or return to the known-good version.

    VERIFY: Performance, error, connection, and data-correctness signals support the decision.
DISCUSSION TOPICS

Compare the trade-offs, not private data.

Use these prompts with your team or website-owner community. Share methods and lessons, but never paste credentials, customer records, or non-public infrastructure details.

  1. 01

    Which customer journey revealed your most valuable database improvement, and what did you measure first?

  2. 02

    How does your team decide when a catalog or content response is safe for a shared cache?

  3. 03

    What rollback constraint has most influenced the sequence of your schema and application releases?

POPULAR / AUTHORITATIVE RESOURCES

Open the source material.

PostgreSQL Global Development GroupUsing EXPLAIN ↗

Explains query-plan nodes and what EXPLAIN ANALYZE measures.

Reviewed 2026-09-27
PostgreSQL Global Development GroupIndexes and ORDER BY ↗

Shows when a B-tree index can provide ordered results.

Reviewed 2026-09-27
PostgreSQL Global Development GroupLIMIT and OFFSET ↗

Documents stable ordering requirements and the cost of large offsets.

Reviewed 2026-09-27
PostgreSQL Global Development GroupConnections and Authentication ↗

Defines connection limits, reserved slots, and resource implications.

Reviewed 2026-09-27
PostgreSQL Global Development Grouppg_stat_statements ↗

Details statement-level statistics, setup needs, and overhead considerations.

Reviewed 2026-09-27
web.devPrevent unnecessary network requests with the HTTP Cache ↗

Guidance for Cache-Control, versioned URLs, and invalidation.

Reviewed 2026-09-27
Google CloudReliable releases and rollbacks—CRE life lessons ↗

Compatibility-first guidance for schema changes and application rollbacks.

Reviewed 2026-09-27
OpenTelemetrySemantic conventions for database client spans ↗

Database tracing guidance for summaries and sanitized query text.

Reviewed 2026-09-27

Source policy. Uses official documentation read for this article. Advice is conditional; internal links are navigation, not evidence.

QUICK CLARIFICATIONS

Common questions.

Should I add an index whenever a query is slow?

No. First show that the query matters and inspect its plan on representative data. An index can improve a matching lookup or ordered small result, but costs storage and write work; a table scan can be preferable when a query needs much of the table.

Is OFFSET pagination always a problem?

No. It can suit shallow pages with deterministic ORDER BY. Review it for deep browsing because skipped rows still have to be computed; keyset pagination is often worth evaluating for sequential browsing.

Can I cache a commerce page at the CDN?

Only after classifying and testing the response. Public repeatable content may suit a shared cache, while carts, account data, authorization-specific output, and sensitive values need restrictive handling. Seek qualified security or payment review for material payment flows.

Status Is UP Editorial Team · Uptime Enablement Editors

Reviewed by Database reliability reviewer with application, security, and release context. Published 2026-09-27; updated 2026-09-30.