NewTry MagicWP now - first month free
WordPress troubleshooting

MySQL server has gone away

WordPress had a working database connection and lost it mid-request. The query is rarely at fault; the connection is.

WordPress database error MySQL server has gone away for query …

Short answer

Three things drop a live connection: a query larger than max_allowed_packet, an idle period longer than wait_timeout, or MySQL restarting. Check whether the server has been up longer than the site has, because a low uptime answers the question immediately and the other two do not need testing.

Diagnosis

What causes it, most likely first.

Work down the list. Each check is written to rule its row in or out before you change anything, because the fixes below it are different and a guess costs more than a command.

CauseHow to checkFix
A query bigger than max_allowed_packetThe failure follows a large import, a post with a very large serialised meta value, or a backup restore — and it fails at the same point every time rather than randomly.Raise max_allowed_packet on the server to comfortably exceed the largest single statement. This is a server-side ceiling, so a client-side setting does not move it.
The connection idled past wait_timeoutLong admin operations fail near the end while ordinary page loads never do. The gap between two queries exceeded the timeout and MySQL closed the socket.Raise wait_timeout, or break the work into shorter batches so no single connection sits idle that long. Batching is the more durable of the two.
MySQL restarted or was killedServer uptime is shorter than the site's, or the error log records a shutdown. Out-of-memory kills are the usual reason on small machines.Find why it stopped before restarting it. A database that was killed once for memory will be killed again under the same load.
The database is refusing new workErrors cluster under load and clear when traffic drops, and the process list is close to max_connections.Reduce what is holding connections rather than raising the limit. Long-running queries occupying slots are the cause; a higher ceiling only delays the same failure.
Walkthrough

Fixing it, step by step.

Commands assume WP-CLI and shell access. Where you have neither, each step says what it is doing so it can be done from the dashboard or over SFTP instead.

  1. Ask how long the server has been running

    An uptime shorter than the last time the site worked means the database restarted, and nothing else on this list needs checking.

    mysqladmin status
    mysql -e "SHOW GLOBAL STATUS LIKE 'Uptime';"
  2. Read the two limits that matter

    Packet size and idle timeout account for most of what is left once a restart is ruled out.

    mysql -e "SHOW VARIABLES WHERE Variable_name IN ('max_allowed_packet','wait_timeout','interactive_timeout');"
  3. Raise the packet ceiling if an import is failing

    Set it in the server configuration rather than per session, so a restore run by any tool inherits it.

    [mysqld]
    max_allowed_packet = 256M
    wait_timeout = 300
  4. Check whether it was killed for memory

    The kernel log names the process it chose. This is the single most common cause on a small server running MySQL next to PHP.

    dmesg -T | grep -i -E 'out of memory|killed process' | tail -n 20
  5. Retry the operation in smaller pieces

    If the work is an import, batching keeps every statement well under the ceiling and every connection busy.

    wp db import dump.sql
    wp db check
On MagicWP

What the platform takes off the list.

The database runs in its own container with a memory allowance that belongs to it alone, so a PHP process that spikes cannot get MySQL killed by the kernel — the failure mode behind most of these errors on a single shared machine. Packet and timeout values are sized against that allowance rather than left at the distribution defaults that a large restore immediately exceeds.

FAQ

Questions, answered.

Is my data damaged?
No. The connection dropped; the tables were not touched. An import that failed halfway has written a partial dataset, which is a different problem and is fixed by re-running it after the limit is raised.
Why only during imports and backups?
Those are the only operations that send a single statement of that size or hold one connection for that long. Normal page loads issue small, quick queries and never approach either limit.
Should I just set wait_timeout very high?
It hides one cause and creates another: idle connections accumulate and occupy slots that new requests need. Fixing the long-running operation is better than letting it idle for longer.
How is this different from “error establishing a database connection”?
That one never got a connection. This one had it and lost it mid-request, which is why the site was working seconds earlier and why the fixes are completely different.
Related

If that was not it.

These fail in ways that look similar from the browser.