<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web Hosting | John Nessime</title>
	<atom:link href="https://john-nessime.com/blog/tag/web-hosting/feed/" rel="self" type="application/rss+xml" />
	<link>https://john-nessime.com/blog/tag/web-hosting/</link>
	<description>Cloud, DevOps, Data &#38; AI — Built, Tested, Explained</description>
	<lastBuildDate>Thu, 30 Jul 2026 13:50:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://john-nessime.com/blog/wp-content/uploads/2026/07/cropped-jn-32x32.png</url>
	<title>Web Hosting | John Nessime</title>
	<link>https://john-nessime.com/blog/tag/web-hosting/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>DNS Troubleshooting: How to Find the Real Cause in Minutes, Not Hours</title>
		<link>https://john-nessime.com/blog/networking/dns-troubleshooting/</link>
					<comments>https://john-nessime.com/blog/networking/dns-troubleshooting/#respond</comments>
		
		<dc:creator><![CDATA[John Nessime]]></dc:creator>
		<pubDate>Thu, 30 Jul 2026 13:50:39 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Web Hosting]]></category>
		<category><![CDATA[BIND]]></category>
		<category><![CDATA[Cloudflare]]></category>
		<category><![CDATA[dig]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[DNS Cache]]></category>
		<category><![CDATA[DNS Records]]></category>
		<category><![CDATA[DNS Troubleshooting]]></category>
		<category><![CDATA[DNSSEC]]></category>
		<category><![CDATA[Domain Configuration]]></category>
		<category><![CDATA[Linux Networking]]></category>
		<category><![CDATA[MX Records]]></category>
		<category><![CDATA[Nameservers]]></category>
		<category><![CDATA[Network Debugging]]></category>
		<category><![CDATA[NSlookup]]></category>
		<category><![CDATA[NXDOMAIN]]></category>
		<category><![CDATA[SERVFAIL]]></category>
		<category><![CDATA[SPF]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[TTL]]></category>
		<guid isPermaLink="false">https://john-nessime.com/blog/?p=27</guid>

					<description><![CDATA[<p>Most "the site is down" tickets are really DNS problems wearing a costume. Here's the practical DNS troubleshooting workflow I use — how to read dig output, follow the delegation chain, decode SERVFAIL and NXDOMAIN, and stop blaming propagation for things that are actually caching, TTL, or DNSSEC failures.</p>
<p>The post <a href="https://john-nessime.com/blog/networking/dns-troubleshooting/">DNS Troubleshooting: How to Find the Real Cause in Minutes, Not Hours</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></description>
										<content:encoded><![CDATA[

<p class="wp-block-paragraph">Someone messages you: &#8220;the site is down.&#8221; You open it — it loads fine on your machine. You ask them to try again, and it still fails. Nothing changed on the server. Nothing changed in the code. And somewhere in the back of your head a small voice says: <em>it&#8217;s DNS again.</em></p>



<p class="wp-block-paragraph">It usually is. Not because DNS is fragile, but because it&#8217;s the one layer where caching, delegation, and propagation all conspire to make the same domain behave differently depending on who&#8217;s asking and when. A record can be perfectly correct in your control panel and still resolve to the wrong IP for half the internet.</p>



<p class="wp-block-paragraph">This article is the DNS troubleshooting workflow I actually use — the order of checks, the commands worth memorising, how to read what they tell you, and the specific failure patterns that show up over and over. No theory dumps. Just the path from &#8220;something&#8217;s broken&#8221; to &#8220;here&#8217;s exactly which record on which server is wrong.&#8221;</p>



<h2 class="wp-block-heading">First, Get the Mental Model Right</h2>



<p class="wp-block-paragraph">You can&#8217;t debug a system you don&#8217;t have a picture of. When a browser resolves <code>example.com</code>, several independent parties are involved, and any one of them can be the liar:</p>



<ol class="wp-block-list"><li><strong>The application</strong> — browsers keep their own short-lived DNS cache, and HSTS or connection pooling can mask changes entirely.</li><li><strong>The operating system</strong> — the local stub resolver, <code>/etc/hosts</code>, <code>nscd</code>, <code>systemd-resolved</code>, or the Windows DNS Client service.</li><li><strong>The recursive resolver</strong> — your router, your ISP, or a public resolver like 1.1.1.1 or 8.8.8.8. This is where most stale answers live.</li><li><strong>The delegation chain</strong> — root servers, then the TLD servers, then whichever name servers your registrar says are authoritative.</li><li><strong>The authoritative name server</strong> — the only place where the truth actually lives.</li></ol>



<p class="wp-block-paragraph">Effective DNS troubleshooting is just working down that list and asking each party the same question directly, instead of trusting whatever the browser tells you. The moment you find two parties giving different answers, you&#8217;ve found your boundary — and the problem is between them.</p>



<h2 class="wp-block-heading">The Tools That Matter</h2>



<p class="wp-block-paragraph">You need surprisingly few. My honest ranking:</p>



<h3 class="wp-block-heading">dig — the one you should learn properly</h3>



<p class="wp-block-paragraph"><code>dig</code> is the only tool that shows you everything: the query it sent, the response status, the TTL remaining, the authority section, and whether the answer came from a cache or from the source. On Debian and Ubuntu it lives in <code>dnsutils</code>; on RHEL-family systems it&#8217;s in <code>bind-utils</code>.</p>



<pre class="wp-block-code"><code># Just the answer, nothing else
dig +short example.com A

# The full picture — status, flags, TTL, authority
dig example.com A

# Ask one specific resolver instead of the system default
dig @1.1.1.1 example.com A

# Ask a specific authoritative server directly
dig @ns1.example-dns.com example.com A</code></pre>



<h3 class="wp-block-heading">host — for quick sanity checks</h3>



<pre class="wp-block-code"><code>host example.com
host -t MX example.com
host -t TXT example.com</code></pre>



<h3 class="wp-block-heading">nslookup — fine, but know its limits</h3>



<p class="wp-block-paragraph"><code>nslookup</code> is everywhere, including Windows, which is its main virtue. But it hides details you often need, and its &#8220;Non-authoritative answer&#8221; banner confuses people constantly — it simply means the answer came from a cache rather than the authoritative server. That&#8217;s completely normal. On Windows I reach for PowerShell instead:</p>



<pre class="wp-block-code"><code>Resolve-DnsName example.com -Type A
Resolve-DnsName example.com -Server 1.1.1.1</code></pre>



<h3 class="wp-block-heading">resolvectl — essential on modern Linux</h3>



<p class="wp-block-paragraph">If the machine runs <code>systemd-resolved</code>, your <code>/etc/resolv.conf</code> probably points at <code>127.0.0.53</code>, which tells you nothing about the real upstream servers. <code>resolvectl</code> does:</p>



<pre class="wp-block-code"><code>resolvectl status
resolvectl query example.com
resolvectl statistics</code></pre>



<h3 class="wp-block-heading">getent — the reality check</h3>



<p class="wp-block-paragraph"><code>dig</code> talks to DNS. Your applications talk to the C library resolver, which also consults <code>/etc/hosts</code> and whatever else <code>/etc/nsswitch.conf</code> lists. When <code>dig</code> and the application disagree, this is the command that explains why:</p>



<pre class="wp-block-code"><code>getent hosts example.com
getent ahosts example.com</code></pre>



<h2 class="wp-block-heading">A Repeatable DNS Troubleshooting Workflow</h2>



<p class="wp-block-paragraph">This is the sequence. Don&#8217;t skip ahead — each step eliminates a whole class of causes, and jumping straight to the authoritative server is how you spend an hour fixing something that was never broken.</p>



<h3 class="wp-block-heading">Step 1 — Confirm it&#8217;s actually DNS</h3>



<p class="wp-block-paragraph">Resolve the name, then connect to the resulting IP directly. If the IP works and the name doesn&#8217;t, it&#8217;s DNS. If neither works, you&#8217;re troubleshooting the wrong layer.</p>



<pre class="wp-block-code"><code>dig +short example.com A
curl -I --resolve example.com:443:203.0.113.10 https://example.com/</code></pre>



<p class="wp-block-paragraph">The <code>--resolve</code> flag is underrated. It forces curl to use an IP you specify while still sending the correct Host header and SNI, which lets you test the web server as if DNS were already fixed. Replace <code>203.0.113.10</code> with the IP you expect.</p>



<h3 class="wp-block-heading">Step 2 — Compare local vs public resolvers</h3>



<pre class="wp-block-code"><code>dig +short example.com A
dig +short @1.1.1.1 example.com A
dig +short @8.8.8.8 example.com A
dig +short @9.9.9.9 example.com A</code></pre>



<p class="wp-block-paragraph">If your local answer differs from all three public resolvers, the problem is on your side — a cache, a hosts file entry, a VPN pushing internal DNS, or a router doing something creative. If all four agree but the answer is wrong, the problem is upstream at the authoritative layer.</p>



<h3 class="wp-block-heading">Step 3 — Find out who is actually authoritative</h3>



<p class="wp-block-paragraph">This is the step people skip, and it&#8217;s the one that catches the nastiest problems. The name servers listed in your DNS provider&#8217;s dashboard are not necessarily the ones the internet is using.</p>



<pre class="wp-block-code"><code># What the parent zone (the registry) says
dig +short NS example.com

# What the zone itself says, straight from one of those servers
dig @ns1.example-dns.com example.com NS</code></pre>



<p class="wp-block-paragraph">Those two lists should match. When they don&#8217;t, you&#8217;ve usually found a half-finished DNS migration: the registrar still delegates to the old provider, so the world keeps reading a zone nobody has updated in months.</p>



<h3 class="wp-block-heading">Step 4 — Query every authoritative server individually</h3>



<p class="wp-block-paragraph">A zone with four name servers can be inconsistent across them if a zone transfer failed. Intermittent, &#8220;it works every third time&#8221; problems are almost always this. Compare the SOA serial on each:</p>



<pre class="wp-block-code"><code># Pull the SOA record from every authoritative server in one shot
dig +nssearch example.com

# Or check them one by one
dig +short @ns1.example-dns.com example.com SOA
dig +short @ns2.example-dns.com example.com SOA</code></pre>



<p class="wp-block-paragraph">Different serial numbers mean the secondaries haven&#8217;t caught up with the primary. Different answers for the same record mean something is genuinely broken in replication.</p>



<h3 class="wp-block-heading">Step 5 — Walk the delegation chain</h3>



<p class="wp-block-paragraph">When nothing else explains it, follow the query the way a recursive resolver would — from the root, down through the TLD, to the authoritative servers:</p>



<pre class="wp-block-code"><code>dig +trace example.com A</code></pre>



<p class="wp-block-paragraph">Read it top to bottom. Each block is one hop. The point where the output stops making sense — a referral to servers that don&#8217;t answer, a missing glue record, an unexpected NXDOMAIN — is your break point. This single command has saved me more time than any other in DNS troubleshooting.</p>



<h2 class="wp-block-heading">Reading dig Output Without Guessing</h2>



<p class="wp-block-paragraph">The status line in a <code>dig</code> response tells you the category of failure immediately. Learn these four and you&#8217;ve eliminated most of the guesswork.</p>



<ul class="wp-block-list"><li><strong>NOERROR</strong> — the query succeeded. Note that NOERROR with an empty answer section is <em>not</em> a failure: it means the name exists but has no record of the type you asked for. Asking for an A record on a name that only has MX records gives you exactly this.</li><li><strong>NXDOMAIN</strong> — the name does not exist at all. Not a typo in the record; the label itself isn&#8217;t in the zone. Check for a missing record, a misspelled hostname, or a zone that isn&#8217;t loaded.</li><li><strong>SERVFAIL</strong> — the resolver tried and failed. This is the ambiguous one, and in practice it usually means DNSSEC validation failure, an authoritative server that&#8217;s unreachable or refusing queries, or a broken delegation.</li><li><strong>REFUSED</strong> — the server you asked is not willing to answer for that zone. Typically you&#8217;re querying a server that isn&#8217;t authoritative and doesn&#8217;t do recursion for you.</li></ul>



<p class="wp-block-paragraph">Two other things worth reading in every response:</p>



<ul class="wp-block-list"><li><strong>The <code>aa</code> flag</strong> — present when the answer came from an authoritative server. If it&#8217;s missing, you&#8217;re looking at a cached answer, and the TTL tells you how stale it might be.</li><li><strong>The TTL column</strong> — on a cached answer this counts <em>down</em>. Query the same resolver twice a few seconds apart; if the TTL drops, you&#8217;re being served from cache. If it stays constant, you&#8217;re hitting the source.</li></ul>




<h2 class="wp-block-heading">The Propagation Myth (and What&#8217;s Really Happening)</h2>



<p class="wp-block-paragraph">&#8220;DNS propagation takes 24 to 48 hours&#8221; is the most repeated and least accurate sentence in web hosting. Nothing propagates. When you change a record, the authoritative server has the new value instantly. What takes time is the expiry of cached copies held by thousands of independent resolvers — and that duration is entirely determined by the TTL you set <em>before</em> the change.</p>



<p class="wp-block-paragraph">The practical consequence: lowering a TTL after you&#8217;ve made the change does nothing for anyone who already cached the old value. Plan ahead instead.</p>



<ol class="wp-block-list"><li>Well before a migration, drop the TTL on the records you&#8217;ll change to something short — 300 seconds is a common choice.</li><li>Wait at least the length of the <em>old</em> TTL so the short value fully replaces it in caches.</li><li>Make the actual change. Old cached answers now expire within minutes.</li><li>Verify against several public resolvers and from a couple of different networks.</li><li>Once everything is stable, raise the TTL back to something sane — an hour or more — so you&#8217;re not paying for lookups you don&#8217;t need.</li></ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">The TTL you set today determines how painful next month&#8217;s migration will be. It&#8217;s the cheapest piece of planning in infrastructure work, and the one most consistently skipped.</p>
</blockquote>



<p class="wp-block-paragraph">One more thing people miss: <strong>negative caching</strong>. When a lookup returns NXDOMAIN, resolvers cache that &#8220;doesn&#8217;t exist&#8221; answer too, for a duration derived from the minimum field in the zone&#8217;s SOA record. So if you query a hostname <em>before</em> creating it, you may keep getting NXDOMAIN for a while even after the record is live. Check what you&#8217;re in for:</p>



<pre class="wp-block-code"><code>dig +short example.com SOA</code></pre>



<p class="wp-block-paragraph">The last number in that output is the negative caching TTL. Resist the urge to test a hostname before you&#8217;ve actually created it.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Failure Patterns You&#8217;ll Meet Again and Again</h2>



<h3 class="wp-block-heading">A CNAME on the zone apex</h3>



<p class="wp-block-paragraph">You cannot put a plain CNAME on the root of a domain. The apex must carry SOA and NS records, and a CNAME is not allowed to coexist with other records at the same name. Providers work around this with ALIAS, ANAME, or &#8220;CNAME flattening&#8221; records that resolve the target server-side and return an A record. If your root domain misbehaves while <code>www</code> is fine, this is the first thing to check.</p>



<h3 class="wp-block-heading">Stale cache — everywhere at once</h3>



<p class="wp-block-paragraph">Correct at the authoritative server, wrong on your machine. Clear caches from the outside in:</p>



<pre class="wp-block-code"><code># Linux with systemd-resolved
sudo resolvectl flush-caches

# Linux with nscd
sudo systemctl restart nscd

# macOS
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

# Windows (run as Administrator)
ipconfig /flushdns</code></pre>



<p class="wp-block-paragraph">Then remember the browser. Chromium-based browsers keep a separate cache you can clear at <code>chrome://net-internals/#dns</code>. And if the site uses HSTS, a browser may refuse to fall back to HTTP regardless of what DNS says — test with <code>curl</code> before you conclude anything from a browser.</p>



<h3 class="wp-block-heading">A forgotten line in /etc/hosts</h3>



<p class="wp-block-paragraph">Someone adds a hosts entry during a migration to test the new server, and never removes it. Six months later the server is &#8220;randomly&#8221; hitting the wrong backend. It costs three seconds to rule out:</p>



<pre class="wp-block-code"><code>grep -i example.com /etc/hosts
getent hosts example.com</code></pre>



<h3 class="wp-block-heading">DNSSEC validation failures</h3>



<p class="wp-block-paragraph">A domain with broken DNSSEC returns SERVFAIL from validating resolvers while working perfectly on non-validating ones. That produces the maddening symptom where the site loads for some users and not others, with no geographic pattern.</p>



<p class="wp-block-paragraph">The diagnostic trick is <code>+cd</code>, which disables validation. If the query fails normally but succeeds with <code>+cd</code>, DNSSEC is your culprit:</p>



<pre class="wp-block-code"><code>dig @1.1.1.1 example.com A
dig @1.1.1.1 +cd example.com A

# Show the DNSSEC records themselves
dig example.com DNSKEY +dnssec
dig example.com DS

# delv performs validation and explains the outcome
delv example.com A</code></pre>



<p class="wp-block-paragraph">The usual cause is a DS record at the registrar that no longer matches the keys published in the zone — classic after changing DNS providers without disabling DNSSEC first. <strong>Always turn DNSSEC off at the registrar before migrating name servers, then re-enable it once the new provider is live and stable.</strong></p>



<h3 class="wp-block-heading">Split-horizon DNS surprises</h3>



<p class="wp-block-paragraph">Internal resolvers hand out private addresses; external resolvers hand out public ones. Perfectly intentional — until a VPN, a container, or a misconfigured search domain puts a client on the wrong side of the split. When a name resolves differently depending on <em>where</em> you run the query, compare the local resolver against a public one and check whether a VPN profile is pushing its own DNS servers.</p>



<h3 class="wp-block-heading">Proxied records hiding the origin</h3>



<p class="wp-block-paragraph">If a domain sits behind Cloudflare or a similar proxy, public DNS returns the proxy&#8217;s IP, not your server&#8217;s. That&#8217;s the whole point — but it means you cannot verify an origin change through public DNS at all. Query the authoritative provider&#8217;s own API or dashboard for the real record value, and test the origin directly with <code>curl --resolve</code>.</p>



<h3 class="wp-block-heading">Wildcards masking a missing record</h3>



<p class="wp-block-paragraph">A <code>*</code> record in the zone means every hostname resolves — including the ones you typo&#8217;d, and including subdomains you thought you&#8217;d deleted. If everything resolves but half of it points somewhere unexpected, check for a wildcard before you go hunting for phantom records.</p>



<h3 class="wp-block-heading">Missing trailing dots in zone files</h3>



<p class="wp-block-paragraph">Hand-editing BIND zone files? A record value without a trailing dot gets the origin appended to it. Write <code>mail.example.com</code> instead of <code>mail.example.com.</code> and you&#8217;ve just created <code>mail.example.com.example.com</code>. Validate before reloading:</p>



<pre class="wp-block-code"><code>named-checkconf
named-checkzone example.com /var/named/example.com.zone</code></pre>



<p class="wp-block-paragraph">And bump the SOA serial. A zone edit without a serial increment won&#8217;t reach the secondaries, which is exactly the inconsistency you were chasing in Step 4.</p>



<h3 class="wp-block-heading">Containers and the ndots trap</h3>



<p class="wp-block-paragraph">Inside Kubernetes pods, <code>/etc/resolv.conf</code> commonly sets <code>ndots:5</code>. Any name with fewer than five dots gets tried against every search domain first, so an external lookup like <code>api.example.com</code> can generate several failed queries before the correct one. It works — it&#8217;s just slow, and under load it looks like intermittent DNS failure. Adding a trailing dot to fully qualify the name skips the search list entirely:</p>



<pre class="wp-block-code"><code>cat /etc/resolv.conf
dig api.example.com.        # note the trailing dot</code></pre>



<h2 class="wp-block-heading">DNS Troubleshooting for Email Delivery</h2>



<p class="wp-block-paragraph">Mail problems are DNS problems more often than they are mail-server problems. When messages bounce or land in spam, check these before touching the mail server config:</p>



<pre class="wp-block-code"><code># Where should mail for this domain go?
dig +short example.com MX

# SPF and DMARC live in TXT records
dig +short example.com TXT
dig +short _dmarc.example.com TXT

# DKIM lives under a selector you choose
dig +short selector1._domainkey.example.com TXT

# Reverse DNS for the sending IP
dig -x 203.0.113.10 +short</code></pre>



<p class="wp-block-paragraph">Things that regularly go wrong here:</p>



<ul class="wp-block-list"><li><strong>Two SPF records.</strong> A domain must publish exactly one. Two SPF TXT records is a permanent error, and receiving servers are entitled to fail the check outright. Merge them into one.</li><li><strong>An MX pointing at a CNAME.</strong> MX targets must resolve to address records, not aliases.</li><li><strong>Missing reverse DNS.</strong> If the PTR record for your sending IP doesn&#8217;t match the hostname the server announces, expect a lot of spam folder.</li><li><strong>DKIM selector mismatch.</strong> The selector in the message header must match the one published in DNS — a detail that quietly breaks after a mail platform migration.</li></ul>



<p class="wp-block-paragraph">While you&#8217;re in TXT territory: if certificate issuance is failing, check for a CAA record. A CAA entry that only authorises one certificate authority will silently block every other one, and the error you get back from the ACME client rarely says &#8220;DNS.&#8221;</p>



<pre class="wp-block-code"><code>dig +short example.com CAA</code></pre>



<h2 class="wp-block-heading">Mistakes That Cost the Most Time</h2>



<ul class="wp-block-list"><li><strong>Testing only in a browser.</strong> Browser caches, HSTS, service workers, and QUIC connection reuse will all lie to you. Confirm with <code>dig</code> and <code>curl</code>.</li><li><strong>Trusting the control panel.</strong> The dashboard shows what the zone <em>should</em> contain. Only a query against the authoritative server shows what it actually serves.</li><li><strong>Changing several things at once.</strong> Adjust one record, verify, then move on. Batch changes turn a five-minute fix into an archaeology project.</li><li><strong>Forgetting IPv6.</strong> A stale or wrong AAAA record produces &#8220;works for some people&#8221; behaviour, because dual-stack clients generally prefer IPv6. Always check <code>dig +short example.com AAAA</code>.</li><li><strong>Leaving DNSSEC enabled through a provider migration.</strong> The single most reliable way to take a domain fully offline for hours.</li><li><strong>Not documenting the zone before a migration.</strong> Export or record every record first. Rebuilding a zone from memory at 2am is not a plan.</li></ul>



<h2 class="wp-block-heading">Best Practices That Prevent the Next Incident</h2>



<ul class="wp-block-list"><li><strong>Use at least two name servers</strong>, ideally on separate networks or providers. Single-provider DNS is a single point of failure for your entire presence.</li><li><strong>Keep TTLs deliberate.</strong> Long TTLs for stable infrastructure, short ones ahead of planned changes. Not the other way round.</li><li><strong>Monitor DNS resolution itself</strong>, not just HTTP endpoints. A check that queries your authoritative servers directly and alerts on a changed or missing answer catches problems before users do.</li><li><strong>Version-control your zone data</strong> if your provider supports API or zone-file export. Diffing two zone versions turns &#8220;what changed?&#8221; into a one-second question.</li><li><strong>Keep a record inventory</strong> — what each record is for, who owns it, and whether it&#8217;s still needed. Old A records pointing at decommissioned servers are a genuine security risk, not just clutter.</li><li><strong>Standardise your checks.</strong> A short script that runs your Step 1–5 sequence against a domain makes DNS troubleshooting repeatable instead of improvised.</li></ul>



<h2 class="wp-block-heading">A Quick Reference You Can Keep</h2>



<pre class="wp-block-code"><code># Basic resolution
dig +short example.com A
dig +short example.com AAAA

# Compare resolvers
dig +short @1.1.1.1 example.com A
dig +short @8.8.8.8 example.com A

# Authority and delegation
dig +short example.com NS
dig +trace example.com A
dig +nssearch example.com

# Cache behaviour
dig example.com A            # watch the TTL count down
dig +norecurse @1.1.1.1 example.com A   # cached-only lookup

# DNSSEC
dig +cd example.com A
delv example.com A

# Mail and verification records
dig +short example.com MX
dig +short example.com TXT
dig +short _dmarc.example.com TXT
dig -x 203.0.113.10 +short

# System-level view
resolvectl status
getent hosts example.com
cat /etc/resolv.conf</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Frequently Asked Questions</h2>



<h3 class="wp-block-heading">How long does a DNS change really take to take effect?</h3>



<p class="wp-block-paragraph">At the authoritative server, immediately. For everyone else, up to the TTL that was in place when they last cached the record. If the old TTL was 3600 seconds, worst case is roughly an hour. The &#8220;24 to 48 hours&#8221; figure is a legacy of very long default TTLs and badly behaved resolvers, not a rule.</p>



<h3 class="wp-block-heading">What&#8217;s the difference between SERVFAIL and NXDOMAIN?</h3>



<p class="wp-block-paragraph">NXDOMAIN is a definitive answer: the name doesn&#8217;t exist. SERVFAIL means the resolver couldn&#8217;t produce an answer at all — commonly a DNSSEC validation failure, an unreachable authoritative server, or a broken delegation. NXDOMAIN points you at the zone contents; SERVFAIL points you at the infrastructure.</p>



<h3 class="wp-block-heading">Why does the site work for me but not for a colleague?</h3>



<p class="wp-block-paragraph">Different resolvers with different cache states, a hosts file entry on one machine, a VPN pushing internal DNS, an IPv6 versus IPv4 difference, or DNSSEC failing only on validating resolvers. Have both people run the same <code>dig</code> against the same public resolver — if the answers match, the difference is local to one machine.</p>



<h3 class="wp-block-heading">Should I use dig or nslookup?</h3>



<p class="wp-block-paragraph"><code>dig</code>, whenever it&#8217;s available. It shows response status, flags, TTLs and the authority section, all of which you need for real DNS troubleshooting. Use <code>nslookup</code> or <code>Resolve-DnsName</code> when you&#8217;re on a Windows box without other tooling.</p>



<h3 class="wp-block-heading">Do online &#8220;DNS propagation checker&#8221; sites actually help?</h3>



<p class="wp-block-paragraph">They&#8217;re useful for one thing: seeing what different resolvers around the world currently have cached. They won&#8217;t tell you <em>why</em> an answer is wrong, and they can&#8217;t see proxied origins or internal split-horizon zones. Treat them as a rough sanity check, not a diagnosis.</p>



<h3 class="wp-block-heading">Can a CNAME point to another CNAME?</h3>



<p class="wp-block-paragraph">Technically yes, and resolvers will follow the chain — but every extra hop adds latency and another thing to break. Keep chains short, and never let one loop back on itself. Also remember a CNAME cannot coexist with other records at the same name, which is why it doesn&#8217;t belong on a zone apex.</p>



<h3 class="wp-block-heading">Why do my DNS changes keep reverting?</h3>



<p class="wp-block-paragraph">Usually because something else owns the zone: an infrastructure-as-code pipeline, a control panel that rewrites records on certain actions, or an external DNS controller in a Kubernetes cluster. Decide on one source of truth and make every change through it.</p>



<h3 class="wp-block-heading">Is switching to a public resolver a fix?</h3>



<p class="wp-block-paragraph">It&#8217;s a workaround for one user, not a fix for the domain. It&#8217;s genuinely useful as a diagnostic — if 1.1.1.1 gives the right answer and your ISP&#8217;s resolver doesn&#8217;t, you&#8217;ve isolated the problem to that resolver&#8217;s cache. But if the record itself is wrong, changing resolvers just changes who tells you the wrong thing.</p>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p class="wp-block-paragraph">Good DNS troubleshooting isn&#8217;t about knowing obscure record types. It&#8217;s about discipline: confirm it&#8217;s DNS, compare resolvers, find out who&#8217;s really authoritative, ask each of them directly, and follow the delegation chain when the answers stop agreeing. Five steps, in order, every time.</p>



<p class="wp-block-paragraph">Do that consistently and most incidents collapse into something small and obvious — a stale cache, a TTL nobody lowered, a DS record left behind after a migration, a hosts entry from six months ago. The problems aren&#8217;t usually exotic. They&#8217;re just invisible until you ask the right party the right question.</p>



<p class="wp-block-paragraph">Keep the quick-reference commands somewhere you can reach in thirty seconds, set your TTLs before you need them, and monitor resolution as seriously as you monitor uptime. Future you will appreciate it at 2am.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Need a Hand With DNS, Hosting or Cloud Infrastructure?</h2>



<p class="wp-block-paragraph">If you&#8217;re stuck on a DNS issue, planning a migration you&#8217;d rather not do twice, or you just want someone to review a zone before you flip the switch, I&#8217;m available for freelance work.</p>



<p class="wp-block-paragraph">I work on DNS configuration and troubleshooting, domain and hosting migrations, SSL and certificate issues, email deliverability records (SPF, DKIM, DMARC), server setup and hardening, AWS and cloud infrastructure, and monitoring and alerting — plus WordPress performance and maintenance.</p>



<p class="wp-block-paragraph">You can see my profile, past work and reviews on Upwork, and message me directly there with what you&#8217;re dealing with.</p>



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://www.upwork.com/freelancers/~01f15a912ad84a6620" target="_blank" rel="noreferrer noopener">Hire Me on Upwork</a></div>
</div>



<p class="wp-block-paragraph">Got a DNS problem this article didn&#8217;t cover? Leave a comment describing the symptoms and what <code>dig +trace</code> shows — that output alone usually narrows it down fast.</p>

<!-- /wp:post-content --><p>The post <a href="https://john-nessime.com/blog/networking/dns-troubleshooting/">DNS Troubleshooting: How to Find the Real Cause in Minutes, Not Hours</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://john-nessime.com/blog/networking/dns-troubleshooting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPress Migration Without Downtime: A Practical Guide to Moving Your Website Safely</title>
		<link>https://john-nessime.com/blog/wordpress/wordpress-migration-without-downtime/</link>
					<comments>https://john-nessime.com/blog/wordpress/wordpress-migration-without-downtime/#respond</comments>
		
		<dc:creator><![CDATA[John Nessime]]></dc:creator>
		<pubDate>Thu, 16 Jul 2026 20:32:36 +0000</pubDate>
				<category><![CDATA[Hosting & Infrastructure]]></category>
		<category><![CDATA[Technical Guides]]></category>
		<category><![CDATA[Website Management]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[DNS Migration]]></category>
		<category><![CDATA[SSL Certificate]]></category>
		<category><![CDATA[Web Hosting]]></category>
		<category><![CDATA[Website Downtime]]></category>
		<category><![CDATA[Website Migration]]></category>
		<category><![CDATA[Website Performance]]></category>
		<category><![CDATA[WordPress Backup]]></category>
		<category><![CDATA[WordPress Database]]></category>
		<category><![CDATA[WordPress Hosting]]></category>
		<category><![CDATA[WordPress Migration]]></category>
		<guid isPermaLink="false">https://john-nessime.com/blog/?p=23</guid>

					<description><![CDATA[<p>Moving a WordPress website involves much more than copying files. This practical migration guide explains how to transfer WordPress safely, minimize downtime, protect SEO, preserve email services, and avoid lost data.</p>
<p>The post <a href="https://john-nessime.com/blog/wordpress/wordpress-migration-without-downtime/">WordPress Migration Without Downtime: A Practical Guide to Moving Your Website Safely</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></description>
										<content:encoded><![CDATA[


<p class="wp-block-paragraph">Moving a WordPress website sounds simple until the site contains years of content, customer data, business emails, analytics integrations, payment systems, and search-engine rankings that cannot afford to disappear.</p>




<p class="wp-block-paragraph">A successful WordPress migration is not just a matter of copying files from one server to another. It is a controlled infrastructure change involving the website files, database, domain records, SSL certificate, email configuration, caching layers, scheduled tasks, security settings, and third-party integrations.</p>




<p class="wp-block-paragraph">When the process is planned correctly, visitors may never notice that the website has moved. When it is rushed, the result can include broken pages, missing images, database errors, lost form submissions, email disruption, redirect loops, certificate warnings, or several hours of downtime.</p>




<p class="wp-block-paragraph">This guide explains how to migrate a WordPress website safely, how to reduce downtime, what can go wrong, and what should be verified before the old hosting environment is finally switched off.</p>




<h2 class="wp-block-heading">What Is a WordPress Migration?</h2>




<p class="wp-block-paragraph">A WordPress migration is the process of moving a WordPress website from one environment to another. The destination might be a new hosting provider, a cloud server, a virtual private server, a staging environment, a new domain, or a different server configuration.</p>




<p class="wp-block-paragraph">The website may look like a single application from the visitor’s perspective, but several separate components normally need to be transferred:</p>




<ul class="wp-block-list">
<li>WordPress core files</li>
<li>Theme files</li>
<li>Plugin files</li>
<li>Uploaded media</li>
<li>The MySQL or MariaDB database</li>
<li>Configuration files</li>
<li>Custom code and server rules</li>
<li>DNS records</li>
<li>SSL certificates</li>
<li>Email-related DNS records</li>
<li>Cron jobs and scheduled tasks</li>
<li>CDN and caching configuration</li>
<li>Analytics and tracking scripts</li>
<li>External API integrations</li>
</ul>




<p class="wp-block-paragraph">A complete migration must preserve both the visible website and the underlying functionality. Copying the homepage successfully is not enough if contact forms stop sending, checkout sessions fail, redirects break, or administrators can no longer log in.</p>




<h2 class="wp-block-heading">Common Reasons for Migrating a WordPress Website</h2>




<p class="wp-block-paragraph">Website owners migrate WordPress installations for many different reasons. In most cases, the decision is connected to performance, reliability, cost, control, or security.</p>




<h3 class="wp-block-heading">Slow Hosting Performance</h3>




<p class="wp-block-paragraph">A website may outgrow its original shared hosting plan. Pages become slow, the WordPress dashboard takes longer to load, and traffic spikes begin causing resource-limit errors. Moving to a better-managed host, VPS, or cloud server can provide more CPU, memory, storage performance, and configuration flexibility.</p>




<h3 class="wp-block-heading">Frequent Downtime</h3>




<p class="wp-block-paragraph">Unreliable infrastructure can damage customer trust and search visibility. If the current host experiences repeated outages or provides weak technical support, migration may be the most practical long-term solution.</p>




<h3 class="wp-block-heading">Security Concerns</h3>




<p class="wp-block-paragraph">Outdated server software, poor account isolation, weak backup systems, or limited firewall controls can expose a WordPress website to unnecessary risk. A migration can be used as an opportunity to rebuild the site on a cleaner and more secure environment.</p>




<h3 class="wp-block-heading">Hosting Cost Optimization</h3>




<p class="wp-block-paragraph">Some hosting plans become expensive as traffic grows, especially when backups, staging, CDN access, email, malware scanning, or additional storage are charged separately. Migrating to a more suitable platform can reduce costs without sacrificing performance.</p>




<h3 class="wp-block-heading">Business Growth</h3>




<p class="wp-block-paragraph">A small brochure website may eventually become a membership platform, online store, booking portal, or content-heavy publication. The original environment may no longer support the website’s operational requirements.</p>




<h3 class="wp-block-heading">Domain or Branding Changes</h3>




<p class="wp-block-paragraph">Some migrations involve changing the domain name as well as the server. This requires additional planning because internal URLs, redirects, analytics properties, search-engine records, cookies, and third-party callbacks may all depend on the original domain.</p>




<h2 class="wp-block-heading">The Difference Between a Simple Migration and a Production Migration</h2>




<p class="wp-block-paragraph">A small personal blog with few updates can often be moved using a migration plugin. A production website requires more care.</p>




<p class="wp-block-paragraph">Production websites may receive new orders, registrations, comments, bookings, support requests, or form submissions while the migration is taking place. If the database is copied too early and DNS is updated hours later, any data created during that gap may remain only on the old server.</p>




<p class="wp-block-paragraph">That is why a production migration should be treated as a controlled cutover rather than a one-click file transfer. The objective is to minimize the period during which the old and new environments contain different information.</p>




<h2 class="wp-block-heading">What Can Go Wrong During a WordPress Migration?</h2>




<p class="wp-block-paragraph">Most migration problems fall into a predictable set of categories. Knowing them in advance makes the process easier to plan and troubleshoot.</p>




<h3 class="wp-block-heading">Database Connection Errors</h3>




<p class="wp-block-paragraph">The WordPress configuration file may contain the wrong database name, username, password, or database host. The user may also lack the necessary permissions on the destination database.</p>




<h3 class="wp-block-heading">Broken Internal URLs</h3>




<p class="wp-block-paragraph">WordPress stores URLs in the database. If the domain, protocol, folder path, or staging address changes, old references can remain inside posts, menus, widgets, page-builder content, serialized options, and plugin settings.</p>




<h3 class="wp-block-heading">Missing Images or Media Files</h3>




<p class="wp-block-paragraph">The uploads directory may be incomplete, excluded from the transfer, or copied with incorrect ownership and permissions. A site may appear functional while older images silently return 404 errors.</p>




<h3 class="wp-block-heading">PHP Compatibility Problems</h3>




<p class="wp-block-paragraph">The destination server may use a newer PHP version than the original host. An outdated theme or plugin can then generate warnings, fatal errors, blank pages, or broken administrative screens.</p>




<h3 class="wp-block-heading">Redirect Loops</h3>




<p class="wp-block-paragraph">Conflicting HTTPS, proxy, CDN, and WordPress redirect rules can cause the browser to repeatedly redirect between two versions of the same URL.</p>




<h3 class="wp-block-heading">Email Delivery Failure</h3>




<p class="wp-block-paragraph">A migration may affect outgoing form emails, SMTP authentication, domain verification, or mailbox routing. DNS changes can also unintentionally overwrite MX, SPF, DKIM, or DMARC records.</p>




<h3 class="wp-block-heading">SSL Certificate Warnings</h3>




<p class="wp-block-paragraph">The destination server may not yet have a valid certificate, or the certificate may not cover every hostname used by the website. Mixed-content warnings can also appear when pages load images, scripts, or stylesheets through HTTP.</p>




<h3 class="wp-block-heading">Lost Transactions or Form Submissions</h3>




<p class="wp-block-paragraph">This is one of the most serious risks. If visitors continue using the old website after the final database backup, their activity may not exist on the new server.</p>




<h2 class="wp-block-heading">Phase One: Audit the Existing Website</h2>




<p class="wp-block-paragraph">Before copying anything, document the current environment. A migration is much safer when the source system is fully understood.</p>




<p class="wp-block-paragraph">The audit should include:</p>




<ul class="wp-block-list">
<li>Current WordPress version</li>
<li>PHP version and PHP extensions</li>
<li>Database engine and version</li>
<li>Active theme and child theme</li>
<li>Active and inactive plugins</li>
<li>Disk usage</li>
<li>Database size</li>
<li>Upload directory size</li>
<li>Web server type</li>
<li>Caching configuration</li>
<li>Scheduled cron tasks</li>
<li>CDN or reverse proxy usage</li>
<li>External SMTP provider</li>
<li>Payment and booking integrations</li>
<li>DNS provider</li>
<li>SSL configuration</li>
<li>Backup availability</li>
</ul>




<p class="wp-block-paragraph">This audit often reveals problems that already existed before the migration. For example, a plugin may be abandoned, the database may contain excessive transient records, or the site may still rely on an unsupported PHP version.</p>




<p class="wp-block-paragraph">A migration should not automatically copy every old problem into the new environment. It is often the right time to clean up unused plugins, remove abandoned themes, review administrator accounts, and confirm that all essential components remain supported.</p>




<h2 class="wp-block-heading">Phase Two: Prepare the Destination Server</h2>




<p class="wp-block-paragraph">The destination environment should be ready before the website is transferred. This reduces last-minute troubleshooting during the cutover.</p>




<p class="wp-block-paragraph">The server preparation usually includes:</p>




<ul class="wp-block-list">
<li>Creating the hosting account or virtual host</li>
<li>Installing the correct PHP version</li>
<li>Enabling required PHP extensions</li>
<li>Creating the database and database user</li>
<li>Configuring file permissions</li>
<li>Setting PHP memory and upload limits</li>
<li>Configuring the web server</li>
<li>Preparing SSL issuance</li>
<li>Configuring backups</li>
<li>Installing monitoring or logging tools</li>
<li>Preparing caching and performance settings</li>
</ul>




<p class="wp-block-paragraph">The destination should ideally match the source environment closely during the first transfer. Major software upgrades can be performed later, after the website is stable. Combining a hosting migration, PHP upgrade, plugin cleanup, theme redesign, and domain change into one maintenance window increases the number of possible failure points.</p>




<h2 class="wp-block-heading">Phase Three: Create Verified Backups</h2>




<p class="wp-block-paragraph">A migration should never begin without a complete backup. More importantly, the backup should be verified rather than merely assumed to be usable.</p>




<p class="wp-block-paragraph">At minimum, create separate copies of:</p>




<ul class="wp-block-list">
<li>The entire WordPress file system</li>
<li>The website database</li>
<li>The WordPress configuration file</li>
<li>Web server rules</li>
<li>DNS records</li>
<li>SSL-related information</li>
<li>Custom cron jobs</li>
<li>Email routing records</li>
</ul>




<p class="wp-block-paragraph">A backup is only valuable if it can be restored. Confirm that the archive opens correctly, the database export is not empty or truncated, and the files include the full uploads directory.</p>




<p class="wp-block-paragraph">For business-critical websites, keeping more than one backup copy is sensible. One copy may remain on the source server, while another is stored externally.</p>




<h2 class="wp-block-heading">Phase Four: Copy the WordPress Files</h2>




<p class="wp-block-paragraph">The files can be transferred using several methods, including a migration plugin, hosting control panel, SFTP, SCP, rsync, or a compressed archive.</p>




<p class="wp-block-paragraph">For small websites, a plugin may be sufficient. Larger websites often benefit from server-level transfer tools because they handle large file sets more efficiently and provide better visibility into transfer errors.</p>




<p class="wp-block-paragraph">During the transfer, confirm that hidden files are included. Files such as <code>.htaccess</code> may contain essential rewrite, security, redirect, or caching rules.</p>




<p class="wp-block-paragraph">After copying, verify ownership and permissions. Incorrect permissions can prevent uploads, plugin updates, cache creation, or WordPress core operations.</p>




<h2 class="wp-block-heading">Phase Five: Export and Import the Database</h2>




<p class="wp-block-paragraph">The database contains the website’s posts, pages, users, settings, menus, plugin data, WooCommerce orders, form entries, and most application-level configuration.</p>




<p class="wp-block-paragraph">It can be exported using tools such as phpMyAdmin, WP-CLI, a migration plugin, or the database command line. Large databases are generally more reliable to move through command-line tools because browser-based imports may fail due to upload or execution limits.</p>




<p class="wp-block-paragraph">Once imported, update the destination <code>wp-config.php</code> file with the correct database details:</p>




<pre class="wp-block-code"><code>define('DB_NAME', 'destination_database');
define('DB_USER', 'destination_user');
define('DB_PASSWORD', 'strong_password');
define('DB_HOST', 'localhost');</code></pre>





<p class="wp-block-paragraph">The exact database host depends on the hosting environment. Some providers use a remote database hostname instead of <code>localhost</code>.</p>




<h2 class="wp-block-heading">Phase Six: Handle URL Changes Correctly</h2>




<p class="wp-block-paragraph">If the website keeps the same domain, fewer URL changes may be required. However, staging URLs, temporary hostnames, HTTP-to-HTTPS changes, subdirectory changes, or domain changes require a controlled search-and-replace operation.</p>




<p class="wp-block-paragraph">A plain text replacement inside a database export can damage serialized WordPress data. WordPress plugins and page builders often store structured values where string lengths matter.</p>




<p class="wp-block-paragraph">Use a WordPress-aware tool such as WP-CLI:</p>




<pre class="wp-block-code"><code>wp search-replace 'https://old-domain.example' 'https://new-domain.example' --all-tables --precise --dry-run</code></pre>





<p class="wp-block-paragraph">The dry run displays the expected replacements without modifying the database. Once reviewed, the operation can be repeated without the <code>--dry-run</code> flag.</p>




<p class="wp-block-paragraph">After the replacement, check:</p>




<ul class="wp-block-list">
<li>Page and post links</li>
<li>Navigation menus</li>
<li>Image URLs</li>
<li>Page-builder templates</li>
<li>Widgets</li>
<li>Logo and favicon paths</li>
<li>Canonical tags</li>
<li>Open Graph images</li>
<li>Plugin callback URLs</li>
<li>Webhook endpoints</li>
</ul>




<h2 class="wp-block-heading">Phase Seven: Test the Website Before Changing DNS</h2>




<p class="wp-block-paragraph">The destination website should be tested before public traffic is sent to it. This is one of the most important steps in a low-downtime migration.</p>




<p class="wp-block-paragraph">A local hosts-file override can map the production domain to the new server only on your own computer. This allows the website to be tested under its real domain while the rest of the internet continues reaching the old server.</p>




<p class="wp-block-paragraph">Testing should cover more than the homepage.</p>




<h3 class="wp-block-heading">Front-End Testing</h3>




<ul class="wp-block-list">
<li>Homepage</li>
<li>Posts and pages</li>
<li>Category and archive pages</li>
<li>Search functionality</li>
<li>Navigation menus</li>
<li>Images and downloads</li>
<li>Responsive layout</li>
<li>404 page</li>
<li>Redirects</li>
</ul>




<h3 class="wp-block-heading">Administrative Testing</h3>




<ul class="wp-block-list">
<li>WordPress login</li>
<li>Post editing</li>
<li>Media uploads</li>
<li>Plugin settings</li>
<li>Theme customization</li>
<li>User management</li>
<li>Scheduled tasks</li>
</ul>




<h3 class="wp-block-heading">Business Function Testing</h3>




<ul class="wp-block-list">
<li>Contact forms</li>
<li>Newsletter subscriptions</li>
<li>Account registration</li>
<li>Password reset emails</li>
<li>Checkout and payment flow</li>
<li>Booking forms</li>
<li>Customer dashboards</li>
<li>API integrations</li>
<li>Webhook delivery</li>
</ul>




<p class="wp-block-paragraph">Check the browser console, server logs, WordPress debug logs, and network requests. A page can appear normal while scripts, API calls, or background processes are failing silently.</p>




<h2 class="wp-block-heading">How to Reduce WordPress Migration Downtime</h2>




<p class="wp-block-paragraph">Zero downtime is difficult to guarantee for every website, but downtime can often be reduced to a very small window.</p>




<h3 class="wp-block-heading">Lower the DNS TTL in Advance</h3>




<p class="wp-block-paragraph">DNS Time to Live determines how long resolvers may cache a record. Lowering the TTL before migration can help changes propagate more quickly.</p>




<p class="wp-block-paragraph">This should be done before the migration window, not at the exact moment of cutover. Existing cached records will continue using the previous TTL until they expire.</p>




<h3 class="wp-block-heading">Perform an Initial Copy Before Cutover</h3>




<p class="wp-block-paragraph">Copy the website files and database to the destination in advance. This gives enough time to test the environment and resolve compatibility problems before the final switch.</p>




<h3 class="wp-block-heading">Freeze Content Changes Briefly</h3>




<p class="wp-block-paragraph">For dynamic websites, a short maintenance or content-freeze window may be necessary. During this period, editors should stop publishing and customers may need to be temporarily prevented from submitting transactions.</p>




<h3 class="wp-block-heading">Perform a Final Database Synchronization</h3>




<p class="wp-block-paragraph">After the initial copy and testing, export the latest database immediately before the DNS or proxy cutover. This minimizes the chance of losing recent activity.</p>




<h3 class="wp-block-heading">Keep the Old Server Available</h3>




<p class="wp-block-paragraph">Do not cancel the original hosting account as soon as DNS is changed. Some visitors may still reach the old server due to DNS caching. The source environment should remain available until propagation is complete and the new website has been monitored.</p>




<h2 class="wp-block-heading">DNS Migration: More Than Changing One Record</h2>




<p class="wp-block-paragraph">DNS errors are responsible for many migration failures. A domain may have records for the website, email, verification services, subdomains, APIs, and third-party platforms.</p>




<p class="wp-block-paragraph">Before making changes, export or document the complete DNS zone. Important records may include:</p>




<ul class="wp-block-list">
<li>A records</li>
<li>AAAA records</li>
<li>CNAME records</li>
<li>MX records</li>
<li>TXT records</li>
<li>SPF records</li>
<li>DKIM records</li>
<li>DMARC records</li>
<li>Domain verification records</li>
<li>Service-specific subdomains</li>
</ul>




<p class="wp-block-paragraph">If only the web server is changing, there may be no reason to modify email records. Accidentally replacing the entire DNS zone with a simplified version can interrupt business email even when the website itself works correctly.</p>




<h2 class="wp-block-heading">SSL and HTTPS After Migration</h2>




<p class="wp-block-paragraph">The destination server must have a valid SSL certificate for the production domain. The certificate should cover all required hostnames, such as the root domain and the <code>www</code> version.</p>




<p class="wp-block-paragraph">After enabling HTTPS, verify that:</p>




<ul class="wp-block-list">
<li>The certificate is valid and not expired</li>
<li>The certificate matches the domain</li>
<li>HTTP redirects to HTTPS correctly</li>
<li>The root and www versions behave consistently</li>
<li>No redirect loop exists</li>
<li>Images and scripts load through HTTPS</li>
<li>CDN resources use secure URLs</li>
</ul>




<p class="wp-block-paragraph">Mixed-content errors should be corrected rather than hidden. They usually indicate that some database values, theme settings, CSS files, or external resources still reference HTTP URLs.</p>




<h2 class="wp-block-heading">Email and Contact Form Verification</h2>




<p class="wp-block-paragraph">A website migration is not complete until email functionality is tested.</p>




<p class="wp-block-paragraph">WordPress may rely on the local server mail function, SMTP authentication, a transactional email provider, or an external mailbox service. Each method has different requirements.</p>




<p class="wp-block-paragraph">Test at least the following:</p>




<ul class="wp-block-list">
<li>Contact form delivery</li>
<li>Administrator notifications</li>
<li>Password reset emails</li>
<li>WooCommerce order emails</li>
<li>Registration emails</li>
<li>Newsletter confirmation messages</li>
<li>SMTP authentication</li>
</ul>




<p class="wp-block-paragraph">Also confirm that SPF, DKIM, and DMARC records remain valid. Successful message submission does not always mean successful inbox delivery.</p>




<h2 class="wp-block-heading">Migrating a WooCommerce Website</h2>




<p class="wp-block-paragraph">WooCommerce migrations require additional care because the database may change continuously. Orders, inventory, customer records, carts, subscriptions, refunds, and payment events can be created during the migration window.</p>




<p class="wp-block-paragraph">A WooCommerce migration plan should include:</p>




<ul class="wp-block-list">
<li>A clearly defined cutover time</li>
<li>A short checkout freeze if required</li>
<li>A final database synchronization</li>
<li>Payment gateway testing</li>
<li>Webhook testing</li>
<li>Order email verification</li>
<li>Inventory validation</li>
<li>Subscription and scheduled-payment checks</li>
<li>Customer login testing</li>
<li>Transaction log review</li>
</ul>




<p class="wp-block-paragraph">For high-traffic stores, a simple export-and-import workflow may not be sufficient. More advanced database synchronization or application-level migration techniques may be needed.</p>




<h2 class="wp-block-heading">Migrating WordPress to a New Domain</h2>




<p class="wp-block-paragraph">Changing the domain adds an SEO and application layer to the migration.</p>




<p class="wp-block-paragraph">In addition to moving the website, the process should include:</p>




<ul class="wp-block-list">
<li>Updating WordPress URLs</li>
<li>Replacing old domain references</li>
<li>Creating page-to-page 301 redirects</li>
<li>Updating canonical URLs</li>
<li>Updating XML sitemaps</li>
<li>Updating analytics properties</li>
<li>Updating Search Console records</li>
<li>Updating social profiles</li>
<li>Updating payment callbacks</li>
<li>Updating API allowlists</li>
<li>Updating email addresses where required</li>
</ul>




<p class="wp-block-paragraph">A blanket redirect from every old URL to the new homepage is not a good migration strategy. Each important old URL should redirect to its closest equivalent on the new domain.</p>




<h2 class="wp-block-heading">Protecting SEO During WordPress Migration</h2>




<p class="wp-block-paragraph">A hosting migration that keeps the same domain should normally have limited SEO impact when implemented correctly. A domain change or large structural change requires more planning.</p>




<p class="wp-block-paragraph">Important SEO checks include:</p>




<ul class="wp-block-list">
<li>Preserving existing URL structures</li>
<li>Maintaining page titles and metadata</li>
<li>Keeping canonical tags correct</li>
<li>Preserving structured data</li>
<li>Checking robots.txt</li>
<li>Checking XML sitemaps</li>
<li>Verifying redirects</li>
<li>Removing accidental noindex directives</li>
<li>Checking HTTP status codes</li>
<li>Monitoring crawl errors</li>
<li>Monitoring organic traffic after launch</li>
</ul>




<p class="wp-block-paragraph">Staging environments are often configured with <code>noindex</code> rules to prevent search engines from indexing them. That setting must not be carried into production accidentally.</p>




<p class="wp-block-paragraph">It is also important to remove temporary password protection, development redirects, and staging-specific canonical URLs before launch.</p>




<h2 class="wp-block-heading">Performance Optimization After Migration</h2>




<p class="wp-block-paragraph">A migration provides a good opportunity to improve performance, but optimization should be performed methodically.</p>




<p class="wp-block-paragraph">Start by confirming that the website is stable. Then review:</p>




<ul class="wp-block-list">
<li>Page caching</li>
<li>Object caching</li>
<li>PHP OPcache</li>
<li>Database performance</li>
<li>Image compression</li>
<li>WebP or AVIF delivery</li>
<li>CDN integration</li>
<li>Browser caching</li>
<li>Gzip or Brotli compression</li>
<li>Slow plugins</li>
<li>Unused scripts and styles</li>
<li>External API delays</li>
</ul>




<p class="wp-block-paragraph">Do not enable several caching systems at the same time without understanding how they interact. Duplicate caching layers can create stale pages, login problems, checkout issues, and difficult-to-diagnose behavior.</p>




<h2 class="wp-block-heading">Security Checks After Migration</h2>




<p class="wp-block-paragraph">The new environment should be reviewed before the migration is considered complete.</p>




<p class="wp-block-paragraph">Post-migration security checks should include:</p>




<ul class="wp-block-list">
<li>Removing temporary migration files</li>
<li>Removing exported database archives</li>
<li>Deleting unused administrator accounts</li>
<li>Changing temporary credentials</li>
<li>Confirming file ownership and permissions</li>
<li>Disabling directory listing</li>
<li>Reviewing firewall rules</li>
<li>Enabling brute-force protection</li>
<li>Updating WordPress, themes, and plugins</li>
<li>Reviewing backup access</li>
<li>Protecting configuration files</li>
<li>Confirming malware scanning</li>
</ul>




<p class="wp-block-paragraph">Database exports and full-site archives often contain sensitive information. They should not remain publicly accessible inside the website directory after migration.</p>




<h2 class="wp-block-heading">WordPress Migration Plugins vs Manual Migration</h2>




<p class="wp-block-paragraph">Both methods are valid. The right choice depends on the website.</p>




<h3 class="wp-block-heading">Migration Plugins</h3>




<p class="wp-block-paragraph">Migration plugins are convenient for small and medium-sized websites. They can package files and databases, update URLs, and simplify restoration.</p>




<p class="wp-block-paragraph">However, they may encounter:</p>




<ul class="wp-block-list">
<li>File size limits</li>
<li>PHP execution time limits</li>
<li>Memory limits</li>
<li>Hosting restrictions</li>
<li>Archive extraction failures</li>
<li>Large database timeouts</li>
<li>Limited visibility into errors</li>
</ul>




<h3 class="wp-block-heading">Manual or Server-Level Migration</h3>




<p class="wp-block-paragraph">Manual migration provides more control and is often more reliable for large, customized, or business-critical websites.</p>




<p class="wp-block-paragraph">It also allows the migration specialist to inspect logs, control database operations, preserve permissions, perform incremental transfers, and troubleshoot individual layers separately.</p>




<p class="wp-block-paragraph">The tradeoff is that server-level migration requires stronger knowledge of Linux, databases, DNS, web servers, PHP, SSL, and WordPress internals.</p>




<h2 class="wp-block-heading">A Practical WordPress Migration Checklist</h2>




<h3 class="wp-block-heading">Before Migration</h3>




<ul class="wp-block-list">
<li>Audit the current website</li>
<li>Record PHP and database versions</li>
<li>List active integrations</li>
<li>Export DNS records</li>
<li>Lower DNS TTL if needed</li>
<li>Create and verify backups</li>
<li>Prepare the destination server</li>
<li>Install required PHP extensions</li>
<li>Create the destination database</li>
<li>Plan the maintenance window</li>
</ul>




<h3 class="wp-block-heading">During Migration</h3>




<ul class="wp-block-list">
<li>Copy WordPress files</li>
<li>Export and import the database</li>
<li>Update wp-config.php</li>
<li>Perform safe URL replacement</li>
<li>Verify permissions</li>
<li>Test using a hosts-file override</li>
<li>Check logs and browser errors</li>
<li>Test forms, logins, and transactions</li>
<li>Perform the final database sync</li>
<li>Update DNS</li>
</ul>




<h3 class="wp-block-heading">After Migration</h3>




<ul class="wp-block-list">
<li>Verify SSL</li>
<li>Test email delivery</li>
<li>Check redirects</li>
<li>Check sitemap and robots.txt</li>
<li>Clear all cache layers</li>
<li>Review application logs</li>
<li>Monitor uptime</li>
<li>Monitor search and analytics data</li>
<li>Keep the old server available temporarily</li>
<li>Remove migration archives</li>
<li>Confirm backup schedules</li>
</ul>




<h2 class="wp-block-heading">When Should You Hire a WordPress Migration Specialist?</h2>




<p class="wp-block-paragraph">A simple personal website may be moved successfully with a migration plugin. Professional assistance becomes more valuable when the website has operational or commercial importance.</p>




<p class="wp-block-paragraph">Consider hiring a specialist when:</p>




<ul class="wp-block-list">
<li>The website generates sales or leads</li>
<li>Downtime has a direct business cost</li>
<li>The database changes frequently</li>
<li>The site uses WooCommerce or memberships</li>
<li>The migration includes a domain change</li>
<li>Email services share the same DNS zone</li>
<li>The site contains custom plugins or code</li>
<li>The destination server requires manual configuration</li>
<li>The site has a large media library or database</li>
<li>You need SSL, DNS, redirects, and testing handled together</li>
</ul>




<p class="wp-block-paragraph">A professional migration should provide more than a copied website. It should include preparation, backups, testing, DNS coordination, SSL validation, post-migration verification, and a rollback plan.</p>




<h2 class="wp-block-heading">Final Thoughts</h2>




<p class="wp-block-paragraph">WordPress migration is a technical process, but the real objective is business continuity. Visitors should continue reaching the website, customers should continue completing transactions, administrators should retain access, and search engines should continue finding the same content.</p>




<p class="wp-block-paragraph">The safest migrations are rarely the fastest-looking ones. They are the migrations where the destination is prepared in advance, backups are verified, the website is tested before cutover, DNS is handled carefully, and the old environment remains available until the transition is confirmed.</p>




<p class="wp-block-paragraph">Whether the website is moving to a new hosting company, a VPS, a cloud server, or a new domain, a structured migration plan dramatically reduces the risk of downtime, missing data, and unexpected failures.</p>




<div class="wp-block-group" style="border-width:1px;border-radius:12px;margin-top:48px;padding-top:32px;padding-right:32px;padding-bottom:32px;padding-left:32px"><div class="wp-block-group__inner-container is-layout-constrained wp-container-core-group-is-layout-6f60fb98 wp-block-group-is-layout-constrained">



<h2 class="wp-block-heading has-text-align-center">Need Help Migrating Your WordPress Website?</h2>




<p class="has-text-align-center wp-block-paragraph">A WordPress migration should not put your website, customer data, email delivery, or search rankings at risk. I provide complete WordPress migration services covering website files, databases, DNS, SSL, testing, redirects, and post-migration verification.</p>




<p class="has-text-align-center wp-block-paragraph">Your website will be prepared, transferred, tested, and launched through a controlled migration process designed to minimize downtime and prevent avoidable disruption.</p>




<div class="wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-fe48e5de wp-block-buttons-is-layout-flex">



<div class="wp-block-button has-custom-width wp-block-button__width-75">
<a class="wp-block-button__link wp-element-button" href="https://www.upwork.com/services/product/development-it-wordpress-website-migration-with-minimal-downtime-2077830746744627334" target="_blank" rel="noopener sponsored" style="border-radius:8px;padding-top:14px;padding-right:24px;padding-bottom:14px;padding-left:24px">View My WordPress Migration Service on Upwork</a>
</div>


</div>


</div></div>


<p>The post <a href="https://john-nessime.com/blog/wordpress/wordpress-migration-without-downtime/">WordPress Migration Without Downtime: A Practical Guide to Moving Your Website Safely</a> appeared first on <a href="https://john-nessime.com/blog">John Nessime</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://john-nessime.com/blog/wordpress/wordpress-migration-without-downtime/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
