Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Troubleshooting

phpMyAdmin Upload Limit: The Four Numbers That Cap Your Import

Sean

Platform Writer

Sep 07, 2026
8 min read

The 2MB cap in phpMyAdmin is not a phpMyAdmin setting. It is PHP, and there are four values involved, which is why changing the obvious one so often does nothing at all.

phpMyAdmin Upload Limit: The Four Numbers That Cap Your Import

You export a database, go to import it on the new server, and phpMyAdmin tells you the file is too large. You find the advice to raise upload_max_filesize, you raise it, you retry, and you get the same error or a blank page halfway through. That is the normal experience, and it happens because the limit is enforced at four different layers that each have to agree.

Table of contents

Why the default is 2MB

phpMyAdmin displays whatever PHP tells it. PHP ships with upload_max_filesize = 2M in its default configuration, and most distribution packages leave it there. The number is not a database limit and has nothing to do with MySQL; it is a general guard against someone posting a large file to any PHP script on the box.

That default is fine for a contact form and useless for a database import, where a modest WordPress site can produce a 40MB dump without trying. So the value has to be raised deliberately, along with three others that would otherwise cut the import off before it finishes.

You can see all of the current values without touching a file:

php -i | grep -E 'upload_max_filesize|post_max_size|max_execution_time|max_input_time|memory_limit'

The four values that actually apply

Each one stops the import at a different point, which is why the symptoms differ so much between servers.

  • upload_max_filesize caps the size of the uploaded file itself. Exceed it and phpMyAdmin refuses before anything happens. This is the one everybody finds.
  • post_max_size caps the whole POST body, which is the file plus the form fields around it. It must be larger than upload_max_filesize or the upload fails silently with an empty file array. Set it a couple of megabytes higher.
  • max_execution_time caps how long the script may run. A large dump uploads fine and then dies mid-import with a blank page or a partially populated database. This is the nastiest failure, because it looks like success until you check the tables.
  • memory_limit caps how much memory the import may allocate. Too low and you get an allowed memory size exhausted fatal error partway through.

There is a fifth, max_input_time, which caps how long PHP will spend reading the incoming request. On a slow connection it matters; on a local network it usually does not. Set it alongside max_execution_time and stop thinking about it.

A working set for a 200MB dump:

upload_max_filesize = 256M
post_max_size = 260M
max_execution_time = 1200
max_input_time = 1200
memory_limit = 512M

Where to change them

The hard part is finding the file that is actually loaded. There are usually several php.ini files on a server and only one of them is in use.

php --ini
# Loaded Configuration File: /etc/php/8.3/fpm/php.ini

Note that the CLI and the web server frequently load different files. php --ini from a shell reports the CLI one. For a site served through PHP-FPM you want the fpm path, not the cli path. Editing the wrong one is the single most common reason the change appears to do nothing.

  • PHP-FPM. Edit the FPM php.ini, then sudo systemctl restart php8.3-fpm. A web server reload is not enough, because FPM holds the config.
  • Apache with mod_php. Edit the Apache php.ini and restart Apache. You can also set values per-directory in .htaccess with php_value upload_max_filesize 256M.
  • Docker images. Most phpMyAdmin images read an UPLOAD_LIMIT environment variable and write the PHP settings for you. Set UPLOAD_LIMIT=256M on the container and recreate it.
  • Shared hosting with a control panel. Look for a PHP settings or MultiPHP INI editor page. Some hosts also honour a .user.ini file in the web root containing the same directives.

After restarting, reload the phpMyAdmin import page and confirm the displayed maximum has changed. If it has not, you edited a file that is not loaded, and no amount of raising the number further will help.

The nginx cap nobody mentions

If you are behind nginx there is one more limit, and it is enforced before PHP ever sees the request. client_max_body_size defaults to 1MB, and exceeding it produces a 413 Request Entity Too Large from nginx itself.

The tell is that the error is not a phpMyAdmin error page. It is a bare nginx page, often unstyled, and it appears instantly rather than after an upload delay.

