How to Choose the Right Database Size Before Your Host Caps It

How to Choose the Right Database Size Before Your Host Caps It

To size a database for hosting, measure three things on your own copy of the data: the on-disk size of the tables plus their indexes, the peak number of simultaneous connections, and the growth rate per unit of content. The cap you hit first is almost never raw disk; it is usually connections, temporary space, or a per-account inode or row limit that nobody read in the plan description. Everything below is about getting those three numbers before a provider enforces them for you.

Start with storage, because it is the easiest to measure and the easiest to misjudge. The number that matters is not the size of your .sql dump. It is the size the engine allocates on disk, which includes indexes, free space left by deleted rows, and per-table overhead. A dump is a logical representation; InnoDB tablespaces and PostgreSQL heap files are physical. They diverge, sometimes by a large factor, in either direction.

Measure the physical footprint, not the dump

On MySQL or MariaDB, query the information schema. This reports data and index bytes per table, which is what the host will bill you for.

SELECT table_schema, table_name,
       ROUND((data_length + index_length) / 1024 / 1024) AS mb
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
ORDER BY data_length + index_length DESC
LIMIT 10;

On PostgreSQL, the equivalent lives in a function, not a view. pg_total_relation_size returns bytes including indexes and TOAST data.

SELECT relname,
       pg_size_pretty(pg_total_relation_size(oid)) AS total
FROM pg_class
WHERE relkind = 'r'
ORDER BY pg_total_relation_size(oid) DESC
LIMIT 10;

Run these against a copy that has been in production for a while, not a freshly imported one. Fresh imports have no bloat. Deleted rows, rolled-back transactions and heavy updates leave gaps that the engine does not always return to the filesystem, so a table that grew to a gigabyte and then shrank to a hundred megabytes of live rows may still occupy most of that gigabyte. If your host counts allocated bytes, plan for allocated bytes.

Then project forward. Take the current size, subtract the size at some earlier point you can still measure, and divide by the content added in between. That gives you bytes per article, per order, per user, per whatever your site accumulates. Multiply by your realistic content plan and add a margin for indexes, which grow with row count and can dominate on tables with several composite indexes or full-text search columns.

Connection limits are the cap that bites first

Disk is visible on a dashboard. Connections are not, and they are where shared hosting and small managed plans throttle hardest. Each request that touches the database holds a connection, and a pooler or PHP worker holds one for the life of the process even when idle. A site with a modest table can exhaust a connection cap long before it fills a disk.

Check the server ceiling and your current usage on MySQL:

SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';

Max_used_connections is the high-water mark since the server started, which is the number to compare against the cap. If it sits close to max_connections, you are one traffic spike away from "too many connections" errors. On PostgreSQL the same information comes from SHOW max_connections; and a count of pg_stat_activity rows, and you should watch for backends in idle in transaction state, which hold a slot while doing nothing.

Then look at your application. If it opens a connection per request and your web tier runs many worker processes, the database sees the sum of all of them. A pooler such as PgBouncer or a MySQL proxy in front of the database lets hundreds of application workers share a small number of real connections. If your host caps connections per account, a pooler is often the difference between staying on a plan and being told to upgrade. Size the pool to the host's cap minus a few slots reserved for administration, and set the pooler's own maximum below that, not at it.

How to size a database for hosting when the caps are hidden

Read the plan limits before you read the marketing. Look specifically for per-database size, total account size, maximum connections, maximum simultaneous queries, temporary table space, and any row or inode ceiling. A limit on temporary space matters for sorts and large joins: a query that spills to disk can fail even when the stored data is tiny, because the sort buffer is capped separately.

You can test for that class of failure on your own copy. Run your heaviest reporting query while watching the temporary space counter, and confirm it completes without spilling beyond what the host allows. If a query needs a temporary table larger than the cap, it will fail at exactly the wrong moment, under load, in front of a customer.

For storage headroom, a simple rule holds up: keep live data comfortably under the cap so that a restore, a reindex, or a bulk import fits alongside it. A restore needs room for the new copy while the old one still exists. A REINDEX or an OPTIMIZE TABLE can briefly double a table's footprint. If you are already near the ceiling, you cannot perform maintenance without a temporary upgrade, and some hosts will not grant one on short notice.

Watch the growth of indexes and logs

Two things surprise people. First, indexes: adding an index to a large table writes a new structure that can rival the table itself, and every insert maintains it. Second, binary logs and general query logs, which live on the same disk and are counted against your quota on many plans. A verbose slow-query log left on for weeks can quietly consume the space you thought was free. Check the log directory size, not just the data directory.

du -sh /var/lib/mysql /var/log/mysql
df -h /var/lib/mysql

Compare the database directory total against the filesystem's available space. The gap is your real headroom, after logs, temporary files and the operating system's own needs. If your host exposes only a database size in a control panel, that number may exclude logs and temporary space, so trust the filesystem figure where you can see it.

What to do next

Take the three measurements on a current copy of your data: allocated bytes per table, peak connections, and bytes added per unit of content. Write them down with the date. Then compare each against the documented limit on your plan, leaving a margin for maintenance operations and traffic spikes, and set up a periodic check that alerts you when any of the three crosses a threshold you choose in advance. That way the decision to move plans is yours to make on a quiet afternoon rather than the host's to make for you during an outage.

Related articles

Subscribe to our newsletter

Get the latest hosting tips, performance insights, and industry news.