diff --git a/lib/gat/gatcaddyfile/pool.go b/lib/gat/gatcaddyfile/pool.go
index 856859eddce12b9ce88499110cb5aae90ddd8f13..32572f84d963270e6c7797f4633642eaf010bd70 100644
--- a/lib/gat/gatcaddyfile/pool.go
+++ b/lib/gat/gatcaddyfile/pool.go
@@ -1,7 +1,159 @@
 package gatcaddyfile
 
-import "gfx.cafe/gfx/pggat/lib/gat/handlers/pool/pools/basic"
+import (
+	"time"
+
+	"github.com/caddyserver/caddy/v2"
+	"github.com/caddyserver/caddy/v2/caddyconfig"
+	"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
+
+	"gfx.cafe/gfx/pggat/lib/gat/handlers/pool/pools/basic"
+	"gfx.cafe/gfx/pggat/lib/util/strutil"
+)
+
+func defaultPoolConfig(base basic.Config) basic.Config {
+	base.ServerIdleTimeout = caddy.Duration(5 * time.Minute)
+	base.ServerReconnectInitialTime = caddy.Duration(5 * time.Second)
+	base.ServerReconnectMaxTime = caddy.Duration(1 * time.Minute)
+	base.TrackedParameters = []strutil.CIString{
+		strutil.MakeCIString("client_encoding"),
+		strutil.MakeCIString("datestyle"),
+		strutil.MakeCIString("timezone"),
+		strutil.MakeCIString("standard_conforming_strings"),
+		strutil.MakeCIString("application_name"),
+	}
+	return base
+}
 
 var defaultPool = &basic.Factory{
-	Config: basic.Transaction,
+	Config: defaultPoolConfig(basic.Transaction),
+}
+
+func init() {
+	RegisterDirective(Pool, "basic", func(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
+		module := *defaultPool
+
+		if d.NextArg() {
+			switch d.Val() {
+			case "transaction":
+				module.Config = defaultPoolConfig(basic.Transaction)
+			case "session":
+				module.Config = defaultPoolConfig(basic.Session)
+			default:
+				return nil, d.ArgErr()
+			}
+		} else {
+			if !d.NextBlock(d.Nesting()) {
+				return nil, d.ArgErr()
+			}
+
+			for {
+				if d.Val() == "}" {
+					break
+				}
+
+				directive := d.Val()
+				switch directive {
+				case "pooler":
+					if !d.NextArg() {
+						return nil, d.ArgErr()
+					}
+
+					var err error
+					module.RawPoolerFactory, err = UnmarshalDirectiveJSONModuleObject(
+						d,
+						Pooler,
+						"pooler",
+						warnings,
+					)
+					if err != nil {
+						return nil, err
+					}
+				case "release_after_transaction":
+					if d.NextArg() {
+						switch d.Val() {
+						case "true":
+							module.ReleaseAfterTransaction = true
+						case "false":
+							module.ReleaseAfterTransaction = false
+						default:
+							return nil, d.ArgErr()
+						}
+					} else {
+						module.ReleaseAfterTransaction = true
+					}
+				case "parameter_status_sync":
+					if !d.NextArg() {
+						return nil, d.ArgErr()
+					}
+
+					module.ParameterStatusSync = basic.ParameterStatusSync(d.Val())
+				case "extended_query_sync":
+					if d.NextArg() {
+						switch d.Val() {
+						case "true":
+							module.ExtendedQuerySync = true
+						case "false":
+							module.ExtendedQuerySync = false
+						default:
+							return nil, d.ArgErr()
+						}
+					} else {
+						module.ExtendedQuerySync = true
+					}
+				case "reset_query":
+					if !d.NextArg() {
+						return nil, d.ArgErr()
+					}
+
+					module.ServerResetQuery = d.Val()
+				case "idle_timeout":
+					if !d.NextArg() {
+						return nil, d.ArgErr()
+					}
+
+					val, err := time.ParseDuration(d.Val())
+					if err != nil {
+						return nil, d.WrapErr(err)
+					}
+
+					module.ServerIdleTimeout = caddy.Duration(val)
+				case "reconnect":
+					if !d.NextArg() {
+						return nil, d.ArgErr()
+					}
+
+					initialTime, err := time.ParseDuration(d.Val())
+					if err != nil {
+						return nil, d.WrapErr(err)
+					}
+
+					maxTime := initialTime
+					if d.NextArg() {
+						maxTime, err = time.ParseDuration(d.Val())
+						if err != nil {
+							return nil, d.WrapErr(err)
+						}
+					}
+
+					module.ServerReconnectInitialTime = caddy.Duration(initialTime)
+					module.ServerReconnectMaxTime = caddy.Duration(maxTime)
+				case "track":
+					if !d.NextArg() {
+						return nil, d.ArgErr()
+					}
+
+					module.TrackedParameters = append(module.TrackedParameters, strutil.MakeCIString(d.Val()))
+				default:
+					return nil, d.ArgErr()
+				}
+
+				if !d.NextLine() {
+					return nil, d.EOFErr()
+				}
+			}
+		}
+
+		return &module, nil
+	})
 }
