diff --git a/lib/modules/Sql.pmod/pgsql.h b/lib/modules/Sql.pmod/pgsql.h
index 32e2224653401e2de88f89a78b30cc6752484a28..e65ff70fde91de5fe3bab75906bfb6f6f49cd628 100644
--- a/lib/modules/Sql.pmod/pgsql.h
+++ b/lib/modules/Sql.pmod/pgsql.h
@@ -24,6 +24,7 @@
 #define QUERYTIMEOUT	     4095   // Queries running longer than this number
 				    // of seconds are canceled automatically
 #define PORTALBUFFERSIZE     (32*1024) // Approximate buffer per portal
+#define BACKOFFDELAY	     1
 
 #define PGSQL_DEFAULT_PORT   5432
 #define PGSQL_DEFAULT_HOST   "localhost"
diff --git a/lib/modules/Sql.pmod/pgsql.pike b/lib/modules/Sql.pmod/pgsql.pike
index 704757b78cf9e2107da4568969579aa7424d20d7..5cc10ab53be4e35db99523f7c9d30124e908f96f 100644
--- a/lib/modules/Sql.pmod/pgsql.pike
+++ b/lib/modules/Sql.pmod/pgsql.pike
@@ -78,6 +78,8 @@ private int prepstmtused;	// Number of times we used prepared statements
 private int cachedepth = STATEMENTCACHEDEPTH;
 private int portalbuffersize = PORTALBUFFERSIZE;
 private int timeout = QUERYTIMEOUT;
+private array connparmcache;
+private int reconnected;
 
 protected string _sprintf(int type) {
   string res;
@@ -114,6 +116,12 @@ protected string _sprintf(int type) {
 //! @param options
 //! Currently supports at least the following:
 //! @mapping
+//!   @member int "reconnect"
+//!    Set it to zero to disable automatic reconnects upon losing
+//!     the connection to the database.  Not setting it, or setting
+//!     it to one, will cause one timed reconnect to take place.
+//!     Setting it to -1 will cause the system to try and reconnect
+//!     indefinitely.
 //!   @member int "use_ssl"
 //!	If the database supports and allows SSL connections, the session
 //!	will be SSL encrypted, if not, the connection will fallback
@@ -176,9 +184,10 @@ protected void create(void|string host, void|string database,
     String.secure(pass);
     pass = "CENSORED";
   }
-  proxy = .pgsql_util.proxy(host, database,
+  connparmcache = ({ host, database,
    user && user != "" ? Standards.IDNA.to_ascii(user, 1) : user,
-   spass, options || ([]));
+   spass, options || ([])});
+  proxy = .pgsql_util.proxy(@connparmcache);
 }
 
 //! @returns
@@ -245,7 +254,8 @@ protected void create(void|string host, void|string database,
 //!   @[is_open()]
 /*semi*/final int ping() {
   waitauthready();
-  return is_open() && !catch(proxy.c->start()->sendcmd(FLUSHSEND)) ? 0 : -1;
+  return is_open()
+   && !catch(proxy.c->start()->sendcmd(FLUSHSEND)) ? !!reconnected : -1;
 }
 
 //! Cancels all currently running queries in this session.
@@ -881,6 +891,15 @@ private inline void throwdelayederror(object parent) {
 private void startquery(int forcetext, .pgsql_util.sql_result portal, string q,
  mapping(string:mixed) tp, string preparedname) {
   .pgsql_util.conxion c = proxy.c;
+  if (!c && (proxy.options["reconnect"]
+             || zero_type(proxy.options["reconnect"]))) {
+    sleep(BACKOFFDELAY);	// Force a backoff delay
+    if (!proxy.c) {
+      reconnected++;
+      proxy = .pgsql_util.proxy(@connparmcache);
+    }
+    c = proxy.c;
+  }
   if (forcetext) {	// FIXME What happens if portals are still open?
     portal._unnamedportalkey = proxy.unnamedportalmux->lock(1);
     portal._portalname = "";
diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod
index f5cd54fac35092b8482f60bc374377d986d90f0a..be350e33b68ff4d48fea7625130a025f4f5c54be 100644
--- a/lib/modules/Sql.pmod/pgsql_util.pmod
+++ b/lib/modules/Sql.pmod/pgsql_util.pmod
@@ -1496,7 +1496,7 @@ class proxy {
   final int(0..1) invalidatecache;
   private Thread.Queue qportals;
   final mixed delayederror;
-  private function (:void) readyforquery_cb;
+  final function (:void) readyforquery_cb;
 
   final string host;
   final int(0..65535) port;
@@ -1698,11 +1698,12 @@ class proxy {
     };
 #endif
     int msgisfatal(mapping(string:string) msgresponse) {
-      if (!terminating)		// Run the callback once per lost connection
-        runcallback(backendpid,"_lost","");
-      return (has_prefix(msgresponse.C, "53")
-           || has_prefix(msgresponse.C, "3D")
-           || has_prefix(msgresponse.C, "57P")) && MAGICTERMINATE;
+      int isfatal = (has_prefix(msgresponse.C, "53")
+                  || has_prefix(msgresponse.C, "3D")
+                  || has_prefix(msgresponse.C, "57P")) && MAGICTERMINATE;
+      if (isfatal && !terminating) // Run the callback once per lost connection
+        runcallback(backendpid, "_lost", "");
+      return isfatal;
     };
     for (;;) {
       err = catch {
@@ -2394,13 +2395,15 @@ class proxy {
     }
   }
 
-  private void sendsync() {
+  final void sendsync() {
     readyforquerycount++;
     c->start()->sendcmd(SYNCSEND);
   }
 
   private void runcallback(int pid, string condition, string extrainfo) {
     array cb;
+    if (condition == "_lost")
+      destruct(c);
     if ((cb = notifylist[condition] || notifylist[""])
        && (pid != backendpid || sizeof(cb) > 1 && cb[1]))
       callout(cb[0], 0, pid, condition, extrainfo, @cb[2..]);