# ServerAvatar
> The first, Fully Hybrid Cloud Hosting Solution.
> Generated by All in One SEO Pro v5.0.3, this is an llms-full.txt file, used by LLMs to index the site.
## Posts
### [Blog](https://serveravatar.com/blog/)
**Published:** February 7, 2025
**Author:** Gorakh Sirsikar
---
### [How to Fix DNS_PROBE_FINISHED_NXDOMAIN Error](https://serveravatar.com/fix-dns-probe-finished-nxdomain-error/)
**Published:** October 17, 2026
**Author:** Meghna Meghwani
**Content:**
[](https://serveravatar.com/?ref=blog)Have you ever seen a DNS\_PROBE\_FINISHED\_NXDOMAIN in browser? We usually begin by verifying the website URL, then try accessing it on another device, through a different network, or in an incognito browser window to identify the possible cause of the issue. That quick steps helps to decide whether to troubleshoot your device or the website’s DNS configuration.
What if you own the website and the error appears across networks? You probably check the domain’s nameservers and DNS records before changing browser settings.
This guide takes you through both situations, with Windows and Ubuntu commands, Chrome checks, and separate workflow for developers and website administrators.

## Find where the problem happens
Copy the exact address that keeps failing. Keep the hostname unchanged as example.com, www.example.com, and shop.example.com all can have different DNS records.
Then make these comparisons:
1. Open an unrelated website to check whether the problem affects more than one domain.
2. Try the failing address in another browser or in incognito browser on the same device.
3. Try another device on the same Wi-Fi or network.
4. Try the same address over mobile data, with Wi-Fi switched off.
| **What you observe** | **What to investigate first** |
|---|---|
| **Only Chrome fails** | Chrome Secure DNS, extensions, or browser configuration |
| **One device fails across browsers** | Local resolver settings, cached DNS, or a hosts-file override |
| **Devices on Wi-Fi fail, but mobile data works** | Router, ISP resolver, network filtering, or VPN configuration |
| **The hostname fails across independent networks** | Public DNS records, nameserver delegation, or domain status |
| **The root domain works, but** **www** **or a subdomain fails** | Records for that exact hostname or its CNAME target |
These are basic diagnostic hints, not proof. Different networks can use different caches, and browser can use different resolver from the operating system.
If you are visiting someone else’s website: follow the device checks below. If it fails across networks, send the owner the exact address and error.
If you manage the website: move to the website-owner checks when multiple networks fail.
## What does DNS\_PROBE\_FINISHED\_NXDOMAIN mean?
DNS helps browser to find the address associated with a hostname. NXDOMAIN means “non-existent domain”: a DNS response reports that the queried name does not exist. A response can also involve alias whose target not exist.
That does not necessarily mean the domain was never registered, but maybe you might be requesting a missing subdomain, or receiving an old cached response, or using resolver that filters the name. The browser message alone is not establish the root cause.
DNS distinguishes non-existent name from a name that exists but has no record of the requested type. These distinctions are defined in [RFC 2308 on negative DNS caching](https://www.rfc-editor.org/rfc/rfc2308).
The failure occurs during name resolution, before the browser can make its normal connection to the website. Reinstalling WordPress, changing PHP, or renewing an SSL certificate is not a sensible first response to an NXDOMAIN error.
Check out “[How DNS Works](https://serveravatar.com/how-dns-works/)” guide to [see](https://serveravatar.com/how-dns-works/) DNS working and it’s complete process.
## Troubleshoot Issues Related to Your Device or Network
Make one change at a time, then check by reopening the same failing address. Stop when it is opened properly and access is restored.
### 1. Check the address and reconnect
Look for any spelling mistakes, or any extra characters, or incorrect subdomain. Try typing the correct address instead of opening old bookmark.
Check by close and reopen the browser. On personal device, reconnect to Wi-Fi or restart the device if required. Restarting router may help with temporary network issues.
Do not directly factory-reset your router as it can remove the connection settings and it is not necessary for initial DNS diagnosis.
### 2. Check Chrome’s Secure DNS setting
Chrome can perform encrypted DNS lookups. This method can help when command-line tools confirm that the website is reachable, yet Chrome still fails to load the page.
**On desktop Chrome:**
- Open Settings from the three-dot icon at the top right corner
- Navigate to the Privacy and security section >> Security
- Find the “Use secure DNS” option, and note the current configuration.
- If a custom provider is selected, test using your current service provider. Alternatively, turn off the “Secure DNS” to compare results.
- Reload the failing address to check, and then restore your preferred secure configuration after identifying the problem.

[Google’s Chrome documentation](https://support.google.com/chrome/answer/10468685?hl=en&co=GENIE.Platform%3DDesktop) explains a custom Secure DNS provider does not fall back to unencrypted DNS when encounters lookup problems. Website access may also be affected by device management settings or parental control restrictions.
If problem continues only in Chrome, update chrome, and test fresh browser profile or disable a recently added extension temporarily to check.
### 3. Clear the local DNS cache where applicable
DNS cache can retain earlier failure even after website owner fixes the record. Clearing DNS cache affects your device, and does not clear cache held by your ISP or another upstream resolver.
**For Windows:**
Open Command Prompt as an administrator and run below mentioned command:
```
```
```
ipconfig /flushdns
```
Windows will report that it flushed the DNS resolver cache. Close and relaunch your browser, then visit the website once more to check whether the issue has been resolved. The command is documented in [Microsoft’s ipconfig reference](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/ipconfig).

Do not immediately add “ipconfig /release” and “ipconfig /renew” to this step. It will change DHCP configuration and can interrupt connectivity, especially during remote work.
**For Ubuntu 22.04 and 24.04:**
Open a terminal and inspect the resolver using below command:
```
```
```
resolvectl status
```
You can see the output as mentioned in below screenshot:

If machine use “systemd-resolved”, clear its cache and test lookup:
```
```
```
sudo resolvectl flush-caches
```
```
```
```
resolvectl query example.com
```
Replace “example.com” in above command with your failing hostname.
The flush command generally finishes without success message, and follow-up query checks whether resolution now works.
If “resolvectl” is unavailable or resolver service is not running, identify machine’s actual DNS setup instead of installing or restarting unrelated caching service. Ubuntu documents its resolver approach in [network configuration guidance](https://ubuntu.com/server/docs/explanation/networking/configuring-networks/) and [resolvectl manual](https://manpages.ubuntu.com/manpages/noble/man1/resolvectl.1.html).
Avoid overwriting “/etc/resolv.conf” as generic fix. Manual changes to it can be replaced or interfere with configured resolver.
**For macOS and mobile devices:**
First, quit and reopen browser, then restart device if needed. On Android or iPhone, check Wi-Fi with mobile data and check whether VPN or custom DNS configuration is active.
Do not erase mobile network settings, network reset can remove saved configuration. If error follows Wi-Fi rather than device, investigate that network’s resolver.
### 4. Compare with another DNS resolver
For public website, compare your current DNS resolver with Google Public DNS before changing system settings.
**On Windows:**
```
```
```
nslookup example.com
```
```
```
```
nslookup example.com 8.8.8.8
```
Replace “example.com” in above command with failing hostname.
**On Ubuntu or a Mac with** **dig** **available:**
```
```
```
dig example.com A
```
```
```
```
dig @8.8.8.8 example.com A
```
Replace “example.com” in above command with your failing hostname.
If public resolver returns address while your usual resolver reports non-existent name, difference points toward caching, filtering, or resolver configuration. It does not by itself prove ISP outage. Some networks block direct DNS queries to external providers.
If you decide to test Google Public DNS in your device settings, its IPv4 addresses are:
Preferred: 8.8.8.8
Alternate: 8.8.4.4
**Note:** Do not replace corporate or VPN DNS with public DNS when troubleshooting internal hostnames. Those names may intentionally exist only inside private network.
### 5. Review VPNs, filters, and local overrides
If error began after enabling a VPN or DNS filtering service, compare results with and without that service when your network policy allows it. Restore protection after the test.
Avoid disabling the entire firewall or antivirus as a routine fix. Investigate the specific DNS or web-filtering feature instead.
Developers should also check for an old hosts-file entry left over from a migration or local preview:
| **Operating system** | **Hosts-file location** |
|---|---|
| **Windows** | C:\\Windows\\System32\\drivers\\etc\\hosts |
| **Ubuntu/Linux** | /etc/hosts |
| **macOS** | /etc/hosts |
Back up the file before editing. Remove or comment out only an obsolete entry you understand; preserve intentional development and system entries. An incorrect override may cause different connection error rather than NXDOMAIN, but it is relevant when the browser and DNS tools disagree.
## Fix DNS for your own website
You need access to the domain registrar and the authoritative DNS provider. These may be different companies. Before changing anything, save the current DNS records and nameserver settings.
### 1. Confirm the domain and exact hostname
Start by reviewing your domain details in the registrar’s dashboard. Confirm that the domain is renewed, hasn’t been suspended, and has no pending verification requirements. Expiry or a registrar hold can disrupt DNS, and resulting browser errors.
Then check the exact hostname that visitors use. A working “example.com” domain does not ensure that “www.example.com” works.
### 2. Confirm you are editing the active DNS zone
Compare the nameservers configured at the registrar with those assigned by your DNS provider. Editing zone at provider that is no longer authoritative will not change the answers visitors receive.
For instance, if your domain points to one DNS provider but you configure records with a different provider, those changes won’t take effect because the active DNS configuration doesn’t include them.
### 3. Repair the required address or alias record
Common website records are:
| **Record** | **Purpose** | **What to check** |
|---|---|---|
| **A** | Maps hostname to IPv4 | Address matches the intended hosting configuration |
| **AAAA** | Maps hostname to IPv6 | Hosting supports that IPv6 address |
| **CNAME** | Makes hostname an alias | Target exists and resolves successfully |
Illustrative configuration for website hosted directly on server:
| **Type** | **Name** | **Value** |
|---|---|---|
| **A** | @ | 192.0.2.40 |
| **CNAME** | www | example.com |
**Do not copy IP address above**. It is just an example; replace it with the actual address your hosting setup requires. Providers often use @ for the root domain, but their input formats differ.
If you use CDN or proxy, public DNS may correctly return the proxy’s addresses. Follow that provider’s configuration instead of assuming every public answer must equal your origin server IP.
Do not delete unrelated MX or TXT records while repairing web records, as it may support email delivery, authentication, or domain verification.
### 4. Account for negative caching
Suppose someone opened preview.example.com before you created its DNS record. Their resolver may have cached the earlier “does not exist” response. The authoritative server can now have the correct record while that resolver still returns NXDOMAIN.
The negative-cache lifetime is derived from the zone’s SOA information. Under RFC 2308, it uses the lower of the SOA record’s TTL and SOA MINIMUM value. Lowering the newly created A record’s TTL does not remove an already cached negative response.
There is no any universal “wait exactly 48 hours” rule. Check whether the authoritative servers are correct first, then compare recursive resolver answers. Waiting will not fix an incorrect record or delegation.
## Advanced checks for developers and server administrators
The commands below perform DNS lookups without changing configuration. On Ubuntu, install dig only if needed:
```
```
```
sudo apt update
```
```
```
```
sudo apt install dnsutils
```
This installs diagnostic software; it does not change the DNS provider. Ubuntu’s [DNS documentation](https://ubuntu.com/server/docs/how-to/networking/install-dns/) identifies dnsutils as the package providing dig.
### Read the response before choosing a fix
```
```
```
dig @8.8.8.8 shop.example.com A
```
```
```
```
dig @8.8.8.8 shop.example.com AAAA
```
Replace the hostname with the one that fails. Read the header’s status, the answer section, and any CNAME chain. Do not rely only on +short: an empty display hides useful distinctions.
| **Result** | **Meaning** | **Next action** |
|---|---|---|
| **NXDOMAIN** | The lookup reports non-existent name; alias target may be involved | Check spelling, the hostname, alias targets, and the active zone |
| **NOERROR** **with no relevant answer** | The lookup completed, but that record type may be absent | Check other address types and alias records |
| **SERVFAIL** | The resolver could not complete the lookup | Investigate delegation, authoritative availability, and DNSSEC |
| **Timeout** | No answer arrived within the query timeout | Check resolver reachability and network policy |
| **Expected address or valid alias chain** | DNS answers this query | Investigate browser differences or the subsequent connection |
[](https://serveravatar.com/?ref=blog)## Verify the fix and know when to escalate
A successful DNS lookup is one milestone. Confirm that the website itself loads too:
- Query the exact failing hostname again.
- Check root domain, www, and any affected application subdomain separately.
- Reopen browser and load intended HTTPS address.
- For a public website, repeat test from an independent network.
If NXDOMAIN message is replaced by certificate warning, timeout, or HTTP error, you have different symptom to investigate. Check relevant TLS, networking, or application layer rather than continuing to flush DNS.
## Reduce the chance of another DNS incident
- Enable registrar renewal reminders and keep account contact details current.
- Save DNS-zone export before migrations or nameserver changes.
- Create and verify important hostname records before sharing new application links.
- When planning changes, lower relevant record TTLs ahead of time if appropriate; existing caches retain their earlier lifetimes.
- Monitor DNS resolution as well as HTTP availability for critical domains.
- For agencies, record who controls each client’s registrar, DNS provider, and hosting account.
If you manage applications with ServerAvatar, use its [DNS workflow](https://serveravatar.com/docs/application/cloudflare/dns-records/) where your connected Cloudflare setup applies. Verify public resolution before moving on to application or certificate troubleshooting.
## Key takeaways
- DNS\_PROBE\_FINISHED\_NXDOMAIN means DNS lookup reports that the requested hostname or its alias target does not exist.
- Test exact website address across browsers, devices, and networks to identify where DNS error occurs.
- Review Chrome’s Secure DNS settings, clear the local DNS cache, and check VPNs or DNS filters when the issue is limited to your device.
- Compare DNS responses using nslookup or dig before changing your DNS resolver settings.
- Verify domain status, authoritative nameservers, and the affected hostname’s A, AAAA, or CNAME records.
- Cached NXDOMAIN responses can persist after DNS fix, but waiting will not resolve incorrect records or nameservers.
- Confirm DNS resolution and HTTPS access after troubleshooting, and maintain DNS monitoring, renewal reminders, and backups.
## Conclusion
To fix DNS\_PROBE\_FINISHED\_NXDOMAIN error, starting by identifying whether problem affects the browser, device, network, or the website’s DNS configuration. By checking exact URL, comparing results across independent networks, and using DNS lookup tools for next step. Depending on the findings, the solution may involve clearing a local DNS cache, reviewing Chrome’s Secure DNS settings, or correcting a missing hostname record.
For website owners, reliable recovery depends on checking domain status, confirming the authoritative nameservers, and repairing the required DNS records in the active zone. After making changes, account for cached negative responses and verify that both DNS resolution and the website’s HTTPS connection work. Regular DNS monitoring, renewal reminders, and configuration backups can help prevent future DNS errors and keep your website accessible.
## FAQs
### Is DNS\_PROBE\_FINISHED\_NXDOMAIN a server-down error?
This alone does not necessarily mean the web server is offline. It indicates a name-resolution problem. A server can be running while its hostname fails to resolve.
### Why Can You Access a Website on Mobile Data but Not on Wi-Fi?
The connections may use different DNS resolvers, caches, filters, or VPN routes. Compare lookup answers before deciding whether the router or ISP is responsible.
### Will clearing cookies fix NXDOMAIN?
Cookies are not DNS records. Clearing cookies is not targeted remedy for missing hostname. Check DNS resolution and browser resolver settings first.
### Why does NXDOMAIN remain after I add the DNS record?
A resolver may retain a negative answer from before the record existed. Confirm the record at the authoritative servers, then compare recursive answers. Also check that you edited the active zone.
### Can WordPress plugins or PHP settings fix this error?
They do not create public DNS records. Fix hostname resolution first, then investigate WordPress or PHP only if the site produces an application error after connecting.
### Does an empty A-record answer always mean the domain does not exist?
No. Inspect the DNS response status and check AAAA and CNAME records. A hostname can exist without an A record.
### About the Author
Meghna Meghwani is a technical writer focused on Linux, Ubuntu, VPS hosting, server management, WordPress, PHP, Node.js, cloud hosting, and DevOps. She creates beginner-friendly tutorials, practical hosting guides, troubleshooting articles, and server security content designed to help developers and businesses manage applications and servers more efficiently.
**Categories:** Blog, Guide, Linux, Others, Tutorials, Ubuntu
**Tags:** change DNS servers, DNS Error, DNS Troubleshooting, DNS_PROBE_FINISHED_NXDOMAIN, fix DNS errors, flush DNS cache, Google Chrome Errors, Website Not Loading, Windows DNS fix
---
### [tar vs ZIP in Linux: Which Compression Format Should You Use?](https://serveravatar.com/tar-vs-zip/)
**Published:** September 5, 2026
**Author:** Meghna Meghwani
**Content:**
[](https://serveravatar.com/?ref=blog)If you have ever downloaded a Linux backup ending in `.tar.gz` and wondered why it was not simply a `.zip`, you are not alone. The tar vs ZIP comparison matters because both formats can bundle a directory into one convenient file, reduce storage use, and are easy to extract. That makes the choice look less important than it really is.
The practical difference appears when the archive contains Linux permissions, symbolic links, many small files, or data that needs to move to Windows or macOS. Pick the wrong format and the archive may still open, but it may not restore exactly the way you expected.
I compared tar vs ZIP in Linux with a small reproducible test instead of relying only on feature lists. In this guide, I will explain what each tool actually does, show the commands I use, share the test results, and give you a direct recommendation for backups, file transfers, website files, and cross-platform sharing.
## TL;DR
- Use .tar.gz for Linux server backups, application directories, deployment packages, permissions, and symbolic links.
- Use .zip when the archive will be opened by people on Windows, macOS, and Linux, especially for ordinary documents or media.
- A plain .tar file is an archive, not a compressed archive. Add gzip (.tar.gz) when you also want compression.
- ZIP compresses files individually. Tar usually combines the files first, and gzip compresses the combined stream.
- Neither format replaces a proper backup plan. Always test extraction and keep copies away from the source server.
## TAR.GZ vs ZIP: Choosing the Right Format
For day-to-day Linux server work, .tar.gz is my default. It fits the way Linux stores directory structures and metadata, it handles symbolic links properly, and it is available on practically every Linux server I work with.
ZIP is still the better choice in one common situation: I am sending files to someone who should be able to open them without thinking about Linux tools. A ZIP attachment containing PDFs, images, or exported reports is easy for almost anyone to use.
Here is the decision in one table:
| **Requirement** | **Better choice** | **Why** |
|---|---|---|
| **Linux server backup** | .tar.gz | Better fit for permissions, ownership details, links, and directory trees |
| **Website or application files** | .tar.gz | Preserves the Linux-oriented structure more reliably |
| **Sharing with Windows users** | .zip | Built-in support and familiar workflow |
| **Opening one file without extracting everything** | .zip | Files are compressed separately, which makes random access easier |
| **Compressing many similar text files** | Often .tar.gz | gzip can find repetition across the combined tar stream |
| **Already-compressed photos or videos** | Either | Extra compression is usually small |
| **Append files to an uncompressed archive** | .tar | Tar can update a plain archive; compressed tar archives are different |
**My rule is simple:** if the archive will return to a Linux server, I use tar. If it is mainly for people to download and open on different desktop systems, I use ZIP.
## tar is an archive format, not a compression method
Here most of the confusion occurs. The name tar comes from “tape archive.” Its basic job is to collect multiple files and directories into one archive while recording information about those entries.
A file named project.tar is usually not compressed. It is just one archive containing the project files. The GNU tar format can record file modes, user and group information, modification time, directories, symbolic links, and other file types. The [GNU tar format documentation](https://www.gnu.org/software/tar/manual/html_node/Standard.html?ref=serveravatar.com) describes these fields in detail.
Compression is normally added as a second step, although the tar command can perform both operations in one command:
```
```
```
tar -czf project.tar.gz project/
```
**The options mean:**
- **-c:** create a new archive
- **-z:** pass the archive through gzip compression
- **-f:** use the following archive filename
That produces a gzip-compressed tar archive, commonly written as .tar.gz or .tgz. The structure is essentially:
```
```
```
files and directories -> tar archive -> gzip compression -> project.tar.gz
```
I find it helpful to keep these two jobs separate in my head. Tar handles the collection and metadata; gzip handles the compression. Once that clicks, filenames such as .tar.bz2 and .tar.xz also make more sense: tar is still creating the archive, but another compressor is reducing its size.
**Creating, listing, and extracting a tar archive**
- Create a gzip-compressed archive:
```
```
```
tar -czf website-files.tar.gz /var/www/example.com
```
- List its contents without extracting:
```
```
```
tar -tzf website-files.tar.gz
```
- Extract it into a specific directory:
```
```
```
mkdir -p /tmp/website-restore
tar -xzf website-files.tar.gz -C /tmp/website-restore
```
Before extracting an unfamiliar archive, I normally list it first. It takes a few seconds and lets me catch unexpected absolute paths or an extra top-level directory before files land in the wrong place.
## ZIP combines archiving and compression in one format
ZIP takes a different approach. It stores multiple entries in one container and normally compresses each file separately. You do not need to pair it with gzip or another compression tool.
- On Ubuntu, the command-line packages may need to be installed first:
```
```
```
sudo apt update
sudo apt install zip unzip
```
- Create a ZIP archive recursively:
```
```
```
zip -r website-files.zip website-files/
```
- List the contents:
```
```
```
unzip -l website-files.zip
```
- Extract into a chosen directory:
```
```
```
mkdir -p /tmp/website-restore
unzip website-files.zip -d /tmp/website-restore
```
The -r matters. Without it, zip will not recursively include everything inside nested directories. This is a small detail, but it is exactly the kind of mistake that creates an archive which looks valid until restore time.
**ZIP’s individual-file design has a useful advantage:**
An extraction tool can reach one member without processing one long compressed stream from the beginning. That is convenient when someone only needs a single file from a large collection.
Compatibility is the other big win. Current Linux desktops, Windows, and macOS can all work with ZIP files easily. For a folder of invoices, screenshots, or reports, I personally would not complicate the handoff with .tar.gz unless Linux metadata mattered.
## tar vs ZIP in Linux: the differences that actually matter
The extensions are not the interesting part. What matters is what happens to your files during compression and restoration.
### Compression behavior and archive size
With .tar.gz, tar first creates one continuous stream from the directory, then gzip compresses that stream. If hundreds of text or configuration files contain similar strings, gzip can potentially use repeated patterns across those file boundaries.
ZIP generally compresses every file as a separate entry. That makes individual access easier, but it can miss some repetition that exists across a collection of small, similar files.
This does not mean .tar.gz will always be smaller. A directory full of JPEG, MP4, PDF, or other already-compressed data may barely shrink in either format. Compression level, tool version, file sizes, and the actual content all matter.
### Permissions, ownership, and symbolic links
For Linux backups, metadata is often more important than saving another megabyte. Executable scripts need their execute bit. Private configuration files may need restrictive modes. Symbolic links should still be links after restoration, rather than becoming copied files.
Tar was designed around this sort of filesystem information. In my test, the .tar.gz extraction restored the symbolic link as a symbolic link. With the default zip -r command, ZIP followed that link and stored the target content instead. Info-ZIP offers -y on Unix to store symbolic links as links, but a recipient’s extraction tool and operating system still affect the result.
ZIP can store some Unix metadata, and Linux ZIP tools can preserve more than people sometimes assume. Still, I would not make an ordinary ZIP workflow my first choice for a faithful Linux server restore. Cross-platform extraction tools do not all interpret Unix-specific metadata in the same way.
After extraction, verify rather than assume:
```
```
```
find /tmp/website-restore -maxdepth 2 -type l -ls
stat /tmp/website-restore/path/to/script.sh
```
If ownership is important, remember that restoring the original owner may require root privileges. An archive can contain ownership information without the current user having permission to apply it.
### Portability and ease of use
ZIP wins for casual cross-platform sharing. A non-technical recipient can usually double-click it and extract the files. .tar.gz support is also common now, but ZIP remains the safer assumption when you do not control the recipient’s system.
On Linux servers, the balance shifts. Tar is commonly installed by default, its options are familiar to administrators, and .tar.gz is standard across source packages, deployment bundles, and backups.
I checked the workflow from both sides, and this is the distinction I would use:
- Machine-to-machine or server-to-server: .tar.gz
- Server-to-person across mixed desktop systems: .zip
### Updating and accessing archive contents
A plain tar archive can be updated with operations such as appending another file:
```
```
```
tar -rf logs.tar latest.log
```
If ownership is important, remember that restoring the original owner may require root privileges. An archive can contain ownership information without the current user having permission to apply it.
That does not work the same way with a gzip-compressed .tar.gz, because the archive is wrapped in one compressed stream. In practice, I usually rebuild a compressed tar archive instead of trying to modify it in place.
ZIP is friendlier when entries need to be added or replaced:
```
```
```
zip reports.zip september-report.csv
```
ZIP is also more convenient for extracting a single known member:
```
```
```
unzip reports.zip september-report.csv
```
You can extract a selected member from a tar archive too:
```
```
```
tar -xzf website-files.tar.gz website-files/config/app.conf
```
The practical distinction is that gzip compression is stream-oriented, whereas ZIP keeps a directory of individually compressed entries. For routine full restores, that difference may not matter. For repeated access to individual files inside a large archive, it can.
## Which format should you use for common Linux tasks?
There is no need to turn every archive decision into a benchmark. The intended use usually gives the answer.
### Linux server and website backups
Choose .tar.gz for a filesystem backup of website code, uploaded files, deployment scripts, or server configuration. It is the more natural Linux format and is less likely to surprise you around links and permission bits.
For a typical website archive, I would use:
```
```
```
tar -czf example.com-files-2026-09-05.tar.gz /var/www/example.com
```
Do not treat that command as a complete live-website backup. A database-backed application also needs a consistent database dump, and files that are changing during the archive process can produce an inconsistent recovery point. Store backups outside the server and test a restore periodically.
### Deployment packages and configuration directories
Choose .tar.gz when a deployment bundle contains shell scripts, executable files, symlinks, or Linux-specific configuration. I also prefer it when moving an application directory between two Linux hosts because the intent is restoration, not merely sharing.
One caution: avoid archiving secrets into a deployment package just because the command makes it easy. Check for .env files, private keys, backup credentials, and application-generated cache directories. Exclude what should not travel:
```
```
```
tar -czf release.tar.gz \
--exclude='.env' \
--exclude='storage/logs/*' \
--exclude='node_modules' \
my-application/
```
I like to list the finished archive immediately afterward:
```
```
```
tar -tzf release.tar.gz | less
```
That quick check catches accidental paths before the package leaves the server.
### Documents, images, and files for clients
Choose ZIP for ordinary downloads and client hand-offs. If the recipient only needs documents, exported data, images, or other regular files, Linux ownership and symbolic links are irrelevant. Ease of opening the archive matters more.
For example:
```
```
```
zip -r client-assets.zip client-assets/
```
If the folder mostly contains JPEG images and MP4 videos, do not expect a dramatic size reduction. Those formats are already compressed. ZIP still adds value by putting everything into one downloadable file.
### Large sets of similar text files
Try .tar.gz first for logs, source code, CSV exports, and configuration collections. Because gzip sees the combined tar stream, it can take advantage of repetition across files.
My test directory was deliberately mixed, yet .tar.gz still came out a little smaller than ZIP. If storage cost or transfer time matters at scale, repeat the comparison with real production-like data and several runs. A tiny synthetic test should guide a question, not settle it forever.
### When no compression is useful
Sometimes plain .tar is the right answer. On a fast local network, you may care more about low CPU use than reducing bytes. A plain tar stream is also useful in pipelines:
```
```
```
tar -cf - application/ | ssh user@backup-server 'tar -xf - -C /backups/application'
```
This streams the archive over SSH without first creating a local archive file. The connection is encrypted, but the data is not compressed by this command. Depending on your data and network, you can add compression deliberately rather than automatically.
## Safe commands I would keep nearby
| **Task** | **tar** | **ZIP** |
|---|---|---|
| **Create** | tar -czf archive.tar.gz directory/ | zip -r archive.zip directory/ |
| **List** | tar -tzf archive.tar.gz | unzip -l archive.zip |
| **Extract** | tar -xzf archive.tar.gz | unzip archive.zip |
| **Extract elsewhere** | tar -xzf archive.tar.gz -C /target | unzip archive.zip -d /target |
| **Test/read archive** | tar -tzf archive.tar.gz > /dev/null | unzip -t archive.zip |
| **Exclude a path** | tar -czf archive.tar.gz –exclude=’cache’ directory/ | zip -r archive.zip directory/ -x ‘\*/cache/\*’ |
Be careful with archive filenames and source paths. A typo can place the archive inside the directory being archived, or extract files into your current working directory when you expected a new folder.
For untrusted archives, I use a new empty directory, inspect the member list, and extract as an unprivileged user. Do not casually run sudo tar -x… on an archive you did not create or verify.
[](https://serveravatar.com/?ref=blog)## Common mistakes I see with tar and ZIP
**Calling `.tar` a compressed file**
A plain tar archive may be slightly larger than the source directory because it adds headers and block padding. If size reduction is the goal, use `.tar.gz` rather than `.tar`.
**Forgetting recursive mode with ZIP**
Use `zip -r` for a directory. Then run `unzip -l archive.zip` and confirm the nested content is present.
**Trusting the extension instead of testing the archive**
A filename can be wrong or a transfer can be incomplete. Test the actual archive:
```
```
```
tar -tzf archive.tar.gz > /dev/null && echo "tar archive is readable"
unzip -t archive.zip
```
These checks confirm that the tools can read the archive. For important backups, go further and perform a test restoration.
**Expecting compression to protect sensitive data**
Compression is not encryption. A `.tar.gz` archive has no built-in password layer. Traditional ZIP password protection also has compatibility and security caveats, depending on the encryption method and tool used.
For confidential server data, use a properly designed encryption workflow and manage keys separately. Do not assume an unfamiliar extension makes an archive private.
**Ignoring free disk space during extraction**
The compressed size is not the restored size. Check the destination filesystem before extraction:
```
```
```
df -h /target/path
```
This matters when an archive contains large logs or database exports that compress unusually well. A 2 GB archive can expand far beyond 2 GB.
## Key takeaways
- Tar archives files; gzip commonly compresses the resulting tar stream.
- .tar.gz is usually the better default for Linux server files and metadata.
- ZIP is usually easier for cross-platform sharing and individual-file access.
- Compression results depend heavily on the data, so test representative files when size matters.
- A backup is only trustworthy after you have tested its restoration.
## Conclusion
After comparing the structure, commands, metadata handling, compatibility, and a real mixed-file test, I would use .tar.gz for most Linux-native work. It is the sensible default for server directories, website files, deployments, and recoverable backups.
I would choose ZIP when convenience for the recipient matters more than preserving Linux-specific details. That includes client downloads, exported reports, images, and documents meant for mixed operating systems.
The important detail is not which format “wins.” It is whether the restored result matches what you need. If executable permissions and symbolic links matter, test them. If cross-platform opening matters, test that too.
## FAQs
### Is tar better than ZIP in Linux?
Tar with gzip is usually better for Linux-native backups and application directories because it handles Unix filesystem structure and metadata more naturally. ZIP is better when easy sharing across Windows, macOS, and Linux is the main requirement.
### Does tar compress files more than ZIP?
Not by itself. Plain tar does not compress. A .tar.gz archive uses gzip, and it may compress collections of similar small files more effectively because gzip processes the combined tar stream. Actual results depend on the content and settings.
### What is the difference between .tar and .tar.gz?
.tar is an uncompressed archive containing one or more files. .tar.gz is that tar archive compressed with gzip. Use .tar when bundling or streaming is enough; use .tar.gz when you also want to reduce the size.
### Can Windows open .tar.gz files?
Current Windows environments and many third-party archive tools can open .tar.gz, but ZIP remains the more familiar choice for broad desktop sharing. If you do not control the recipient’s setup, ZIP usually creates less friction.
### Which format should I use for a website backup?
Use .tar.gz for the website’s Linux filesystem content, particularly when permissions and symbolic links matter. Back up the database consistently as well, store copies off the source server, and test a full restore rather than only checking that the archive exists.
If you manage several websites and servers and want a simpler way to handle application backups, deployments, SSL, security, and routine server operations, [ServerAvatar](https://serveravatar.com/) can bring those tasks into one dashboard without hiding the Linux fundamentals behind them.
### About the Author
Meghna Meghwani is a technical writer focused on Linux, Ubuntu, VPS hosting, server management, WordPress, PHP, Node.js, cloud hosting, and DevOps. She creates beginner-friendly tutorials, practical hosting guides, troubleshooting articles, and server security content designed to help developers and businesses manage applications and servers more efficiently.
**Categories:** Blog, Guide, Linux, Others, Ubuntu
**Tags:** compress files in Linux, DevOps, extract files in Linux, Linux archive formats, Linux compression, Linux file compression, Linux Tutorial, tar command, tar vs ZIP, tar.gz
---
### [How to Reduce Cache Misses and Improve Application Performance](https://serveravatar.com/reduce-cache-misses-application-performance/)
**Published:** September 4, 2026
**Author:** Meghna Meghwani
**Content:**
[](https://serveravatar.com/?ref=blog)A cache is supposed to remove work. Yet an application can have Redis installed, a CDN enabled, and a page-cache plugin active while still rebuilding the same responses again and again. To reduce cache misses, you must ensure the application can consistently reuse cached data. The problem usually isn’t a missing cache, it’s a cache that the application can’t reuse effectively.
Learning how to reduce cache misses starts with finding out *why* a lookup failed. A short lifetime, an unstable key, an undersized memory limit, and an intentional bypass can all increase the miss counter, but they require very different fixes. Increasing memory won’t repair a key that changes on every request. A longer TTL won’t help when authenticated traffic bypasses the page cache by design.
This guide is for developers, WordPress administrators, and teams running PHP, Laravel, or Node.js applications on a VPS. You’ll learn how to read the right metrics, classify misses, improve cache reuse safely, and verify that the changes reduce real response time rather than merely producing a prettier hit-rate percentage.
## TL;DR
- Measure hit rate, misses, evictions, latency, memory, and origin work together.
- Separate expected cold or bypassed requests from avoidable misses before tuning anything.
- Normalize cache keys so equivalent requests map to the same entry.
- Assign TTLs according to the cost and volatility of each data type, not one global number.
- Prevent cache stampedes with request coalescing, locks, early refresh, or stale-while-revalidate.
- Invalidate the smallest affected cache area after a write; avoid routine full-cache flushes.
- Confirm improvements with p95 response time, database load, and field Core Web Vitals.
## Why a Cache Miss Is Only the Beginning
A cache hit occurs when the requested value is present, valid, and reusable. A miss means the application has to obtain or compute that value elsewhere. The fallback might be a database query, an API call, a rendered HTML page, or an expensive calculation.

**The basic hit-rate formula is:**
```
```
```
Cache hit rate = hits / (hits + misses) × 100
```
If a cache records 72,000 hits and 18,000 misses, its hit rate is 80%. That number is useful, but it isn’t a verdict. A cache protecting a slow third-party API may deliver major savings at 80%, while an edge cache for versioned CSS files should normally reuse far more requests. Context matters.
You also need to distinguish the layer being measured. Browser cache, CDN cache, NGINX page cache, PHP OPcache, Redis object cache, and an application-level memoization cache do different jobs. Combining their counters into one ratio hides the bottleneck.
The practical question is not “How do I make the hit rate 100%?” It is: Which expensive operations are repeated, and why can’t the existing cache answer them?
That framing prevents two common mistakes: caching data that should remain dynamic and optimizing cheap lookups while a slow database query remains untouched.
## Classify the Cache Miss Before Changing Configuration
Most application cache misses fit one of five operational categories. Identify the category first; then choose the remedy.
| **Miss pattern** | **What it looks like** | **Likely cause** | **Useful response** |
|---|---|---|---|
| **Cold miss** | Spike after deploy, restart, or purge | Entry has never been created | Warm only critical keys or accept the brief cold period |
| **Expired miss** | Entries disappear on a predictable schedule | TTL ends before the next reuse | Revisit TTL by data type and add jitter |
| **Capacity miss** | Evictions rise as memory fills | Working set is larger than available cache | Remove low-value entries, tune policy, or add capacity |
| **Key-fragmentation miss** | Similar requests create many near-duplicate keys | IDs, parameters, locale, or ordering aren’t normalized | Redesign and version the key format |
| **Intentional miss** | Logged-in, checkout, preview, or personalized requests bypass cache | Safety rule or application requirement | Keep the bypass and optimize the underlying path |
A sixth pattern deserves special attention: invalidation churn. Here the cache is populated correctly but broad purge events remove useful entries too often. Publishing one article should not force every unrelated page, tenant, or product to become cold.
### Start with one slow request path
Don’t begin with server-wide tuning. Pick one route that is both frequent and expensive, such as a product category page, an API endpoint, a dashboard widget, or a WordPress archive.
Record:
- p50 and p95 response time
- requests per minute
- cache status or application cache outcome
- database query count or duration
- upstream API time
- CPU and memory during the same interval
Then compare the same route for a cold request and a repeated request. If both take roughly the same time, either the response isn’t cacheable, the key changes, the write fails, or a bypass rule is active.
## Measure Cache Behavior Without Disturbing Production
Redis provides cumulative counters that are safer for routine diagnosis than streaming every command in real time.
Start with:
```
```
```
redis-cli INFO stats | grep -E 'keyspace_hits|keyspace_misses|evicted_keys|expired_keys'
```
```
```
```
redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy|mem_fragmentation_ratio'
```
If authentication is enabled, avoid placing the password directly in shell history. Use the connection method already configured for your application or an appropriately protected Redis CLI configuration.
Capture the hit and miss counters, wait through a representative traffic window, and capture them again. Calculate the rate from the difference between the two samples. Using lifetime totals can conceal a problem that began after the last deployment.
For HTTP caches, expose a cache-status response header in a non-sensitive environment or inspect the header your CDN already provides. For example, an NGINX FastCGI configuration can return its cache result during testing:
```
```
```
add_header X-Cache-Status $upstream_cache_status always;
```
Typical values include HIT, MISS, BYPASS, EXPIRED, and UPDATING. Remove or restrict diagnostic headers if they reveal details you don’t want to expose publicly.
Avoid running redis-cli MONITOR casually on a busy production server. It streams every command and can create unnecessary overhead as well as expose sensitive values. Likewise, FLUSHALL is not a troubleshooting shortcut. On a multi-application server, it can empty unrelated databases and create a synchronized burst of expensive regeneration.
### Read related metrics as a group
A rising hit rate is good only when the rest of the system improves. Watch these signals together:
- **Evicted keys:** rising evictions suggest memory pressure or a poor eviction policy.
- **Expired keys:** high expiration volume may be normal, but synchronized expiration can trigger load spikes.
- **Redis latency:** a remote or overloaded cache can cost more than a cheap computation.
- **Origin response time:** p95 and p99 reveal tail latency hidden by averages.
- **Database load:** query time and connection pressure should fall for paths protected by object caching.
- **Error rate:** timeouts and connection errors can make a healthy cache appear ineffective.
## Make Equivalent Requests Share the Same Cache Key
Key design is often the highest-leverage fix because a fragmented keyspace wastes both memory and compute. Two requests that should return the same data must resolve to the same canonical key.
**Suppose an endpoint accepts these URLs:**
```
```
```
/api/products?category=shoes&page=1
```
```
```
```
/api/products?page=1&category=shoes
```
```
```
```
/api/products?category=shoes&page=01&utm_source=email
```
If parameter order, number formatting, or tracking parameters are included naively, the application may store three entries for one response. Normalize the request before hashing it:
- Keep only parameters that change the response.
- Sort parameter names.
- Normalize case, Unicode, booleans, and numeric formats.
- Include tenant, locale, currency, role, or permission scope only when each changes the result.
- Add a schema or deployment version so incompatible entries can be retired safely.
**A practical key might look like:**
catalog:v3:tenant\_42:locale\_en-IN:category\_shoes:page\_1
Never include secrets, full authorization tokens, or raw personal data in cache keys. Even when values aren’t returned to users, keys can appear in logs, dashboards, and debugging output.
### Don’t over-personalize the key
Including a user ID in every key eliminates reuse between users. Sometimes that isolation is required, for example, account balances or private dashboards. Public product data, country-level tax tables, and shared feature configuration may instead be cached by the smallest safe audience segment.
The rule is simple: vary the key on everything that changes the response, but nothing else. Underspecifying a key can leak or serve incorrect data. Overspecifying it creates avoidable misses.
## A Practical Framework for Choosing TTLs
A time to live (TTL) is a freshness decision, not simply a performance setting. Set it too short and useful entries expire before reuse. Set it too long without a reliable invalidation path, and users may see stale data.
**Use three questions for each cache family:**
- **How expensive is regeneration?**
A 400 ms database aggregate deserves more protection than a 1 ms lookup.
- **How often does the source change?**
Configuration may remain stable for hours; inventory can change within seconds.
- **What is the cost of staleness?**
A stale blog archive is inconvenient. Stale authorization data can be dangerous.
**This produces a policy rather than one global TTL:**
| **Data type** | **Starting approach** | **Invalidation trigger** |
|---|---|---|
| **Versioned static asset** | Long browser/CDN lifetime | New filename or content hash |
| **Public article or documentation page** | Moderate page-cache lifetime | Publish or update event |
| **Expensive shared query** | Moderate object-cache lifetime | Model or record change |
| **Product availability** | Short lifetime or event-driven update | Inventory write |
| **Permission or security decision** | Very short lifetime or no cache | Role, session, or policy change |
| **Empty or missing result** | Brief negative-cache lifetime | Creation event or short expiry |
Treat these as policy categories, not universal durations. Your correct numbers depend on traffic, update frequency, and acceptable staleness.
### Add jitter to avoid synchronized expiry
If thousands of keys receive the same 15-minute TTL during a deployment, they may expire together 15 minutes later.
**Add a small random offset so regeneration is spread over time:**
```
```
```
$baseTtl = 900; // 15 minutes
$jitter = random_int(0, 120);
$cache->put($key, $value, $baseTtl + $jitter);
```
Jitter doesn’t reduce the total amount of future work. It prevents that work from landing on the database in one sharp burst.
### Cache “not found” briefly
Repeated requests for a missing record can bypass a cache if the application treats null as “no cached value.” Use a distinct sentinel and a short TTL for negative results. That helps absorb bot traffic, typo-heavy searches, and repeated checks for unavailable resources without preserving absence for too long.
## Stop One Miss from Becoming a Traffic Spike
When a popular entry expires, many workers can miss it at the same moment. Each worker then performs the same expensive query or API request. This is a cache stampede, and it can overload the origin even when the cache is healthy most of the day.
**Four patterns are useful:**
**Request coalescing**
Allow one worker to regenerate the value while the others wait briefly for that result. A distributed lock must have a short expiry and a unique owner token so a crashed worker can’t hold it forever or release another worker’s lock.
```
```
```
value = cache.get(key)
if value exists:
return value
if lock.acquire("lock:" + key, ttl=10 seconds):
try:
value = cache.get(key)
# check again after acquiring lock
if value is missing:
value = origin.load()
cache.set(key, value, ttl_with_jitter)
return value
finally:
lock.release_if_owner()
wait briefly, then retry cache
```
The second lookup inside the lock matters. Another worker may have populated the value while this worker was waiting.
**Stale-while-revalidate**
Serve a slightly stale response for a bounded period while one background task refreshes it. This works well for public content and shared API responses where brief staleness is acceptable. It is usually unsuitable for authorization checks or data that must be current.
**Early refresh**
Refresh a hot entry shortly before it expires. Trigger refresh based on remaining lifetime, request frequency, or a scheduled job. Use this selectively; warming every possible key merely shifts load and stores data nobody requests.
**Graceful fallback**
Decide what happens if Redis or the CDN is unavailable. The application might query the origin, return a last-known value, shed nonessential work, or apply a short circuit breaker. A cache should improve resilience, not become a mandatory single point of failure unless the architecture explicitly accepts that tradeoff.
## Invalidate Precisely Instead of Purging Everything
Cache invalidation is where performance and correctness meet. The safest design links a source-data change to the smallest predictable group of affected keys.
**For example, changing one product may require invalidating:**
- that product’s detail entry
- category pages containing the product
- a price or inventory fragment
- selected API representations
It probably doesn’t require clearing user sessions, unrelated article pages, or every object stored by another application.
Useful techniques include namespace versioning, cache tags, dependency maps, and event-driven invalidation. Namespace versioning is especially simple: increment catalog:v3 to catalog:v4 after a format change and let older keys expire naturally. This avoids a blocking scan-and-delete operation during deployment.
After a write, decide whether to use delete-on-write or update-on-write. Deleting is simpler and lets the next reader rebuild from the source of truth. Updating can avoid the next miss but introduces more paths where cached and canonical data can diverge.
Whatever you choose, make invalidation observable. Log the event type, namespace or tags affected, number of entries removed, and duration. If the miss rate jumps every time an editor publishes a post, the purge scope is probably too broad.
## Match the Technique to the Application Layer
Cache tuning is most effective when each layer has a clear responsibility.
### WordPress: separate page caching from object caching
A page cache stores rendered HTML for reusable public requests. An object cache stores reusable results such as options, query results, and computed objects. One doesn’t replace the other.
Logged-in sessions, carts, checkout pages, previews, and personalized fragments commonly bypass full-page caching to preserve correctness. Treat those bypasses as expected. Optimize their database work with a persistent object cache, better queries, and PHP OPcache rather than trying to force every response into the page cache.
WordPress’s official [caching overview](https://developer.wordpress.org/advanced-administration/performance/cache?ref=serveravatar.com) distinguishes browser, object, and server caching and notes that cached data should be replaceable and regenerable.
ServerAvatar users can follow the existing [Redis Object Cache setup guide](https://serveravatar.com/install-redis-object-cache-plugin-wordpress/); Redis is already installed and configured on newly connected ServerAvatar servers, while the WordPress plugin and application credentials still need to be connected correctly.
Use a different Redis database or a reliable key prefix for each site where supported. Avoid a server-wide flush. After plugin, theme, or schema changes, purge only the cache the change invalidates and verify both a logged-out and logged-in request.
### Laravel: cache the expensive boundary, not the whole controller
Laravel’s cache-aside pattern is useful for shared queries:
```
```
```
use Illuminate\Support\Facades\Cache;
$key = "product-summary:v2:{$storeId}:{$categoryId}";
$summary = Cache::remember(
$key,
now()->addMinutes(10),
fn () => $service->buildCategorySummary($storeId, $categoryId);
```
The hard part isn’t Cache::remember; it’s invalidation. When a product affecting the summary changes, remove or version the relevant key. For high-concurrency regeneration, use Laravel’s atomic locks with an expiry and handle lock timeouts rather than allowing every PHP-FPM worker to rebuild the same result.
Don’t cache an entire authenticated controller response unless the key includes every permission and personalization dimension. Caching the expensive shared service result is usually easier to reason about.
### Node.js: don’t let per-process memory fragment the cache
An in-memory Map can be effective inside one process, but multiple Node.js workers each build a separate cache. After a restart or scale-out, every worker begins cold. Use a shared cache such as Redis for entries that must be reused across processes, while keeping tiny process-local caches only where duplication is acceptable.
Normalize keys before serialization, avoid unbounded Maps, and make concurrent promise coalescing part of the loader. Also measure event-loop delay. A higher hit rate won’t rescue an application that blocks the event loop while serializing very large values.
## Fix Cache Waste Before Adding Memory
Adding RAM can reduce capacity misses, but it should follow key and value cleanup. First check:
- Are duplicate key variants storing the same response?
- Are values much larger than the data actually read?
- Are one-off results cached despite never being reused?
- Are abandoned namespaces lingering after deployments?
- Is the cache sharing memory with queues, sessions, or another workload?
Then choose an eviction policy that matches the role of the Redis instance. A cache-only instance can evict data under pressure; an instance containing sessions, queues, or durable-looking state requires much more careful separation and policy selection. Don’t assume every Redis key is disposable simply because Redis is being used “as a cache.”
Large values also have hidden costs: serialization time, network transfer, allocator overhead, and longer blocking operations. Caching a smaller projection often improves latency and effective capacity more than adding memory.
## Use a Safe Test Plan for Every Cache Change
A cache adjustment should be treated like an application change because it can affect correctness, privacy, and load.
- Record a baseline. Capture route-level latency, hit and miss deltas, evictions, database time, CPU, memory, and errors.
- Change one cache family. Adjust one key pattern, TTL policy, invalidation event, or memory setting at a time.
- Test correctness. Check anonymous, authenticated, privileged, localized, and personalized requests where applicable.
- Test cold behavior. Restart or invalidate the chosen test namespace and observe regeneration under controlled load.
- Test failure behavior. Confirm the application has an acceptable response when the cache is slow or unavailable.
- Compare the same traffic window. Look for improvement in p95 response time and origin load, not only hit rate.
- Keep a rollback. Preserve the previous configuration and document the namespace or setting changed.
For public web pages, also measure field data after deployment. Google says its systems aim to reward helpful, reliable, people-first content and an overall good page experience, not a single isolated metric. Its current Core Web Vitals guidance defines “good” as LCP within 2.5 seconds, INP below 200 ms, and CLS below 0.1 at the 75th percentile. See Google’s [Core Web Vitals guidance](https://developers.google.com/search/docs/appearance/core-web-vitals?ref=serveravatar.com).
Caching can improve server response time and reduce work feeding into LCP and INP, but it doesn’t automatically fix render-blocking CSS, large images, JavaScript execution, or layout shifts. Validate those separately with PageSpeed Insights and Search Console field data.
[](https://serveravatar.com/?ref=blog)## A Practical Cache-Miss Troubleshooting Checklist
Work through this sequence when the miss rate rises unexpectedly:
- Confirm which cache layer produced the metric.
- Limit analysis to a route, key family, tenant, or application.
- Compare counter deltas over a representative period.
- Separate MISS, BYPASS, EXPIRED, and cache errors.
- Check whether a deploy, restart, purge, or content update preceded the change.
- Inspect key cardinality and normalization.
- Compare TTL with actual reuse intervals.
- Check evictions, maximum memory, and eviction policy.
- Look for synchronized expiry and concurrent regeneration.
- Review invalidation scope after writes.
- Verify that cache reads and writes use the same key, prefix, database, and serialization format.
- Test anonymous and personalized paths independently.
- Confirm lower p95 latency, database time, and CPU after the fix.
If the hit rate remains low but origin cost and response time are already small, caching that path may not be worthwhile. Removing a low-value cache can simplify the system and eliminate invalidation risk.
## Key Takeaways
- A cache miss counter tells you what happened, not why it happened.
- Stable, correctly scoped keys usually matter more than a blanket TTL increase.
- TTLs should reflect regeneration cost, update frequency, and the risk of stale data.
- Locks, coalescing, early refresh, and stale-while-revalidate prevent popular keys from overwhelming the origin.
- Precise invalidation preserves useful entries and avoids post-publish traffic spikes.
- Hit rate must be evaluated beside tail latency, database work, evictions, errors, and user-facing performance.
## Conclusion
The best cache isn’t the one with the biggest number on a dashboard. It’s the one that removes meaningful work while keeping responses correct.
Begin with a single expensive route. Measure it, classify its misses, then fix the narrowest cause, key design, TTL, invalidation, memory pressure, or regeneration concurrency. Once the result is visible in p95 latency and origin load, apply the same method to the next route.
If you manage WordPress, Laravel, PHP, or Node.js applications across VPS instances, [ServerAvatar](https://serveravatar.com/) can simplify deployment and ongoing server management. Its application dashboards, file access, Redis-ready server stack, and Log Monitoring Suite give you a practical place to operate and observe the systems around your cache without turning this article into a product pitch.
## FAQs
### What is a good cache hit rate for an application?
There is no universal target. A good rate depends on the cache layer, request mix, data volatility, and cost of a miss. Evaluate hit rate beside p95 latency, origin load, evictions, and correctness. A lower rate on highly dynamic traffic may be healthy, while frequent misses for versioned static assets indicate a configuration problem.
### How do I reduce Redis cache misses?
Measure keyspace\_hits, keyspace\_misses, expirations, evictions, latency, and memory over the same traffic window. Then normalize keys, remove low-value entries, tune TTLs by data type, narrow invalidation, and prevent concurrent regeneration. Add memory only when the useful working set genuinely exceeds available capacity.
### Can increasing the cache TTL cause stale data?
Yes. A longer TTL improves the chance of reuse but extends the period in which old data may be served. Pair longer TTLs with precise invalidation for data that changes, and keep security-sensitive or rapidly changing values on short lifetimes or out of the cache.
### Why does my cache hit rate drop after a deployment?
A restart may clear process-local caches, while a new namespace or full purge makes shared caches cold. Key-format changes can also make old entries unreachable. Version keys deliberately, warm only critical paths, add TTL jitter, and monitor regeneration load during deployment.
### Do cache misses directly hurt Google rankings?
Google doesn’t publish cache hit rate as a ranking factor. Cache misses matter indirectly when they make real pages slower or less reliable. Google recommends a good overall page experience and currently uses LCP, INP, and CLS to describe loading, responsiveness, and visual stability. Optimize caching for users and application health, then confirm the effect with field performance data.
### Explore Related Guides
- [How To Use Redis Full-Page Caching To Speed Up WordPress](https://serveravatar.com/redis-full-page-caching-wordpress/)
- [Install Redis Object Cache Plugin into WordPress](https://serveravatar.com/install-redis-object-cache-plugin-wordpress/)
- [How to speed up a WordPress website: 12 performance optimization methods](https://serveravatar.com/speed-up-a-wordpress-website-performance/)
### About the Author
Meghna Meghwani is a technical writer focused on Linux, Ubuntu, VPS hosting, server management, WordPress, PHP, Node.js, cloud hosting, and DevOps. She creates beginner-friendly tutorials, practical hosting guides, troubleshooting articles, and server security content designed to help developers and businesses manage applications and servers more efficiently.
**Categories:** Blog, Guide, Linux, Optimisation, Others, Tutorials, Ubuntu
**Tags:** Application Caching, Application Performance, Cache Hit Rate, Cache Optimization, CDN Optimization, Redis Caching, Reduce Cache Misses, Web Performance
---
### [How to Send Emails From WordPress Using Gmail SMTP for Free](https://serveravatar.com/wordpress-gmail-smtp/)
**Published:** September 3, 2026
**Author:** Meghna Meghwani
**Content:**
[](https://serveravatar.com/?ref=blog)WordPress may show a reassuring “message sent” notice even when no email reaches the recipient. That gap is frustrating when the missing message is a password reset, contact-form notification, new-account email, or order receipt. WordPress Gmail SMTP provides a reliable way to send emails through Email’s SMTP server instead of relying on your web host’s default mail function.
You can send emails from WordPress using Gmail SMTP without paying for a separate email service. The setup in this guide uses FluentSMTP, a free WordPress plugin, and a Google App Password. It is suitable for personal sites, portfolios, staging sites, and small websites that send a modest number of transactional messages.
This isn’t a newsletter solution, and it won’t guarantee inbox placement. What it will do is replace the server’s often-unreliable default mail path with an authenticated connection to Gmail. You’ll learn how to decide whether Gmail is appropriate, prepare the account safely, configure WordPress, verify more than a green success message, and diagnose the failures that usually trip people up.
## TL;DR
- Install the free FluentSMTP plugin and select Other SMTP.
- Use smtp.gmail.com, TLS encryption, and port 587.
- Turn on Google 2-Step Verification and create a dedicated App Password.
- Keep the WordPress From Email identical to the Gmail account used for authentication.
- Send a test, inspect the email log, and check the received message headers.
- Use Gmail only for low-volume transactional messages, not newsletters or bulk campaigns.
- Prefer OAuth when your chosen plugin offers a practical Gmail integration; Google recommends it over App Passwords.
## First, Understand What This Setup Changes
WordPress applications commonly call the [wp\_mail() function](https://developer.wordpress.org/reference/functions/wp_mail?ref=serveravatar.com) when they need to send a message. By itself, wp\_mail() is only an interface. It passes the message to the configured mailer; it does not provide a reputation system or an email-delivery network.
On many VPSs, WordPress hands mail to PHP’s local mail function. That route can fail because the server has no mail transfer agent, outbound SMTP ports are restricted, the sending IP has a poor reputation, or the message lacks authentication that receiving providers expect.
An SMTP plugin changes the transport. Instead of asking the web server to deliver the message directly, WordPress authenticates with Gmail and asks Google to send it.
| **Component** | **Its job in this setup** |
|---|---|
| **WordPress or a plugin** | Creates the email and recipient details |
| **FluentSMTP** | Intercepts WordPress mail and applies the configured connection |
| **Gmail SMTP** | Authenticates the request and submits the message |
| **Receiving mail server** | Accepts, filters, rejects, or places the message |
| **Email log** | Records what WordPress attempted and any returned error |
This distinction matters during troubleshooting. A successful plugin log means Gmail accepted the submission. It does not prove that the recipient’s provider placed the message in the inbox.
Email reliability is only one part of WordPress performance; if your site also has slow server response times, see our [**WordPress TTFB optimization guide**](https://serveravatar.com/wordpress-ttfb-optimization).
## Is Free Gmail SMTP the Right Choice for Your WordPress Site?
Gmail SMTP is useful when the site sends occasional operational emails. Think of a portfolio contact form, a small membership site, an internal staging environment, or a low-traffic blog where password resets are the main concern.
**It is a poor fit for:**
- Marketing newsletters
- Large membership communities
- Busy WooCommerce stores
- Applications with bursts of notifications
- Sites that need delivery analytics, bounce processing, suppression lists, or guaranteed support
Google enforces sending and recipient limits, and the thresholds vary by account type and sending method. See Google’s [Gmail sending limits](https://support.google.com/mail/answer/22839?ref=serveravatar.com) for the current restrictions. Google’s consumer help page warns that sending may be suspended temporarily when limits are reached, while Google Workspace publishes separate limits for paid organizational accounts. Treat those limits as ceilings, not daily targets. They can change, and anti-abuse systems can restrict suspicious sending before a published maximum is reached.
If your site sends only a few dozen transactional messages on a normal day, Gmail can be a sensible free starting point. If email is tied directly to revenue or customer access, use a transactional provider designed for application mail.
### Gmail SMTP settings at a glance
| **Setting** | **Recommended value** |
|---|---|
| **SMTP host** | smtp.gmail.com |
| **Encryption** | TLS / STARTTLS |
| **Port** | 587 |
| **Authentication** | Enabled |
| **Username** | Your complete Gmail or Google Workspace address |
| **Password** | A 16-character Google App Password, not your normal password |
| **From Email** | The authenticated Google address, unless a verified alias is configured |
Port 465 with SSL is also supported by many mail clients, but this tutorial uses port 587 with STARTTLS. Choosing one complete pair avoids the common mistake of combining TLS with the SSL port.
## What You Need Before Changing WordPress
Do a short preflight check before installing anything. It prevents most configuration loops.
**You need:**
- Administrator access to WordPress.
- A Gmail or Google Workspace account that you control.
- 2-Step Verification enabled for that Google account.
- Permission to create an App Password.
- A WordPress site using HTTPS.
- A recipient address on another provider for meaningful testing, if possible.
Google only exposes App Passwords after [2-Step Verification](https://support.google.com/accounts/answer/10956730?ref=serveravatar.com) is enabled. The option may still be unavailable when the account is enrolled in Advanced Protection, uses security-key-only 2-Step Verification, or is controlled by an organization that blocks App Passwords.
Google also states that App Passwords are not its preferred connection method. When a plugin supports “Sign in with Google” or a native Gmail OAuth connection, OAuth is the better long-term choice because the site does not store a reusable mail password. We’re using an App Password here because it provides a direct, free SMTP configuration and is widely supported.
> **Security note:** Never paste the App Password into a support ticket, screenshot, shared document, or chat. Anyone who obtains it may be able to use the authorized Gmail connection until you revoke it.
## Configure WordPress to Send Through Gmail SMTP
The following workflow uses [FluentSMTP](https://wordpress.org/plugins/fluent-smtp?ref=serveravatar.com). It is available in the WordPress plugin directory, supports standard SMTP, provides email logs, and does not require a paid upgrade for the settings used here.
**1. Install FluentSMTP and open its connection screen**
- In WordPress admin dashboard, go to Plugins section >> Add Plugin.
- Search for FluentSMTP, install it, and activate it.

- Go to the Installed Plugins section, and click on the Settings for FluentSMTP plugin.

- In a setup screen, choose Other SMTP rather than a provider-specific API connection. “Other SMTP” lets you enter Email’s host, encryption, port, and App Password directly.

- Avoid running two SMTP plugins at the same time. Two plugins can both hook into wp\_mail(), producing inconsistent From addresses, duplicate logging, or a connection that changes depending on load order.
- Deactivate any previous SMTP plugin if using, before using FluentSMTP.
**2. Create a dedicated Google App Password**
For security, you should not use your regular Gmail password directly into the plugin. Instead, create a Google **App Password**, a unique 16-character code that allows a specific app or device to securely access your Google Account without revealing your main password.
- Open the Google account that will send the site’s emails.
- Go to Security and confirm that 2-Step Verification is active.

- Then open the [App Passwords page](https://myaccount.google.com/apppasswords?pli=1&rapt=AEjHL4PPteB0qevPoioL0dBZURoPtfw2doCIZ-6BV2kAqO3nveMGAQUcwSTfb-vUsqyHYgSV_0gUXD9pGrXkfErw9V-7KDwuTp1rlO136LMwmXFa2b9otv4).
- Create a new entry with a App name that identifies both the site and its purpose, such as: example.com WordPress SMTP
- Click on Create button.

- Google displays a 16-character App Password once.
- Copy it immediately.
- The spaces shown on screen are for readability; if the plugin rejects the value, paste it without spaces.

- Using a site-specific label pays off later. If that website is retired, migrated, or compromised, you can revoke only its credential without disrupting other applications.
Do not enter your ordinary Google account password in WordPress. Google ended support for basic “less secure app” sign-ins, and using the normal password also exposes a far more valuable credential than necessary.
**3. Enter the SMTP connection details**
Return to the FluentSMTP connection screen and enter these values:
- **From Email**: the Gmail or Google Workspace address you are authenticating
- **From Name:** the website or business name recipients should recognize
- **SMTP Host:** smtp.gmail.com
- **SMTP Port:** 587
- **Encryption:** TLS or STARTTLS
- **Authentication:** enabled
- **SMTP Username:** the full Google email address
- **SMTP Password:** the App Password created for this site
- Save the connection.

The password field may appear blank or masked afterward; that is normal behavior for a secret value.
**4. Update the General Settings**
- Enable the “Log All Emails for Reporting” option to keep a record of sent emails for reporting and troubleshooting purposes.
- Set how long email logs should be retained.
- Select the primary email connection used to send emails. As here, an **SMTP server connected to a Gmail account** is selected.
- Enable “Email Simulation” option when you want to prevent emails from actually being sent. This is useful when testing email functionality.
- Enable the “Add Multi-Part Plain Text for HTML Emails” beta option to include a plain-text version alongside HTML emails, improving compatibility with email clients that don’t properly render HTML.
- Click Save Settings after making changes to apply the updated email configuration.

For additional configuration details, see the [official FluentSMTP Gmail and Google Workspace setup guide](https://docs.fluentsmtp.com/connect-gmail-or-google-workspace-with-fluentsmtp?ref=serveravatar.com).
## Test the Entire Delivery Path
Clicking Send Test Email is necessary, but it isn’t the complete test. Verify the message at three different layers

**Layer 1: WordPress submission**
Open FluentSMTP’s email test tool and send a plain-text message to an address you can inspect. A successful result confirms that WordPress reached Gmail and Gmail accepted the submission at that moment.
If it fails, copy the exact error before changing settings. Authentication errors, connection timeouts, and rejected sender addresses require different fixes.
**Layer 2: Recipient placement**
Check the inbox, spam folder, promotions tab, and any server-side quarantine. Test at least one address outside the sending Google account. Sending from Gmail back to the same inbox can hide routing and filtering problems that real recipients will face.
**Layer 3: Message identity**
Open the received email’s original source or “Show original” view. Confirm that:
- The visible From address is the one you configured.
- The Reply-To address is correct for form notifications.
- Authentication results do not show an obvious failure.
- The message timestamp and subject match the test.
Then trigger a real WordPress workflow: request a password reset or submit the contact form. A plugin test proves the transport works; a real workflow proves the application is creating the email correctly.
## Fix Common Gmail SMTP Problems in WordPress
Use the error message and symptoms to choose a fix. Randomly switching ports or reinstalling the plugin usually wastes time.
| **Symptom or error** | **Likely cause** | **What to check** |
|---|---|---|
| **Username or password rejected** | Normal password used, App Password mistyped, or credential revoked | Create a fresh App Password and confirm the full email username |
| **App Password option missing** | 2-Step Verification is off or account policy blocks App Passwords | Review Google account security and Workspace administrator policies |
| **Connection timed out** | Hosting provider or firewall blocks outbound SMTP | Test outbound access to smtp.gmail.com:587 and ask the host about restrictions |
| **Test succeeds, form mail fails** | Form plugin has an invalid From address or is not generating mail | Match the From Email and inspect the email log |
| **Message goes to spam** | Content, sender reputation, recipient filtering, or identity mismatch | Inspect headers, simplify the message, and use a consistent sender |
| **Mail stops after a password change** | Google revokes App Passwords after account password changes | Generate a new site-specific App Password |
| **Daily limit error** | Too many messages or recipients | Stop retries, wait for the restriction to clear, and move to a transactional provider |
| **Duplicate messages** | Two SMTP plugins or duplicate application triggers | Keep one mailer active and check form/automation rules |
**Authentication fails even with the correct address**
Generate a new App Password rather than trying your normal password. Confirm that the username includes the full domain, such as name@gmail.com, and paste the App Password without accidental leading or trailing spaces.
If the Google password was changed after the App Password was created, replace the stored SMTP credential. Google revokes App Passwords following a password change.
**WordPress cannot connect to port 587**
A timeout usually points below WordPress. Some hosting networks restrict outbound mail ports to reduce abuse.
> If the SMTP issue is accompanied by a broader WordPress server error, see our guide on [**how to fix the WordPress 500 Internal Server Error**](https://serveravatar.com/fix-wordpress-500-internal-server-error/).
If you have SSH access, you can perform a non-destructive connectivity check:
```
```
```
openssl s_client -starttls smtp -connect smtp.gmail.com:587 -crlf
```
A successful TLS handshake shows that the server can reach Gmail on port 587. Exit with Ctrl+C. This command does not validate your username or send a message.
If the connection times out, check the server firewall and hosting provider’s outbound-email policy. Do not open inbound port 587; WordPress is making an outbound connection.
**The test works, but contact-form notifications do not**
Open the [FluentSMTP email log](https://docs.fluentsmtp.com/fluentsmtp-email-logs-feature?ref=serveravatar.com) immediately after submitting the form.
- No new log entry usually means the form did not call WordPress mail. Check conditional rules, recipient fields, and anti-spam behavior in the form plugin.
- A failed log entry points to a mailer or message error. Read the detailed response.
- A successful entry means Gmail accepted it. Continue checking the recipient’s spam, filtering, and headers.
Also confirm that the form uses the site-controlled Gmail address as From and the visitor’s email as Reply-To.
**Emails arrive, but they land in spam**
SMTP authentication improves the sending path; it cannot guarantee inbox placement. Filters also evaluate message content, links, recipient engagement, sending patterns, and sender history.
For cleaner transactional mail:
- Use a consistent From name and address.
- Avoid URL shorteners and unnecessary attachments.
- Keep password-reset and notification templates focused on one purpose.
- Never send purchased lists or promotional blasts through this connection.
- Ask recipients to allowlist the address only when appropriate; do not treat that as the main fix.
If you send from a business domain through Google Workspace, review the domain’s SPF, DKIM, and DMARC configuration. Those controls deserve their own setup and validation rather than being pasted blindly into DNS.
[](https://serveravatar.com/?ref=blog)## Keep the Connection Secure and Reliable
Email configuration is not a one-time checkbox. Add it to normal WordPress maintenance.
**Use one credential per site**
Name each App Password after its website. Separate credentials make revocation precise and reduce the impact of a leaked secret.
**Restrict administrator access**
Anyone who can change plugin settings may be able to replace or misuse the mail connection. Use individual WordPress accounts, strong passwords, 2FA, and the minimum role each team member needs.
**Limit email-log retention**
Logs may contain recipient addresses, subjects, reset links, or form content. Keep them only as long as they are operationally useful, restrict access, and avoid logging sensitive message bodies when the plugin allows that choice.
**Test after relevant changes**
Send a test after migrating the site, restoring a backup, changing the Google account password, replacing an SMTP plugin, or modifying outbound firewall rules. Also test the real contact or password-reset workflow, not only the plugin’s diagnostic email.
If an interrupted WordPress update leaves your site unavailable, see our guide on [**how to fix WordPress stuck in maintenance mode**](https://serveravatar.com/fix-wordpress-stuck-in-maintenance-mode)
**Monitor failures instead of assuming delivery**
Review failed-message logs periodically. A site can continue operating normally while every outgoing email fails. For business-critical workflows, use monitoring or a transactional provider that supplies bounce events and delivery reporting.
If your WordPress dashboard itself is becoming slow during routine maintenance, see our guide on [**why WordPress Admin is slow and how to fix it**](https://serveravatar.com/fix-slow-wordpress-admin/).
## When to Move Beyond Gmail
There is no magic daily number that fits every site. Move away from Gmail when the consequences of delayed or missing mail become more expensive than a dedicated service.
Strong migration signals include:
- Order receipts or account emails are business-critical.
- Normal traffic creates sudden bursts of messages.
- You need bounce and complaint handling.
- Multiple sites share one sending account.
- You are approaching Google’s limits.
- Support staff need searchable delivery events.
- You want to authenticate and report on a business domain properly.
Transactional email providers are designed for application-generated mail and typically expose delivery events, domain authentication, suppression management, and scalable limits. Gmail remains useful for a small site; it should not become hidden infrastructure for a growing platform.
## Key Takeaways
- Gmail SMTP replaces the web server’s default mail path with authenticated submission through Google.
- FluentSMTP can configure the connection without a paid plugin.
- Use TLS on port 587, a dedicated App Password, and a matching From Email.
- Put a contact-form visitor’s address in Reply-To, not From.
- Verify the plugin log, recipient placement, message headers, and a real WordPress workflow.
- Switch to a transactional provider when volume, reporting, or business risk grows.
## Conclusion
For a small WordPress site, Gmail SMTP is a practical way to make password resets, contact-form alerts, and routine notifications more dependable without adding a monthly email bill.
Start with one controlled test: create a site-specific App Password, configure FluentSMTP with smtp.gmail.com and TLS on port 587, then test both the mailer and the WordPress feature that matters most. Keep the sender address consistent and review the log if anything fails.
The moment email becomes revenue-critical or high-volume, graduate to purpose-built transactional delivery. The free route is valuable because it solves a modest problem cleanly, not because it should be stretched indefinitely.
## FAQs
### Can WordPress send email through Gmail for free?
Yes. A low-volume WordPress site can use Email’s SMTP server with a free SMTP plugin and an eligible Google account. You still need to follow Google’s account and sending limits, and free SMTP does not guarantee inbox placement.
### What are the Gmail SMTP settings for WordPress?
Use smtp.gmail.com as the host, port 587 with TLS/STARTTLS, authentication enabled, your complete Gmail address as the username, and a Google App Password as the password.
### Why can’t I use my normal Gmail password in WordPress?
Google no longer supports basic sign-in through “less secure apps.” For a standard SMTP connection, use a dedicated App Password after enabling 2-Step Verification. If your plugin offers a native Google OAuth connection, Google recommends that approach because it does not share a reusable password with the plugin.
### Why is the Google App Password option missing?
The option may be missing because 2-Step Verification is disabled, the account is enrolled in Advanced Protection, 2-Step Verification uses security keys only, or a Google Workspace administrator has restricted App Passwords.
### Why does FluentSMTP say the email was sent when it never arrived?
“Sent” usually means Gmail accepted the submission. The recipient server can still filter, quarantine, defer, or reject the message later. Check spam and quarantine, inspect the received headers when available, verify the recipient address, and review the FluentSMTP log for the exact event.
### Manage the WordPress Server Behind Your Email Workflow
Reliable mail is only one part of a healthy WordPress setup. The application also depends on secure server access, updated software, SSL, firewall rules, backups, and useful logs.
If you want a simpler way to handle those operational tasks on your own cloud server, [ServerAvatar](https://serveravatar.com) provides a central panel for deploying and managing servers and PHP and Node.js applications without turning every maintenance job into a manual command-line session.
### About the Author
Meghna Meghwani is a technical writer focused on Linux, Ubuntu, VPS hosting, server management, WordPress, PHP, Node.js, cloud hosting, and DevOps. She creates beginner-friendly tutorials, practical hosting guides, troubleshooting articles, and server security content designed to help developers and businesses manage applications and servers more efficiently.
**Categories:** Blog, Guide, Others, Tutorials, WordPress
**Tags:** Gmail SMTP, Gmail SMTP Setup, Send WordPress Emails, SMTP for WordPress, Wordpress, WordPress Email, WordPress Email Delivery, WordPress Email SMTP, WordPress Gmail SMTP, WordPress SMTP
---
### [How to Fix “Cannot Use Import Statement Outside a Module” in JavaScript](https://serveravatar.com/fix-cannot-use-import-statement-outside-module/)
**Published:** August 29, 2026
**Author:** Meghna Meghwani
**Content:**
[](https://serveravatar.com/?ref=blog)You run a JavaScript file that looks perfectly valid, yet the process stops before the first useful line executes: Cannot Use Import Statement Outside a Module.
```
```
```
SyntaxError: Cannot use import statement outside a module
```
The wording makes the `import` statement look guilty. Usually, it isn’t. The real problem is that your runtime and your source file disagree about the file’s module format.
This guide shows you how to identify that disagreement before changing project settings. You’ll learn how to fix the error in Node.js, a browser, TypeScript, and common development tools without creating a second module problem elsewhere. It is written for developers who want a reliable diagnosis, not a list of unrelated commands to try.
## TL;DR
- First identify which program is executing the file: Node.js, a browser, a test runner, or a TypeScript tool.
- In Node.js, choose one module system for the relevant package: ESM with `"type": "module"` or `.mjs`, or CommonJS with `require()` and `.cjs`.
- In a browser, load an entry file with `