diff --git a/go.mod b/go.mod
index 3461a8258e1df720ed1cf51b240d170668b61744..d3db8b09fa08eed05d29b106a67d003d970af026 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.21
 
 require (
 	gfx.cafe/ghalliday1/scram v0.0.3
+	gfx.cafe/open/gotoprom v0.0.2
 	gfx.cafe/util/temple v0.0.0-20230312041217-0882540e78eb
 	github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
 	github.com/caddyserver/caddy/v2 v2.7.4
diff --git a/go.sum b/go.sum
index 1a819b87479f33674cf3aaca41e6710791f3abf5..8de86459ba3a481a2ff77c95c15c6b6a4af1c497 100644
--- a/go.sum
+++ b/go.sum
@@ -42,6 +42,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 gfx.cafe/ghalliday1/scram v0.0.3 h1:ScDO2WKij3E0a68adP9/6ZX4OXm+3rerjo51vRQ1agc=
 gfx.cafe/ghalliday1/scram v0.0.3/go.mod h1:qt6+WJoFcX2id67G5w+/dktBJ56Se0sZAa7WjqfNNu0=
+gfx.cafe/open/gotoprom v0.0.2 h1:LNypdpXFYSMoTewDSokZsOiZKcbewEVbOpkFUoQwnkA=
+gfx.cafe/open/gotoprom v0.0.2/go.mod h1:osabAhqSCG+hqtBeUTjFMbzqB2kZFK0SpRYRqmS5Of4=
 gfx.cafe/util/temple v0.0.0-20230312041217-0882540e78eb h1:E6gfSdAD5eBWHD5cLktd/umyivQlFTvEzoadoM33g3M=
 gfx.cafe/util/temple v0.0.0-20230312041217-0882540e78eb/go.mod h1:rDv4JeaN6NFCUXiNiewrmQnvm7npR7XbJ1jsturNDhc=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -363,7 +365,9 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
 github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
diff --git a/lib/gat/server.go b/lib/gat/server.go
index ad68e5f30dfc1d7b215149cdb8bf8681148d5f92..fc0db8718b49cbc7b2c733e1659a280d7e7fc22c 100644
--- a/lib/gat/server.go
+++ b/lib/gat/server.go
@@ -13,6 +13,7 @@ import (
 	"gfx.cafe/gfx/pggat/lib/bouncer/frontends/v0"
 	"gfx.cafe/gfx/pggat/lib/fed"
 	"gfx.cafe/gfx/pggat/lib/gat/metrics"
+	"gfx.cafe/gfx/pggat/lib/instrumentation/prom"
 	"gfx.cafe/gfx/pggat/lib/perror"
 )
 
@@ -144,6 +145,7 @@ func (T *Server) accept(listener *Listener, conn *fed.Conn) {
 	defer func() {
 		_ = conn.Close()
 	}()
+	labels := prom.ListenerLabels{ListenAddr: listener.networkAddress.String()}
 
 	var tlsConfig *tls.Config
 	if listener.ssl != nil {
@@ -167,7 +169,12 @@ func (T *Server) accept(listener *Listener, conn *fed.Conn) {
 	}
 
 	count := listener.open.Add(1)
-	defer listener.open.Add(-1)
+	prom.Listener.ClientConnections(labels).Inc()
+	prom.Listener.IncomingConnections(labels).Inc()
+	defer func() {
+		listener.open.Add(-1)
+		prom.Listener.ClientConnections(labels).Dec()
+	}()
 
 	if listener.MaxConnections != 0 && int(count) > listener.MaxConnections {
 		_ = conn.WritePacket(
@@ -179,7 +186,7 @@ func (T *Server) accept(listener *Listener, conn *fed.Conn) {
 		)
 		return
 	}
-
+	prom.Listener.AcceptedConnections(labels).Inc()
 	T.Serve(conn)
 }
 
diff --git a/lib/instrumentation/prom/metrics.go b/lib/instrumentation/prom/metrics.go
new file mode 100644
index 0000000000000000000000000000000000000000..30a55be7eecc6f3384cf6f4d0b9cac52ecd4fd4a
--- /dev/null
+++ b/lib/instrumentation/prom/metrics.go
@@ -0,0 +1,36 @@
+package prom
+
+import (
+	"gfx.cafe/open/gotoprom"
+	"github.com/prometheus/client_golang/prometheus"
+)
+
+type ListenerLabels struct {
+	ListenAddr string `label:"listen_addr"`
+}
+
+var Listener struct {
+	Incoming func(ListenerLabels) prometheus.Counter `name:"incoming"`
+	Accepted func(ListenerLabels) prometheus.Counter `name:"accepted"`
+	Client   func(ListenerLabels) prometheus.Gauge   `name:"client"`
+}
+
+type ServingLabels struct {
+}
+
+var Serving struct {
+	Route func() `name:""`
+}
+
+type InstanceLabels struct {
+}
+
+var Instance struct {
+	Route func() `name:""`
+}
+
+func init() {
+	gotoprom.MustInit(&Listener, "pggat_listener", prometheus.Labels{})
+	gotoprom.MustInit(&Instance, "pggat_instance", prometheus.Labels{})
+	gotoprom.MustInit(&Serving, "pggat_serving", prometheus.Labels{})
+}