Background: vTM handles HTTP GET requests from multiple clients efficiently, by creating a low number of tcp connections to backend servers, and sending multiple requests from different clients on each connection. Once a request completes, the tcp connection is kept open (called a keepalive connection) to be re-used by subsequent requests. The HTTP protocol allows either the client (vTM here) or server to close an idle keepalive connection at any time.
A problem can happen where vTM sends a GET request, but at the same time the server closes (sends a FIN). If this happens, vTM detects the problem (only if passive monitoring is enabled, which it is by default), and retries the GET on a new connection, and it doesn't matter if the GET got processed on the first connection or not (i.e. GET requests are idempotent).
POST requests may not be idempotent (vTM assumes they are not), as they can be used for e.g. changing an account balance. If vTM sent a POST on an idle keepalive, and the server closed the connection, vTM has no way of knowing if the POST request got processed by the server (or if it was successfully processed, then some other issue caused the server to close the connection improperly instead of sending a response), so it's not retried and instead an error message is returned to the client. To avoid the risk of this happening, POST requests are by default always sent on their own new connection (which can be re-used by subsequent GETs).
For most web applications, this works well. However some applications are 100% POST requests, and the nature of the traffic means it doesn't matter if some of them get processed twice. For applications such as these, it's safe for vTM to send the POSTs on idle keepalives, which is done by enabling keepalive!non_idempotent, in Pool > Protocol Settings. Each application needs to be evaluated individually to see if this is safe.
For applications where there are 100% POST requests, and it's not safe for them to be sent on idle keepalives, then a problem can happen where there are 1000's of unused connections, and in this case it would be better to just disable keepalives, in Pool > Protocol Settings.