Is it the Database or the Network? A Guide to Ending the Blame Game
Is it the Database or the Network? A Guide to Ending the Blame Game
“The application is slow.”
We have all heard this sentence. It usually triggers an endless loop of finger-pointing. The Network Team says the pipes are clean. The Developers swear the code hasn’t changed. The DBA insists the queries are instant.
Instead of guessing, let’s look at the data.

Table of Contents
- Connectivity & DNS: It’s always DNS, isn’t it?
- The “Chatty App” Problem: RTT vs. Execution Time
- The Silent Blocker: MTU & Packet Fragmentation
- Throughput Testing: Is the Pipe Big Enough? (
iperf3) - Route Analysis: Beyond basic Traceroute (
mtr) - The Nuclear Option: Packet Analysis with
tcpdump - Database Configuration: Timeout & Keepalive tuning
1. Connectivity & DNS: It’s always DNS, isn’t it?
Before we dive into complex routing, we must verify the basics. Often, the database is up, but the application cannot resolve its hostname, or a firewall rule is silently dropping packets.
Don’t rely on Ping (ICMP). Most production DBs block it. Use nc (Netcat) to test the specific TCP port.
# 1. Test Port Connectivity
# -z: Scan only, -v: Verbose, -w: Timeout
nc -z -v -w 2 db.production.local 5432
# 2. Test DNS Resolution Latency
# If IP works but Hostname is slow, your DNS is the bottleneck.
time host db.production.local
- Connection Refused: The server is up, but Postgres isn’t listening (or max connections reached).
- Connection Timed Out: A firewall is swallowing the packets.
2. The “Chatty App” Problem: RTT vs. Execution Time
A common scenario: The dashboard is slow, but the slow_query_log is empty. This is often due to Network Round Trip Time (RTT) killing a "chatty" application.
If your app performs 100 sequential queries to load a page, and the network latency is 5ms:
- Database Time: 100 x 0.1ms = 10ms (Fast!)
- Network Travel Time: 100 x 5ms = 500ms (Slow!)
How to verify: Compare the query execution time in Postgres logs vs. the total transaction time in your APM (Application Performance Monitor). If the gap is huge, the network distance is your enemy.
3. The Silent Blocker: MTU & Packet Fragmentation
This is the most overlooked network issue. If your Application Server has an MTU of 1500 (Standard) but a VPN or Router in between has an MTU of 1400, large packets will be dropped if the “Don’t Fragment” (DF) bit is set.
Symptom: Small queries work fine. Large queries (fetching big JSON or text) hang indefinitely.
The Test: Ping with a specific packet size and the “Don’t Fragment” flag.
# Test with 1472 bytes (1500 - 28 bytes header)
ping -M do -s 1472 db.production.local
# If this fails, lower the size until it passes to find the bottleneck.
ping -M do -s 1300 db.production.local
If you find a mismatch, you need to adjust the MTU on your server interface or fix the intermediate router config.
4. Throughput Testing: Is the Pipe Big Enough?
Sometimes, it’s not about latency; it’s about volume. If you are doing a pg_dump or a massive SELECT, you might be saturating the bandwidth.
Use iperf3 to measure the raw speed between App and DB servers.
On DB Server (Listen):
iperf3 -s
On App Server (Send):
iperf3 -c <DB_IP_ADDRESS>
Check the “Retr” column. If retransmissions are high even with good bandwidth, you have a dirty cable or a bad switch port.
5. Route Analysis: Beyond Traceroute
traceroute gives you a static map. mtr (My Traceroute) gives you a live video. It combines ping and traceroute to show packet loss percentages at every hop.
# -r: Report mode, -n: No DNS resolution (faster), -c: Count
mtr -r -n -c 100 db.production.local
How to read it: If Hop 3 shows 0% loss, and Hop 4 shows 20% loss that continues to the end, Hop 4 is your culprit. Call your cloud provider or network admin.
6. The Nuclear Option: Packet Analysis
When all else fails, we capture the traffic. tcpdump allows us to see the TCP Handshake (SYN, SYN-ACK, ACK) and spot retransmissions.
# Capture traffic on port 5432, save to file for Wireshark analysis
sudo tcpdump -i eth0 port 5432 -w db_traffic.pcap
What to look for in Wireshark:
- TCP Retransmissions: Indicates packet loss.
- TCP Zero Window: The receiver (App or DB) is overwhelmed and telling the sender to stop sending data.
- TCP Resets (RST): Something (Firewall, OOM Killer) killed the connection abruptly.
7. Database Configuration: Tuning for Stability
Network glitches happen. Your database configuration determines if the app survives them or crashes.
tcp_keepalives_idle: Default is usually too high (2 hours). Lower it to 60 seconds to detect dead connections faster.statement_timeout: Never let a query run forever. Set a reasonable limit (e.g., 30s) to prevent a network zombie from holding locks.
Conclusion
Blaming the network is easy. Proving it requires data.
By using tools like nc for ports, iperf3 for bandwidth, and ping -M do for MTU checks, you move the conversation from "I think" to "I know."
The next time someone says “The database is slow,” you’ll have the toolkit to find out the truth.
← PostgreSQL Blog