A query that hangs after the TCP handshake is not a routing problem. Route faults fail the handshake, so a session that establishes and then goes quiet points inside the path: inspection, MTU, or the way the tunnel's UDP packets arrive. The decision in front of you is whether to fix that path or move the tunnel to TCP. Three conditions settle it, and none of them is about the database.

Classify the stall before blaming the tunnel

Four outcomes look similar to a user and mean completely different things to an engineer.

What the client seesWhat it rules out
Connection refusedNothing is listening on the address and port the client reached
Timeout before the handshakeA filter, a missing route, or the wrong address
Handshake completes, query hangsThe session exists, so look at inspection, MTU and packet order
Stalls that recover on retryOften reordering, or a state table entry expiring

Only the last two rows justify time on the tunnel. A refused connection across a VPN is usually the database listening on loopback only, which is a listener problem, and a timeout before the handshake is a filter or a route. Neither improves by changing encapsulation.

Write the classification into the ticket first. It is the cheapest step and it removes most of the search space.

Three conditions that decide UDP versus TCP

Encapsulated IPsec traffic rides UDP, and UDP gives the path freedom to reorder and drop without telling anyone. When reordering pushes packets outside the tunnel's anti-replay window, they are discarded silently and the inner TCP session simply waits. That is the mechanism behind a handshake that succeeds and a query that never returns.

Fixing the path or falling back to TCP depends on three things. First, is there real packet loss on the path, or only reordering? Second, can you change where inspection happens, or exclude this tunnel from the component that reorders? Third, is the workload sensitive to the stall pattern, for example many multiplexed sessions sharing one link?

If the first answer is loss and the second is no, TCP on 443 is the pragmatic fallback. If the second answer is yes, fix the path and keep UDP.

Read the firewall record, not the application error

The application reports a timeout, which tells you nothing about cause. The firewall's own log is where the drop or block appears, so filter by the database and application addresses and look for discards as well as accepts. Threat-prevention blades can discard packets without generating an application-level error, which is exactly the shape of a query that hangs. Silence in the log is data too: it points at something that does not log, such as reordering.

Check the cluster as well. A misconfigured cluster can hold a session in the state table on one member while the packets take another member's path, so replies arrive where no state exists. Those stalls look random and do not correlate with load.

Compare both ends before changing anything, and compare arrival order rather than packet counts:

tcpdump -ni any udp port 4500 -w /tmp/encap.pcap
tcpdump -ni any tcp port 5432 -w /tmp/inner.pcap

What TCP on 443 actually costs you

Moving the tunnel to TCP removes the reordering symptom, because the middlebox now sees an ordered stream. It also creates TCP-over-TCP. The outer connection retransmits what the inner connection already retransmitted, and a single loss can stall every multiplexed session at once. On a clean path that is invisible. On a lossy one the cure is worse than the symptom.

The trade is acceptable when the alternative is no connectivity, and it should be documented as an exception with an owner rather than absorbed as normal.

Record the transport, the port, a sample query and the measured result, plus the date. Without that record the next engineer repeats the experiment, and the exception quietly becomes the architecture.

Keep the decision revisitable

A path diagnosis ages badly. The middlebox gets replaced, the blade configuration changes, the link is upgraded, and the reason for TCP on 443 disappears while the configuration stays. Put a review date on the exception and name the condition that would let you return to UDP.

Test both transports with a small query and with a large result set. Reordering shows up as size-dependent stalls, while a listener fault stops both sizes equally.

Ũhoro ũhĩtĩte