server {
    # ...
    client_max_body_size 256M;
}

Put it in the server block, or in http to apply it site-wide, then run sudo nginx -t && sudo systemctl reload nginx. Apache has an equivalent in LimitRequestBody, though it defaults to unlimited and rarely gets in the way.

A proxy or CDN in front of the web server can add its own limit on top of all this. If every setting on the box is correct and the upload still fails at a suspiciously round number, look at what is upstream.

The better answer: skip phpMyAdmin entirely

All of the above is worth knowing, and none of it is worth doing for a large import. phpMyAdmin uploads the dump through a web request and replays it through PHP, which is slow, memory-hungry, and has five separate ways to time out. The MySQL client has none of those problems.

mysql -u dbuser -p dbname < dump.sql

For a compressed dump, stream it rather than expanding it to disk first:

gunzip < dump.sql.gz | mysql -u dbuser -p dbname

If the import stops with a packet too large error, the dump contains a row bigger than the server’s max_allowed_packet. Raise it for the session rather than editing the config:

mysql -u dbuser -p --max_allowed_packet=512M dbname < dump.sql

This is faster by an order of magnitude and it reports errors properly instead of dying at a white page. If you have shell access at all, use it.

When the dump is genuinely too big

Past a few gigabytes, even the CLI import gets slow enough to want a plan. Three things help, in roughly this order.

  1. Keep extended inserts on. mysqldump batches rows into multi-row INSERT statements by default and they import far faster than one statement per row. If someone handed you a dump produced with --skip-extended-insert, re-dump it.
  2. Import schema and data separately. mysqldump --no-data then mysqldump --no-create-info. It makes failures easier to diagnose and lets you defer index creation until after the rows land.
  3. Split by table. mysqldump dbname table1 table2 produces per-table files you can import independently and retry individually. A failure in one no longer means starting over.

And if the reason you are doing this is a server migration, check whether the platform on the other end will simply take the dump for you. Restoring into a managed instance through its own tooling avoids the upload path entirely, which is the real fix.

How this fits the rest of the stack

Most of this friction is a symptom of managing the database and the web server as one box. When the database is a managed instance instead, imports go through a client connection rather than a PHP upload form, and the four PHP values stop being part of your life. A dashboard database browser covers the day-to-day work that sends people to phpMyAdmin in the first place: browsing tables, running SQL, and exporting or importing without SFTP. If you are sizing that setup, the RunxBuild hosting calculator shows the service and the database as separate line items, which is a more honest picture than a single blended hosting number.

Useful related references:

FAQ

Why is the phpMyAdmin upload limit 2MB?

Because that is the PHP default for upload_max_filesize, and most distributions ship it unchanged. phpMyAdmin simply reports whatever PHP allows. The value is a general protection for any PHP upload on the server and has nothing to do with MySQL or with phpMyAdmin itself.

I raised upload_max_filesize and nothing changed. Why?

Almost always because you edited a php.ini that is not the one your web server loads. Run php —ini to see the loaded file, and remember the CLI and PHP-FPM usually load different ones. The other common cause is that post_max_size is still lower than upload_max_filesize, which makes the upload fail silently.

What causes a 413 error when importing?

nginx, not PHP. The client_max_body_size directive defaults to 1MB and rejects the request before PHP is involved. Raise it in the server or http block and reload nginx. The giveaway is that the error page is a plain nginx one and appears immediately rather than after an upload delay.

How do I import a large SQL file without phpMyAdmin?

Use the mysql client directly with mysql -u user -p dbname and the dump redirected in, or pipe a compressed dump through gunzip. It is dramatically faster, has no upload or execution-time limits, and reports errors clearly instead of failing at a blank page.

My import finishes but tables are missing. What happened?

The script hit max_execution_time and PHP killed it partway through. The upload succeeded, so there is no upload error, but the replay stopped mid-file. Raise max_execution_time and memory_limit, or drop the database and re-import from the command line where neither limit applies.

#phpmyadmin upload limit#php.ini#mysql import#wordpress#database