There is no universal percentage that describes how much an index slows writes: the cost depends on the database, index definition, data, and workload. Measure the index’s on-disk size separately from its write overhead, then compare equivalent workloads with and without it.
What to measure
An index has two distinct costs. Its storage cost is the space it occupies on disk. Its write cost is the additional work the database performs to keep it current as rows are inserted, updated, or deleted. Measure those costs alongside the read queries the index is intended to improve; an index that adds overhead may still be worthwhile if it materially benefits important queries.
As an Amazon Associate I earn from qualifying purchases.
The commands below are PostgreSQL-specific examples, not portable SQL for every database. PostgreSQL documents relation-size functions, query-plan tools, and index statistics, but does not establish a general write-penalty percentage. Your result should describe your tested system and workload, not claim a universal multiplier.
Define a representative test
Before comparing configurations, record enough context for someone else to interpret the result. A measurement from a small synthetic table, for example, is not automatically predictive of a production workload.
- Database engine and version; table size and row count.
- The index method and full definition: indexed columns, expressions, included columns, and relevant storage parameters.
- Data distribution, database settings, hardware, and storage.
- Concurrency and the actual mix of inserts, updates, and deletes.
- Whether the workload is synthetic or sampled from production, plus cache and warm-up conditions.
Measure index storage in PostgreSQL
PostgreSQL’s size functions report on-disk relation sizes in bytes; they describe what exists now, not a forecast of future growth. Use the function that matches the scope of the question:
| Question | Function | What it measures |
|---|---|---|
| How large are all indexes attached to a table? | pg_indexes_size('schema.table') |
Total size of the table’s indexes. |
| How large is one index relation? | pg_relation_size('schema.index_name') |
Size of the specified relation, such as an individual index. |
| How large is the table excluding indexes? | pg_table_size('schema.table') |
Table storage excluding indexes. |
| What is the table total including indexes and TOAST data? | pg_total_relation_size('schema.table') |
Total relation size including indexes and TOAST data. |
These functions are documented in the PostgreSQL database size functions documentation. For a before-and-after comparison, capture the same measurements under the same database conditions and identify whether each figure is per index or for all indexes on the table.
Check the read benefit before pricing the write cost
First refresh planner statistics with ANALYZE, then examine representative queries from the workload the index is meant to serve. PostgreSQL recommends gathering statistics and using EXPLAIN to assess index use; its Examining Index Usage documentation notes that “The EXPLAIN ANALYZE command can be useful here.”
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use EXPLAIN to inspect the plan. Where actual execution measurements are appropriate, use EXPLAIN ANALYZE on representative data and queries. Interpret its output carefully: PostgreSQL warns that “The measurement overhead added by EXPLAIN ANALYZE can be significant, especially on machines with slow gettimeofday() operating-system calls.” It also excludes client network transmission time. Do not extrapolate results from a toy table to a materially different data size or distribution. See the Using EXPLAIN documentation.
Rank #3
Measure write overhead with a controlled comparison
There is no index-specific benchmark recipe or cost multiplier established by PostgreSQL’s documentation. A useful local measurement is a controlled A/B comparison: make the candidate index the meaningful difference between runs, and keep the data and write workload equivalent.
- Prepare equivalent starting data. Load or restore identical data for each run, with and without the candidate index.
- Run the same write workload. Use a representative scale, concurrency, and insert/update/delete mix. Keep database settings and test conditions consistent.
- Measure more than an average. Record throughput and latency distributions so that slow periods and variability are visible.
- Track resource use. Record CPU and I/O alongside database-level statistics where available. PostgreSQL’s monitoring statistics include per-index information useful for analyzing index use; its guidance recommends combining database statistics with operating-system utilities for a fuller I/O picture.
- Repeat and document conditions. Repeat enough runs to expose variability, and state cache and warm-up conditions. Report the tested database version, hardware, settings, data, and workload.
Compare the runs’ write throughput and latency, then place those results beside the index-size measurement and the read-query changes. This distinguishes a larger index from an index that causes a measurable change in a particular write workload.
Rank #4
Account for the index definition and settings
Two indexes on the same table can differ in both storage and maintenance behavior. When comparing genuine candidates, record the index method, indexed columns or expressions, included columns, and relevant storage parameters. Compare the same axes for each option:
Free tools Windows power users keep installed
One-click scans. No signup required.
- Index size in bytes.
- Insert, update, and delete throughput and latency under the same workload.
- Which read queries improve, and how their plans or measured latency change.
- CPU and I/O implications.
- Index method, definition, and storage settings.
For PostgreSQL B-tree indexes, fillfactor affects page packing and can influence page-split behavior; the outcome is workload-dependent. It is not a universal tuning shortcut. Consult the version-appropriate CREATE INDEX documentation and measure the setting under your own workload.
Best Value
Report results without overgeneralizing
A useful report lets another person see what was compared and why the result matters. State the index bytes, the write-throughput and latency changes, the read queries affected, and the test conditions together. If the result came from one local benchmark, describe it as that workload’s result—not as a general cost of indexes.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




