diff --git a/.schema/api.swagger.json b/.schema/api.swagger.json
index 9ff1138fe1e0..a68853a8bb9a 100755
--- a/.schema/api.swagger.json
+++ b/.schema/api.swagger.json
@@ -320,6 +320,24 @@
         }
       }
     },
+    "/metrics/prometheus": {
+      "get": {
+        "description": "```\nmetadata:\nannotations:\nprometheus.io/port: \"4445\"\nprometheus.io/path: \"/metrics/prometheus\"\n```",
+        "produces": [
+          "plain/text"
+        ],
+        "tags": [
+          "admin"
+        ],
+        "summary": "Get snapshot metrics from the Hydra service. If you're using k8s, you can then add annotations to\nyour deployment like so:",
+        "operationId": "prometheus",
+        "responses": {
+          "200": {
+            "description": "Empty responses are sent when, for example, resources are deleted. The HTTP status code for empty responses is\ntypically 201."
+          }
+        }
+      }
+    },
     "/recovery/link": {
       "post": {
         "description": "This endpoint creates a recovery link which should be given to the user in order for them to recover\n(or activate) their account.",
diff --git a/cmd/daemon/serve.go b/cmd/daemon/serve.go
index ef9ec298e121..5d759c2f07ff 100644
--- a/cmd/daemon/serve.go
+++ b/cmd/daemon/serve.go
@@ -5,6 +5,8 @@ import (
 	"strings"
 	"sync"
 
+	"github.com/ory/kratos/metrics/prometheus"
+
 	"github.com/ory/analytics-go/v4"
 
 	"github.com/ory/x/flagx"
@@ -84,6 +86,7 @@ func serveAdmin(d driver.Driver, wg *sync.WaitGroup, cmd *cobra.Command, args []
 	r.RegisterAdminRoutes(router)
 	n.Use(NewNegroniLoggerMiddleware(l, "admin#"+c.SelfAdminURL().String()))
 	n.Use(sqa(cmd, d))
+	n.Use(d.Registry().PrometheusManager())
 
 	if tracer := d.Registry().Tracer(); tracer.IsLoaded() {
 		n.Use(tracer)
@@ -144,6 +147,7 @@ func sqa(cmd *cobra.Command, d driver.Driver) *metricsx.Service {
 				strings.ReplaceAll(verification.PublicVerificationInitPath, ":via", "email"),
 				verification.PublicVerificationRequestPath,
 				errorx.ErrorsPath,
+				prometheus.MetricsPrometheusPath,
 			},
 			BuildVersion: d.Registry().BuildVersion(),
 			BuildHash:    d.Registry().BuildHash(),
diff --git a/docs/docs/admin/managing-users-identities.mdx b/docs/docs/admin/managing-users-identities.mdx
index 19ad5204364d..736195627d42 100644
--- a/docs/docs/admin/managing-users-identities.mdx
+++ b/docs/docs/admin/managing-users-identities.mdx
@@ -74,6 +74,7 @@ To create the account recovery link, use:
   ]}>
 <TabItem value="curl">
 
+
 ```shell script
 $ curl --request POST -sL \
     --header "Content-Type: application/json" \
@@ -93,6 +94,7 @@ $ curl --request POST -sL \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -143,6 +145,7 @@ email, this feature is tracked as
 </TabItem>
 </Tabs>
 
+
 ### Import a User Identity
 
 This feature is not implemented yet.
diff --git a/docs/docs/reference/api.mdx b/docs/docs/reference/api.mdx
index 5e6c460d2ce2..90d24bab3990 100644
--- a/docs/docs/reference/api.mdx
+++ b/docs/docs/reference/api.mdx
@@ -78,6 +78,7 @@ status will never refer to the cluster state, only to a single instance.
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /health/alive \
   -H 'Accept: application/json'
@@ -86,6 +87,7 @@ curl -X GET /health/alive \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -114,6 +116,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -134,6 +137,7 @@ fetch('/health/alive', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/health/alive");
@@ -160,6 +164,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -178,6 +183,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -195,6 +201,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdisInstanceReady"></a>
 
 ### Check readiness status
@@ -244,6 +251,7 @@ status will never refer to the cluster state, only to a single instance.
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /health/ready \
   -H 'Accept: application/json'
@@ -252,6 +260,7 @@ curl -X GET /health/ready \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -280,6 +289,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -300,6 +310,7 @@ fetch('/health/ready', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/health/ready");
@@ -326,6 +337,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -344,6 +356,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -361,6 +374,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="ory-kratos-administrative-endpoints"></a>
 
 ## Administrative Endpoints
@@ -457,6 +471,7 @@ Status Code **200**
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /identities \
   -H 'Accept: application/json'
@@ -465,6 +480,7 @@ curl -X GET /identities \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -493,6 +509,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -513,6 +530,7 @@ fetch('/identities', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/identities");
@@ -539,6 +557,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -557,6 +576,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -574,6 +594,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdcreateIdentity"></a>
 
 ### Create an identity
@@ -679,6 +700,7 @@ Learn how identities work in
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X POST /identities \
   -H 'Content-Type: application/json' \  -H 'Accept: application/json'
@@ -687,6 +709,7 @@ curl -X POST /identities \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -716,6 +739,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch');
 const input = '{
@@ -759,6 +783,7 @@ fetch('/identities', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/identities");
@@ -785,6 +810,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -804,6 +830,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -822,6 +849,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdgetIdentity"></a>
 
 ### Get an identity
@@ -894,6 +922,7 @@ Learn how identities work in
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /identities/{id} \
   -H 'Accept: application/json'
@@ -902,6 +931,7 @@ curl -X GET /identities/{id} \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -930,6 +960,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -950,6 +981,7 @@ fetch('/identities/{id}', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/identities/{id}");
@@ -976,6 +1008,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -994,6 +1027,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -1011,6 +1045,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdupdateIdentity"></a>
 
 ### Update an identity
@@ -1121,6 +1156,7 @@ Learn how identities work in
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X PUT /identities/{id} \
   -H 'Content-Type: application/json' \  -H 'Accept: application/json'
@@ -1129,6 +1165,7 @@ curl -X PUT /identities/{id} \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -1158,6 +1195,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch');
 const input = '{
@@ -1201,6 +1239,7 @@ fetch('/identities/{id}', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/identities/{id}");
@@ -1227,6 +1266,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -1246,6 +1286,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -1264,6 +1305,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIddeleteIdentity"></a>
 
 ### Delete an identity
@@ -1327,6 +1369,7 @@ Learn how identities work in
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X DELETE /identities/{id} \
   -H 'Accept: application/json'
@@ -1335,6 +1378,7 @@ curl -X DELETE /identities/{id} \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -1363,6 +1407,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -1383,6 +1428,7 @@ fetch('/identities/{id}', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/identities/{id}");
@@ -1409,6 +1455,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -1427,6 +1474,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -1444,6 +1492,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="ory-kratos-common"></a>
 
 ## common
@@ -1500,6 +1549,7 @@ Get a traits schema definition
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /schemas/{id} \
   -H 'Accept: application/json'
@@ -1508,6 +1558,7 @@ curl -X GET /schemas/{id} \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -1536,6 +1587,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -1556,6 +1608,7 @@ fetch('/schemas/{id}', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/schemas/{id}");
@@ -1582,6 +1635,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -1600,6 +1654,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -1617,6 +1672,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdgetSelfServiceBrowserLoginRequest"></a>
 
 ### Get the request context of browser-based login user flows
@@ -1802,6 +1858,7 @@ your application (e.g. `/login?request=abcde`).
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/requests/login?request=string \
   -H 'Accept: application/json'
@@ -1810,6 +1867,7 @@ curl -X GET /self-service/browser/flows/requests/login?request=string \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -1838,6 +1896,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -1858,6 +1917,7 @@ fetch('/self-service/browser/flows/requests/login?request=string', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/requests/login?request=string");
@@ -1884,6 +1944,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -1903,6 +1964,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -1921,6 +1983,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdgetSelfServiceBrowserRecoveryRequest"></a>
 
 ### Get the request context of browser-based recovery flows
@@ -2068,6 +2131,7 @@ your application (e.g. `/recover?request=abcde`).
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/requests/recovery?request=string \
   -H 'Accept: application/json'
@@ -2076,6 +2140,7 @@ curl -X GET /self-service/browser/flows/requests/recovery?request=string \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -2104,6 +2169,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -2124,6 +2190,7 @@ fetch('/self-service/browser/flows/requests/recovery?request=string', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/requests/recovery?request=string");
@@ -2150,6 +2217,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -2169,6 +2237,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -2187,6 +2256,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdgetSelfServiceBrowserRegistrationRequest"></a>
 
 ### Get the request context of browser-based registration user flows
@@ -2371,6 +2441,7 @@ your application (e.g. `/registration?request=abcde`).
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/requests/registration?request=string \
   -H 'Accept: application/json'
@@ -2379,6 +2450,7 @@ curl -X GET /self-service/browser/flows/requests/registration?request=string \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -2407,6 +2479,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -2427,6 +2500,7 @@ fetch('/self-service/browser/flows/requests/registration?request=string', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/requests/registration?request=string");
@@ -2453,6 +2527,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -2472,6 +2547,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -2490,6 +2566,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdgetSelfServiceBrowserSettingsRequest"></a>
 
 ### Get the request context of browser-based settings flows
@@ -2660,6 +2737,7 @@ your application (e.g. `/settingss?request=abcde`).
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/requests/settings?request=string \
   -H 'Accept: application/json'
@@ -2668,6 +2746,7 @@ curl -X GET /self-service/browser/flows/requests/settings?request=string \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -2696,6 +2775,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -2716,6 +2796,7 @@ fetch('/self-service/browser/flows/requests/settings?request=string', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/requests/settings?request=string");
@@ -2742,6 +2823,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -2761,6 +2843,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -2779,6 +2862,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdgetSelfServiceVerificationRequest"></a>
 
 ### Get the request context of browser-based verification flows
@@ -2887,6 +2971,7 @@ your application (e.g. `/verify?request=abcde`).
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/requests/verification?request=string \
   -H 'Accept: application/json'
@@ -2895,6 +2980,7 @@ curl -X GET /self-service/browser/flows/requests/verification?request=string \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -2923,6 +3009,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -2943,6 +3030,7 @@ fetch('/self-service/browser/flows/requests/verification?request=string', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/requests/verification?request=string");
@@ -2969,6 +3057,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -2988,6 +3077,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -3006,6 +3096,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdgetSelfServiceError"></a>
 
 ### Get user-facing self-service errors
@@ -3067,6 +3158,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/errors \
   -H 'Accept: application/json'
@@ -3075,6 +3167,7 @@ curl -X GET /self-service/errors \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -3103,6 +3196,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -3123,6 +3217,7 @@ fetch('/self-service/errors', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/errors");
@@ -3149,6 +3244,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -3167,6 +3263,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -3184,6 +3281,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="ory-kratos-public-endpoints"></a>
 
 ## Public Endpoints
@@ -3263,6 +3361,7 @@ to sign in again. This will reset the authenticated_at time of the session.
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/login \
   -H 'Accept: application/json'
@@ -3271,6 +3370,7 @@ curl -X GET /self-service/browser/flows/login \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -3299,6 +3399,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -3319,6 +3420,7 @@ fetch('/self-service/browser/flows/login', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/login");
@@ -3345,6 +3447,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -3363,6 +3466,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -3380,6 +3484,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdinitializeSelfServiceBrowserLogoutFlow"></a>
 
 ### Initialize Browser-Based Logout User Flow
@@ -3440,6 +3545,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/logout \
   -H 'Accept: application/json'
@@ -3448,6 +3554,7 @@ curl -X GET /self-service/browser/flows/logout \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -3476,6 +3583,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -3496,6 +3604,7 @@ fetch('/self-service/browser/flows/logout', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/logout");
@@ -3522,6 +3631,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -3540,6 +3650,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -3557,6 +3668,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdinitializeSelfServiceRecoveryFlow"></a>
 
 ### Initialize browser-based account recovery flow
@@ -3617,6 +3729,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/recovery \
   -H 'Accept: application/json'
@@ -3625,6 +3738,7 @@ curl -X GET /self-service/browser/flows/recovery \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -3653,6 +3767,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -3673,6 +3788,7 @@ fetch('/self-service/browser/flows/recovery', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/recovery");
@@ -3699,6 +3815,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -3717,6 +3834,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -3734,6 +3852,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdcompleteSelfServiceBrowserRecoveryLinkStrategyFlow"></a>
 
 ### Complete the browser-based recovery flow using a recovery link
@@ -3789,6 +3908,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X POST /self-service/browser/flows/recovery/link \
   -H 'Accept: application/json'
@@ -3797,6 +3917,7 @@ curl -X POST /self-service/browser/flows/recovery/link \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -3825,6 +3946,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -3845,6 +3967,7 @@ fetch('/self-service/browser/flows/recovery/link', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/recovery/link");
@@ -3871,6 +3994,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -3889,6 +4013,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -3906,6 +4031,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdinitializeSelfServiceBrowserRegistrationFlow"></a>
 
 ### Initialize browser-based registration user flow
@@ -3967,6 +4093,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/registration \
   -H 'Accept: application/json'
@@ -3975,6 +4102,7 @@ curl -X GET /self-service/browser/flows/registration \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -4003,6 +4131,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -4023,6 +4152,7 @@ fetch('/self-service/browser/flows/registration', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/registration");
@@ -4049,6 +4179,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -4067,6 +4198,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -4084,6 +4216,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdcompleteSelfServiceBrowserSettingsOIDCSettingsFlow"></a>
 
 ### Complete the browser-based settings flow for the OpenID Connect strategy
@@ -4142,6 +4275,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X POST /self-service/browser/flows/registration/strategies/oidc/settings/connections \
   -H 'Accept: application/json'
@@ -4150,6 +4284,7 @@ curl -X POST /self-service/browser/flows/registration/strategies/oidc/settings/c
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -4178,6 +4313,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -4201,6 +4337,7 @@ fetch(
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/registration/strategies/oidc/settings/connections");
@@ -4227,6 +4364,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -4245,6 +4383,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -4262,6 +4401,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdinitializeSelfServiceSettingsFlow"></a>
 
 ### Initialize browser-based settings flow
@@ -4322,6 +4462,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/settings \
   -H 'Accept: application/json'
@@ -4330,6 +4471,7 @@ curl -X GET /self-service/browser/flows/settings \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -4358,6 +4500,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -4378,6 +4521,7 @@ fetch('/self-service/browser/flows/settings', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/settings");
@@ -4404,6 +4548,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -4422,6 +4567,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -4439,6 +4585,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdcompleteSelfServiceBrowserSettingsPasswordStrategyFlow"></a>
 
 ### Complete the browser-based settings flow for the password strategy
@@ -4497,6 +4644,7 @@ More information can be found at
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X POST /self-service/browser/flows/settings/strategies/password \
   -H 'Accept: application/json'
@@ -4505,6 +4653,7 @@ curl -X POST /self-service/browser/flows/settings/strategies/password \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -4533,6 +4682,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -4553,6 +4703,7 @@ fetch('/self-service/browser/flows/settings/strategies/password', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/settings/strategies/password");
@@ -4579,6 +4730,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -4597,6 +4749,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -4614,6 +4767,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdcompleteSelfServiceBrowserSettingsProfileStrategyFlow"></a>
 
 ### Complete the browser-based settings flow for profile data
@@ -4700,6 +4854,7 @@ traits: {}
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X POST /self-service/browser/flows/settings/strategies/profile?request=string \
   -H 'Content-Type: application/json' \  -H 'Accept: application/json'
@@ -4708,6 +4863,7 @@ curl -X POST /self-service/browser/flows/settings/strategies/profile?request=str
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -4737,6 +4893,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch');
 const input = '{
@@ -4761,6 +4918,7 @@ fetch('/self-service/browser/flows/settings/strategies/profile?request=string',
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/settings/strategies/profile?request=string");
@@ -4787,6 +4945,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -4807,6 +4966,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -4826,6 +4986,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdinitializeSelfServiceBrowserVerificationFlow"></a>
 
 ### Initialize browser-based verification flow
@@ -4900,6 +5061,7 @@ Currently only "email" is supported.
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/verification/init/{via} \
   -H 'Accept: application/json'
@@ -4908,6 +5070,7 @@ curl -X GET /self-service/browser/flows/verification/init/{via} \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -4936,6 +5099,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -4956,6 +5120,7 @@ fetch('/self-service/browser/flows/verification/init/{via}', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/verification/init/{via}");
@@ -4982,6 +5147,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -5000,6 +5166,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -5017,6 +5184,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdselfServiceBrowserVerify"></a>
 
 ### Complete the browser-based verification flows
@@ -5089,6 +5257,7 @@ Currently only "email" is supported.
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /self-service/browser/flows/verification/{via}/confirm/{code} \
   -H 'Accept: application/json'
@@ -5097,6 +5266,7 @@ curl -X GET /self-service/browser/flows/verification/{via}/confirm/{code} \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -5125,6 +5295,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -5145,6 +5316,7 @@ fetch('/self-service/browser/flows/verification/{via}/confirm/{code}', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/self-service/browser/flows/verification/{via}/confirm/{code}");
@@ -5171,6 +5343,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -5189,6 +5362,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -5206,6 +5380,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="opIdwhoami"></a>
 
 ### Check who the current HTTP session belongs to
@@ -5281,6 +5456,7 @@ This endpoint is useful for reverse proxies and API Gateways.
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /sessions/whoami \
   -H 'Accept: application/json'
@@ -5289,6 +5465,7 @@ curl -X GET /sessions/whoami \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -5317,6 +5494,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -5337,6 +5515,7 @@ fetch('/sessions/whoami', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/sessions/whoami");
@@ -5363,6 +5542,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -5381,6 +5561,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -5398,6 +5579,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 <a id="ory-kratos-version"></a>
 
 ## version
@@ -5450,6 +5632,7 @@ status will never refer to the cluster state, only to a single instance.
     {label: 'Java', value: 'java'}, {label: 'Python', value: 'python'}, {label: 'Ruby', value: 'ruby'}]}>
 <TabItem value="shell">
 
+
 ```shell
 curl -X GET /version \
   -H 'Accept: application/json'
@@ -5458,6 +5641,7 @@ curl -X GET /version \
 </TabItem>
 <TabItem value="go">
 
+
 ```go
 package main
 
@@ -5486,6 +5670,7 @@ func main() {
 </TabItem>
 <TabItem value="node">
 
+
 ```javascript
 const fetch = require('node-fetch')
 
@@ -5506,6 +5691,7 @@ fetch('/version', {
 </TabItem>
 <TabItem value="java">
 
+
 ```java
 // This sample needs improvement.
 URL obj = new URL("/version");
@@ -5532,6 +5718,7 @@ System.out.println(response.toString());
 </TabItem>
 <TabItem value="python">
 
+
 ```python
 import requests
 
@@ -5550,6 +5737,7 @@ print r.json()
 </TabItem>
 <TabItem value="ruby">
 
+
 ```ruby
 require 'rest-client'
 require 'json'
@@ -5567,6 +5755,7 @@ p JSON.parse(result)
 </TabItem>
 </Tabs>
 
+
 ## Schemas
 
 <a id="tocScredentialstype">CredentialsType</a>
diff --git a/docs/docs/self-service/flows/account-recovery/password-reset-recovery-link.mdx b/docs/docs/self-service/flows/account-recovery/password-reset-recovery-link.mdx
index c924e34d0d6c..942a1e7ff271 100644
--- a/docs/docs/self-service/flows/account-recovery/password-reset-recovery-link.mdx
+++ b/docs/docs/self-service/flows/account-recovery/password-reset-recovery-link.mdx
@@ -74,6 +74,7 @@ To initiate the request, point the browser to
   ]}>
 <TabItem value="html">
 
+
 ```html
 <a
   href="https://<kratos-public>/self-service/browser/flows/recovery"/>
@@ -84,6 +85,7 @@ To initiate the request, point the browser to
 </TabItem>
 <TabItem value="js">
 
+
 ```js
 // ...
 window.location.href =
@@ -93,6 +95,7 @@ window.location.href =
 </TabItem>
 </Tabs>
 
+
 Next, the user is redirected to the Recovery UI set by config variable
 `selfservice.flows.recovery.ui_url` with a `?request=...` query parameter:
 
@@ -105,6 +108,7 @@ Next, the user is redirected to the Recovery UI set by config variable
   ]}>
 <TabItem value="ui">
 
+
 The browser is redirected to, for example:
 `http://127.0.0.1:4455/recovery?request=e219b0ee-58a8-4dc4-aeb6-294e9787dfa9`
 
@@ -112,6 +116,7 @@ The browser is redirected to, for example:
 </TabItem>
 <TabItem value="json">
 
+
 ```json title="$ curl http://<kratos-admin>/self-service/browser/flows/requests/recovery?request=e219b0ee-58a8-4dc4-aeb6-294e9787dfa9"
 {
   "id": "e219b0ee-58a8-4dc4-aeb6-294e9787dfa9",
@@ -148,6 +153,7 @@ The browser is redirected to, for example:
 </TabItem>
 <TabItem value="form">
 
+
 ```html
 <div class="container">
     <h4>Recover your account</h4>
@@ -168,6 +174,7 @@ The browser is redirected to, for example:
 </TabItem>
 </Tabs>
 
+
 The `state` parameter follows the state machine
 
 <Mermaid
@@ -207,6 +214,7 @@ set:
 </TabItem>
 <TabItem value="json">
 
+
 ```json title="$ curl http://<kratos-admin>/self-service/browser/flows/requests/recovery?request=81d6f25e-6163-467a-afa3-1dae6c58b83d"
 {
   "id": "e6b25130-72d8-4776-8435-8d4790f7ec2f",
@@ -255,6 +263,7 @@ set:
 </TabItem>
 <TabItem value="form">
 
+
 ```html
 <div class="container">
   <h4>Recover your account</h4>
@@ -286,6 +295,7 @@ set:
 </TabItem>
 </Tabs>
 
+
 If the form data is valid, the `state` is set to `sent_email` and `messages`
 will also be set:
 
@@ -301,6 +311,7 @@ will also be set:
 </TabItem>
 <TabItem value="json">
 
+
 ```json title="$ curl http://<kratos-admin>/self-service/browser/flows/requests/recovery?request=7f3b531f-f78b-46ba-b770-873082dca1b7"
 {
   "id": "7f3b531f-f78b-46ba-b770-873082dca1b7",
@@ -346,6 +357,7 @@ will also be set:
 </TabItem>
 <TabItem value="form">
 
+
 ```html
 <div class="container">
   <h4>Recover your account</h4>
@@ -385,6 +397,7 @@ will also be set:
 </TabItem>
 </Tabs>
 
+
 Once the user clicks the link in the E-Mail, she/he will be redirected to the
 Settings endpoint (e.g.
 `http://127.0.0.1:4455/settings?request=752b6d46-af3d-40d2-9d06-b3e3c0279f02`)
@@ -402,6 +415,7 @@ directing the user to update the password / other credentials:
 </TabItem>
 <TabItem value="json">
 
+
 ```json5 title="$ curl http://<kratos-admin>/self-service/browser/flows/requests/settings?request=752b6d46-af3d-40d2-9d06-b3e3c0279f02"
 {
   id: '752b6d46-af3d-40d2-9d06-b3e3c0279f02',
@@ -425,6 +439,7 @@ directing the user to update the password / other credentials:
 </TabItem>
 </Tabs>
 
+
 If the user clicks an invalid (already used, expired) recovery link, a new
 recovery request will be initiated and she/he will be asked to retry the flow:
 
@@ -439,6 +454,7 @@ recovery request will be initiated and she/he will be asked to retry the flow:
 </TabItem>
 <TabItem value="json">
 
+
 ```json5 title="$ curl http://<kratos-admin>/self-service/browser/flows/requests/recovery?request=ce7a8d78-ffd7-438f-90d3-f6b923faa405"
 {
   id: 'ce7a8d78-ffd7-438f-90d3-f6b923faa405',
@@ -465,6 +481,7 @@ recovery request will be initiated and she/he will be asked to retry the flow:
 </TabItem>
 </Tabs>
 
+
 ## API Clients
 
 API-based login and registration using this strategy will be addressed in a
diff --git a/driver/registry.go b/driver/registry.go
index 85ba3ef637a4..4997d6452d48 100644
--- a/driver/registry.go
+++ b/driver/registry.go
@@ -1,6 +1,7 @@
 package driver
 
 import (
+	"github.com/ory/kratos/metrics/prometheus"
 	"github.com/ory/x/tracing"
 
 	"github.com/gorilla/sessions"
@@ -56,6 +57,7 @@ type Registry interface {
 	RegisterRoutes(public *x.RouterPublic, admin *x.RouterAdmin)
 	RegisterPublicRoutes(public *x.RouterPublic)
 	RegisterAdminRoutes(admin *x.RouterAdmin)
+	PrometheusManager() *prometheus.MetricsManager
 	Tracer() *tracing.Tracer
 
 	x.CSRFProvider
diff --git a/driver/registry_default.go b/driver/registry_default.go
index 3abd13c03b0f..839dc201ce25 100644
--- a/driver/registry_default.go
+++ b/driver/registry_default.go
@@ -6,6 +6,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/ory/kratos/metrics/prometheus"
+
 	"github.com/gobuffalo/pop/v5"
 
 	"github.com/ory/kratos/continuity"
@@ -65,8 +67,10 @@ type RegistryDefault struct {
 
 	nosurf         x.CSRFHandler
 	trc            *tracing.Tracer
+	pmm            *prometheus.MetricsManager
 	writer         herodot.Writer
 	healthxHandler *healthx.Handler
+	metricsHandler *prometheus.Handler
 
 	courier   *courier.Courier
 	persister persistence.Persister
@@ -180,6 +184,7 @@ func (m *RegistryDefault) RegisterAdminRoutes(router *x.RouterAdmin) {
 	}
 
 	m.HealthHandler().SetRoutes(router.Router, true)
+	m.MetricsHandler().SetRoutes(router.Router)
 }
 
 func (m *RegistryDefault) RegisterRoutes(public *x.RouterPublic, admin *x.RouterAdmin) {
@@ -231,6 +236,14 @@ func (m *RegistryDefault) HealthHandler() *healthx.Handler {
 	return m.healthxHandler
 }
 
+func (m *RegistryDefault) MetricsHandler() *prometheus.Handler {
+	if m.metricsHandler == nil {
+		m.metricsHandler = prometheus.NewHandler(m.Writer(), m.BuildVersion())
+	}
+
+	return m.metricsHandler
+}
+
 func (m *RegistryDefault) WithCSRFHandler(c x.CSRFHandler) {
 	m.nosurf = c
 }
@@ -539,3 +552,10 @@ func (m *RegistryDefault) IdentityManager() *identity.Manager {
 	}
 	return m.identityManager
 }
+
+func (m *RegistryDefault) PrometheusManager() *prometheus.MetricsManager {
+	if m.pmm == nil {
+		m.pmm = prometheus.NewMetricsManager(m.buildVersion, m.buildHash, m.buildDate)
+	}
+	return m.pmm
+}
diff --git a/go.mod b/go.mod
index 17e0b4d4f993..d0b87ebf4cc2 100644
--- a/go.mod
+++ b/go.mod
@@ -62,9 +62,11 @@ require (
 	github.com/ory/jsonschema/v3 v3.0.1
 	github.com/ory/mail/v3 v3.0.0
 	github.com/ory/viper v1.7.5
-	github.com/ory/x v0.0.135
+	github.com/ory/x v0.0.146
 	github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
 	github.com/pkg/errors v0.9.1
+	github.com/prometheus/client_golang v1.4.0
+	github.com/prometheus/common v0.9.1
 	github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e
 	github.com/sirupsen/logrus v1.6.0
 	github.com/spf13/cobra v1.0.0
diff --git a/go.sum b/go.sum
index 957dfc6c1cf2..add0cba69f96 100644
--- a/go.sum
+++ b/go.sum
@@ -82,6 +82,7 @@ github.com/benbjohnson/clock v1.0.0 h1:78Jk/r6m4wCi6sndMpty7A//t4dw/RW5fV4ZgDVfX
 github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
@@ -97,6 +98,7 @@ github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4r
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo=
 github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
@@ -956,6 +958,7 @@ github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc
 github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
 github.com/mattn/goveralls v0.0.5 h1:spfq8AyZ0cCk57Za6/juJ5btQxeE1FaEGMdfcI+XO48=
 github.com/mattn/goveralls v0.0.5/go.mod h1:Xg2LHi51faXLyKXwsndxiW6uxEEQT9+3sjGzzwU4xy0=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
 github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=
@@ -1084,6 +1087,8 @@ github.com/ory/x v0.0.128 h1:sArBGCH5s+0Zv0jD+t639Vy22URAD6XskBnD9r0+ESk=
 github.com/ory/x v0.0.128/go.mod h1:ykx1XOsl9taQtoW2yNvuxl/feEfTfrZTcbY1U7841tI=
 github.com/ory/x v0.0.135 h1:QjXkAI181EqrtMVQoYi0quFMOeu32B58HYbZPC1wFzg=
 github.com/ory/x v0.0.135/go.mod h1:BMzD4kJYW5/GHoBJndjO0lFy7igXz81UfpXzBQplscQ=
+github.com/ory/x v0.0.146 h1:QCf1w0EJuC+P+4cNO5C6kZViQKMAO517d1iL16nquxc=
+github.com/ory/x v0.0.146/go.mod h1:kYT14ajKGfDV8pRPRzQD3begYqRISZq1IQUgOVliQCE=
 github.com/parnurzeal/gorequest v0.2.15/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
@@ -1117,18 +1122,22 @@ github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prY
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI=
 github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
 github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
diff --git a/internal/httpclient/client/admin/admin_client.go b/internal/httpclient/client/admin/admin_client.go
index 558b19308123..a47919a2d15c 100644
--- a/internal/httpclient/client/admin/admin_client.go
+++ b/internal/httpclient/client/admin/admin_client.go
@@ -37,6 +37,8 @@ type ClientService interface {
 
 	ListIdentities(params *ListIdentitiesParams) (*ListIdentitiesOK, error)
 
+	Prometheus(params *PrometheusParams) (*PrometheusOK, error)
+
 	UpdateIdentity(params *UpdateIdentityParams) (*UpdateIdentityOK, error)
 
 	SetTransport(transport runtime.ClientTransport)
@@ -232,6 +234,47 @@ func (a *Client) ListIdentities(params *ListIdentitiesParams) (*ListIdentitiesOK
 	panic(msg)
 }
 
+/*
+  Prometheus gets snapshot metrics from the hydra service if you re using k8s you can then add annotations to your deployment like so
+
+  ```
+metadata:
+annotations:
+prometheus.io/port: "4445"
+prometheus.io/path: "/metrics/prometheus"
+```
+*/
+func (a *Client) Prometheus(params *PrometheusParams) (*PrometheusOK, error) {
+	// TODO: Validate the params before sending
+	if params == nil {
+		params = NewPrometheusParams()
+	}
+
+	result, err := a.transport.Submit(&runtime.ClientOperation{
+		ID:                 "prometheus",
+		Method:             "GET",
+		PathPattern:        "/metrics/prometheus",
+		ProducesMediaTypes: []string{"plain/text"},
+		ConsumesMediaTypes: []string{"application/json", "application/x-www-form-urlencoded"},
+		Schemes:            []string{"http", "https"},
+		Params:             params,
+		Reader:             &PrometheusReader{formats: a.formats},
+		Context:            params.Context,
+		Client:             params.HTTPClient,
+	})
+	if err != nil {
+		return nil, err
+	}
+	success, ok := result.(*PrometheusOK)
+	if ok {
+		return success, nil
+	}
+	// unexpected success response
+	// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
+	msg := fmt.Sprintf("unexpected success response for prometheus: API contract not enforced by server. Client expected to get an error, but got: %T", result)
+	panic(msg)
+}
+
 /*
   UpdateIdentity updates an identity
 
diff --git a/internal/httpclient/client/admin/prometheus_parameters.go b/internal/httpclient/client/admin/prometheus_parameters.go
new file mode 100644
index 000000000000..03b76358d868
--- /dev/null
+++ b/internal/httpclient/client/admin/prometheus_parameters.go
@@ -0,0 +1,112 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package admin
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+	"context"
+	"net/http"
+	"time"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	cr "github.com/go-openapi/runtime/client"
+	"github.com/go-openapi/strfmt"
+)
+
+// NewPrometheusParams creates a new PrometheusParams object
+// with the default values initialized.
+func NewPrometheusParams() *PrometheusParams {
+
+	return &PrometheusParams{
+
+		timeout: cr.DefaultTimeout,
+	}
+}
+
+// NewPrometheusParamsWithTimeout creates a new PrometheusParams object
+// with the default values initialized, and the ability to set a timeout on a request
+func NewPrometheusParamsWithTimeout(timeout time.Duration) *PrometheusParams {
+
+	return &PrometheusParams{
+
+		timeout: timeout,
+	}
+}
+
+// NewPrometheusParamsWithContext creates a new PrometheusParams object
+// with the default values initialized, and the ability to set a context for a request
+func NewPrometheusParamsWithContext(ctx context.Context) *PrometheusParams {
+
+	return &PrometheusParams{
+
+		Context: ctx,
+	}
+}
+
+// NewPrometheusParamsWithHTTPClient creates a new PrometheusParams object
+// with the default values initialized, and the ability to set a custom HTTPClient for a request
+func NewPrometheusParamsWithHTTPClient(client *http.Client) *PrometheusParams {
+
+	return &PrometheusParams{
+		HTTPClient: client,
+	}
+}
+
+/*PrometheusParams contains all the parameters to send to the API endpoint
+for the prometheus operation typically these are written to a http.Request
+*/
+type PrometheusParams struct {
+	timeout    time.Duration
+	Context    context.Context
+	HTTPClient *http.Client
+}
+
+// WithTimeout adds the timeout to the prometheus params
+func (o *PrometheusParams) WithTimeout(timeout time.Duration) *PrometheusParams {
+	o.SetTimeout(timeout)
+	return o
+}
+
+// SetTimeout adds the timeout to the prometheus params
+func (o *PrometheusParams) SetTimeout(timeout time.Duration) {
+	o.timeout = timeout
+}
+
+// WithContext adds the context to the prometheus params
+func (o *PrometheusParams) WithContext(ctx context.Context) *PrometheusParams {
+	o.SetContext(ctx)
+	return o
+}
+
+// SetContext adds the context to the prometheus params
+func (o *PrometheusParams) SetContext(ctx context.Context) {
+	o.Context = ctx
+}
+
+// WithHTTPClient adds the HTTPClient to the prometheus params
+func (o *PrometheusParams) WithHTTPClient(client *http.Client) *PrometheusParams {
+	o.SetHTTPClient(client)
+	return o
+}
+
+// SetHTTPClient adds the HTTPClient to the prometheus params
+func (o *PrometheusParams) SetHTTPClient(client *http.Client) {
+	o.HTTPClient = client
+}
+
+// WriteToRequest writes these params to a swagger request
+func (o *PrometheusParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
+
+	if err := r.SetTimeout(o.timeout); err != nil {
+		return err
+	}
+	var res []error
+
+	if len(res) > 0 {
+		return errors.CompositeValidationError(res...)
+	}
+	return nil
+}
diff --git a/internal/httpclient/client/admin/prometheus_responses.go b/internal/httpclient/client/admin/prometheus_responses.go
new file mode 100644
index 000000000000..aee4fb32838a
--- /dev/null
+++ b/internal/httpclient/client/admin/prometheus_responses.go
@@ -0,0 +1,55 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package admin
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+	"fmt"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+)
+
+// PrometheusReader is a Reader for the Prometheus structure.
+type PrometheusReader struct {
+	formats strfmt.Registry
+}
+
+// ReadResponse reads a server response into the received o.
+func (o *PrometheusReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+	switch response.Code() {
+	case 200:
+		result := NewPrometheusOK()
+		if err := result.readResponse(response, consumer, o.formats); err != nil {
+			return nil, err
+		}
+		return result, nil
+
+	default:
+		return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
+	}
+}
+
+// NewPrometheusOK creates a PrometheusOK with default headers values
+func NewPrometheusOK() *PrometheusOK {
+	return &PrometheusOK{}
+}
+
+/*PrometheusOK handles this case with default header values.
+
+Empty responses are sent when, for example, resources are deleted. The HTTP status code for empty responses is
+typically 201.
+*/
+type PrometheusOK struct {
+}
+
+func (o *PrometheusOK) Error() string {
+	return fmt.Sprintf("[GET /metrics/prometheus][%d] prometheusOK ", 200)
+}
+
+func (o *PrometheusOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
+
+	return nil
+}
diff --git a/metrics/prometheus/handler.go b/metrics/prometheus/handler.go
new file mode 100644
index 000000000000..981d59e2126a
--- /dev/null
+++ b/metrics/prometheus/handler.go
@@ -0,0 +1,59 @@
+package prometheus
+
+import (
+	"net/http"
+
+	"github.com/julienschmidt/httprouter"
+	"github.com/prometheus/client_golang/prometheus/promhttp"
+
+	"github.com/ory/herodot"
+)
+
+const (
+	MetricsPrometheusPath = "/metrics/prometheus"
+)
+
+// Handler handles HTTP requests to health and version endpoints.
+type Handler struct {
+	H             herodot.Writer
+	VersionString string
+}
+
+// NewHandler instantiates a handler.
+func NewHandler(
+	h herodot.Writer,
+	version string,
+) *Handler {
+	return &Handler{
+		H:             h,
+		VersionString: version,
+	}
+}
+
+// SetRoutes registers this handler's routes.
+func (h *Handler) SetRoutes(r *httprouter.Router) {
+	r.GET(MetricsPrometheusPath, h.Metrics)
+}
+
+// Metrics outputs prometheus metrics
+//
+// swagger:route GET /metrics/prometheus admin prometheus
+//
+// Get snapshot metrics from the Hydra service. If you're using k8s, you can then add annotations to
+// your deployment like so:
+//
+// ```
+// metadata:
+//  annotations:
+//    prometheus.io/port: "4434"
+//      prometheus.io/path: "/metrics/prometheus"
+// ```
+//
+//     Produces:
+//     - plain/text
+//
+//     Responses:
+//       200: emptyResponse
+func (h *Handler) Metrics(rw http.ResponseWriter, r *http.Request, _ httprouter.Params) {
+	promhttp.Handler().ServeHTTP(rw, r)
+}
diff --git a/metrics/prometheus/handler_test.go b/metrics/prometheus/handler_test.go
new file mode 100644
index 000000000000..f1209f30b075
--- /dev/null
+++ b/metrics/prometheus/handler_test.go
@@ -0,0 +1,32 @@
+package prometheus_test
+
+import (
+	"github.com/ory/kratos/metrics/prometheus"
+	"github.com/prometheus/common/expfmt"
+	"github.com/stretchr/testify/require"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/ory/kratos/internal"
+	"github.com/ory/kratos/x"
+)
+
+func TestHandler(t *testing.T) {
+	_, reg := internal.NewFastRegistryWithMocks(t)
+	router := x.NewRouterAdmin()
+	reg.MetricsHandler().SetRoutes(router.Router)
+	ts := httptest.NewServer(router)
+	defer ts.Close()
+
+	c := http.DefaultClient
+
+	response, err := c.Get(ts.URL + prometheus.MetricsPrometheusPath)
+	require.NoError(t, err)
+	require.EqualValues(t, http.StatusOK, response.StatusCode)
+
+	textParser := expfmt.TextParser{}
+	text, err := textParser.TextToMetricFamilies(response.Body)
+	require.NoError(t, err)
+	require.EqualValues(t, "go_info", *text["go_info"].Name)
+}
diff --git a/metrics/prometheus/metrics.go b/metrics/prometheus/metrics.go
new file mode 100644
index 000000000000..5666f078d7ad
--- /dev/null
+++ b/metrics/prometheus/metrics.go
@@ -0,0 +1,32 @@
+package prometheus
+
+import "github.com/prometheus/client_golang/prometheus"
+
+// Metrics prototypes
+type Metrics struct {
+	ResponseTime *prometheus.HistogramVec
+}
+
+// Method for creation new custom Prometheus  metrics
+func NewMetrics(version, hash, date string) *Metrics {
+	pm := &Metrics{
+		ResponseTime: prometheus.NewHistogramVec(
+			prometheus.HistogramOpts{
+				Name: "kratos_response_time_seconds",
+				Help: "Description",
+				ConstLabels: map[string]string{
+					"version":   version,
+					"hash":      hash,
+					"buildTime": date,
+				},
+			},
+			[]string{"endpoint"},
+		),
+	}
+	err := prometheus.Register(pm.ResponseTime)
+
+	if err != nil {
+		panic(err)
+	}
+	return pm
+}
diff --git a/metrics/prometheus/middleware.go b/metrics/prometheus/middleware.go
new file mode 100644
index 000000000000..5c7f5cbae400
--- /dev/null
+++ b/metrics/prometheus/middleware.go
@@ -0,0 +1,24 @@
+package prometheus
+
+import (
+	"net/http"
+	"time"
+)
+
+type MetricsManager struct {
+	prometheusMetrics *Metrics
+}
+
+func NewMetricsManager(version, hash, buildTime string) *MetricsManager {
+	return &MetricsManager{
+		prometheusMetrics: NewMetrics(version, hash, buildTime),
+	}
+}
+
+// Main middleware method to collect metrics for Prometheus.
+func (pmm *MetricsManager) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
+	start := time.Now()
+	next(rw, r)
+
+	pmm.prometheusMetrics.ResponseTime.WithLabelValues(r.URL.Path).Observe(time.Since(start).Seconds())
+}
diff --git a/selfservice/form/html_form.go b/selfservice/form/html_form.go
index 106809bbf9ef..6b6794c2e81b 100644
--- a/selfservice/form/html_form.go
+++ b/selfservice/form/html_form.go
@@ -70,7 +70,7 @@ func NewHTMLFormFromRequestBody(r *http.Request, action string, compiler decoder
 	c := NewHTMLForm(action)
 	raw := json.RawMessage(`{}`)
 	if err := decoder.Decode(r, &raw, compiler,
-		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnore),
+		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnoreConversionErrors),
 	); err != nil {
 		if err := c.ParseError(err); err != nil {
 			return nil, err
diff --git a/selfservice/strategy/oidc/form.go b/selfservice/strategy/oidc/form.go
index edd23931a227..24df8c398e0c 100644
--- a/selfservice/strategy/oidc/form.go
+++ b/selfservice/strategy/oidc/form.go
@@ -56,7 +56,7 @@ func merge(userFormValues string, openIDProviderValues json.RawMessage, option d
 		req, &df,
 		decoderx.HTTPFormDecoder(),
 		option,
-		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnore),
+		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnoreConversionErrors),
 		decoderx.HTTPDecoderSetValidatePayloads(false),
 	); err != nil {
 		return nil, err
diff --git a/selfservice/strategy/password/registration.go b/selfservice/strategy/password/registration.go
index dd0a18c9fe46..72f02a5a4cd4 100644
--- a/selfservice/strategy/password/registration.go
+++ b/selfservice/strategy/password/registration.go
@@ -122,7 +122,7 @@ func (s *Strategy) handleRegistration(w http.ResponseWriter, r *http.Request, _
 	if err := decoderx.NewHTTP().Decode(r, &p,
 		decoderx.HTTPFormDecoder(),
 		option,
-		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnore),
+		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnoreConversionErrors),
 		decoderx.HTTPDecoderSetValidatePayloads(false),
 	); err != nil {
 		s.handleRegistrationError(w, r, ar, &p, err)
diff --git a/selfservice/strategy/profile/strategy.go b/selfservice/strategy/profile/strategy.go
index 123190d926b1..f8ab105652c0 100644
--- a/selfservice/strategy/profile/strategy.go
+++ b/selfservice/strategy/profile/strategy.go
@@ -169,7 +169,7 @@ func (s *Strategy) handleSubmit(w http.ResponseWriter, r *http.Request, ps httpr
 		decoderx.HTTPFormDecoder(),
 		option,
 		decoderx.HTTPDecoderSetValidatePayloads(false),
-		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnore),
+		decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnoreConversionErrors),
 	); err != nil {
 		s.handleSettingsError(w, r, ctxUpdate, nil, &p, err)
 		return
diff --git a/x/config.go b/x/config.go
index 3c6088f5dfa4..3703619a0e46 100644
--- a/x/config.go
+++ b/x/config.go
@@ -19,5 +19,5 @@ func WatchAndValidateViper(log *logrusx.Logger) {
 	if err != nil {
 		log.WithError(err).Fatal("Unable to read configuration JSON Schema.")
 	}
-	viperx.WatchAndValidateViper(log, schema, "ORY Kratos", []string{"serve", "profiling", "log"})
+	viperx.WatchAndValidateViper(log, schema, "ORY Kratos", []string{"serve", "profiling", "log"}, "")
 }