diff --git a/lib/gat/gatcaddyfile/pooler.go b/lib/gat/gatcaddyfile/pooler.go
new file mode 100644
index 0000000000000000000000000000000000000000..a129c5fb1be8ce1ccdb0d880135146d8b846f34a
--- /dev/null
+++ b/lib/gat/gatcaddyfile/pooler.go
@@ -0,0 +1,19 @@
+package gatcaddyfile
+
+import (
+	"github.com/caddyserver/caddy/v2"
+	"github.com/caddyserver/caddy/v2/caddyconfig"
+	"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
+
+	"gfx.cafe/gfx/pggat/lib/gat/handlers/pool/poolers/lifo"
+	"gfx.cafe/gfx/pggat/lib/gat/handlers/pool/poolers/rob"
+)
+
+func init() {
+	RegisterDirective(Pooler, "lifo", func(d *caddyfile.Dispenser, _ *[]caddyconfig.Warning) (caddy.Module, error) {
+		return &lifo.Factory{}, nil
+	})
+	RegisterDirective(Pooler, "rob", func(d *caddyfile.Dispenser, _ *[]caddyconfig.Warning) (caddy.Module, error) {
+		return &rob.Factory{}, nil
+	})
+}
diff --git a/lib/gat/handlers/allowed_startup_parameters/module.go b/lib/gat/handlers/allowed_startup_parameters/module.go
index f23ab20e767f24769ecd06b515263126b18c929b..d797381bbf9acb82b5caf631476e577531751c27 100644
--- a/lib/gat/handlers/allowed_startup_parameters/module.go
+++ b/lib/gat/handlers/allowed_startup_parameters/module.go
@@ -17,7 +17,7 @@ func init() {
 }
 
 type Module struct {
-	Parameters []strutil.CIString `json:"parameters"`
+	Parameters []strutil.CIString `json:"parameters,omitempty"`
 }
 
 func (T *Module) CaddyModule() caddy.ModuleInfo {
diff --git a/lib/gat/handlers/pool/dialer.go b/lib/gat/handlers/pool/dialer.go
index 140c1474b39a79675949bb8e0522cfe77181f495..552bca1187158b386a657cb9c4d5061ebfa10423 100644
--- a/lib/gat/handlers/pool/dialer.go
+++ b/lib/gat/handlers/pool/dialer.go
@@ -26,7 +26,7 @@ type Dialer struct {
 
 	RawSSL        json.RawMessage   `json:"ssl,omitempty" caddy:"namespace=pggat.ssl.clients inline_key=provider"`
 	RawPassword   string            `json:"password"`
-	RawParameters map[string]string `json:"parameters"`
+	RawParameters map[string]string `json:"parameters,omitempty"`
 
 	SSLConfig   *tls.Config                 `json:"-"`
 	Credentials auth.Credentials            `json:"-"`