Repository: c410-f3r/wtx (language: rust)

Issue:
Examples in wtx-instances are not working
http2-client and web-socket-client are not working.

```
$ cargo run --features=wtx/http2 --example http2-client
Error: Http2ErrorGoAway(FrameSizeError, Some(LargeArbitraryFrameLen))
```

```
$ cargo run --features=wtx/web-socket-handshake --example web-socket-client
error[E0425]: cannot find function `stdin` in module `tokio::io`
   --> wtx-instances/web-socket-examples/web-socket-client.rs:26:46
    |
26  |   let mut reader = BufReader::new(tokio::io::stdin());
    |                                              ^^^^^ not found in `tokio::io`
```

After fixing the dependency in tokio (added feature `io-std` to tokio dependency),

```
$ cargo run --features=wtx/web-socket-handshake --example web-socket-client
Error: WebSocketError(MissingSwitchingProtocols)
```


Discussion / hints:
Hello,

Thank you for pointing out the missing feature. It will be included in the next release.

```bash
$ cargo run --features=wtx/web-socket-handshake --example web-socket-client
Error: WebSocketError(MissingSwitchingProtocols)
```

The `web-socket-client` example is trying to connect to the `ws://www.example.com` URL that actually exists but doesn't support WebSocket, thus the protocol error. In the next release `ws://www.example.com` will be replaced with `SOME_URI` to avoid further misunderstandings.

```bash
$ cargo run --features=wtx/http2 --example http2-client
Error: Http2ErrorGoAway(FrameSizeError, Some(LargeArbitraryFrameLen))
```

Same thing with `http2-client`. The code is trying to connect to the `http://www.example.com` server over an unencrypted connection, which is unsupported.



Hi,

Thanks for the response.

Have you tested http2-client with https://www.example.com or other web sites that support HTTP/2? I get the same `FrameSizeError` or `IoError(Os { code: 104, kind: ConnectionReset, message: "Connection reset by peer" })`.

I tested different URLs that actually support websocket upgrade with web-socket-client but it did not work.

Could you check from your side?
Hello,

Browsers don't allow upgrading unencrypted connections to encrypted HTTP/2 connections so the way only to connect to `https://www.example.com` is through the use of ALPN. Here goes a snippet that does that.

```toml
[dependencies]
tokio = { default-features = false, features = ["macros", "net", "rt-multi-thread"], version = "1.0" }
wtx = { default-features = false, features = ["http2", "tokio-rustls", "webpki-roots"], version = "0.27" }
```

```rust
use tokio::net::TcpStream;
use wtx::{
  http::{Method, ReqResBuffer, Request},
  http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2Tokio},
  misc::{TokioRustlsConnector, Uri, Xorshift64, from_utf8_basic, simple_seed},
};

#[tokio::main]
async fn main() -> wtx::Result<()> {
  let uri = Uri::new("https://www.example.com");
  let tls_connector = TokioRustlsConnector::from_auto()?.http2();
  let stream = TcpStream::connect(uri.hostname_with_implied_port()).await?;
  let (frame_reader, mut http2) = Http2Tokio::connect(
    Http2Buffer::new(Xorshift64::from(simple_seed())),
    Http2Params::default(),
    tokio::io::split(tls_connector.connect_without_client_auth(uri.hostname(), stream).await?),
  )
  .await?;
  let _jh = tokio::spawn(frame_reader);
  let rrb = ReqResBuffer::empty();
  let mut stream = http2.stream().await?;
  stream.send_req(Request::http2(Method::Get, b"Hello!"), &uri.to_ref()).await?;
  let (_, res_rrb) = stream.recv_res(rrb).await?;
  stream.common().clear(false).await?;
  println!("{}", from_utf8_basic(&res_rrb.body)?);
  http2.send_go_away(Http2ErrorCode::NoError).await;
  Ok(())
}
```

It is worth noting that the RFC specifies very low default values so you will have to increase some `Http2Params` parameters to fetch larger websites like `google.com`. If you don't want to deal with low-level HTTP/2 stuff, then the HTTP client framework or HTTP client pool should automatically handle the most boring stuff.

Please bare in mind that `wtx` is under active development and breaking changes are expected in the near future, as such, it is recommended to pursue more stable and well-known alternatives like `reqwest`.

Cheers

Fix patch:
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index 04e2ed5a..dd72cd46 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -25,7 +25,7 @@ jobs:
           echo `pwd`/mdbook >> $GITHUB_PATH
       - name: Test and Build Book
         run: |
-          rustup default nightly-2024-11-22
+          rustup default nightly-2025-02-23
           cargo clean --target-dir mdbook-target
           cargo build --all-features --target-dir mdbook-target
           mdbook test -L mdbook-target/debug/deps wtx-docs && mdbook build wtx-docs
diff --git a/.gitignore b/.gitignore
index 410e1ef2..6751378e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
 **/rustc-ice-*.txt
 **/target
 boringssl
+callgrind*
 mdbook-target
 wtx-docs/book
 wtx-fuzz/artifacts
diff --git a/.scripts/h2load.sh b/.scripts/h2load.sh
index 0650f5ff..dbb41e56 100755
--- a/.scripts/h2load.sh
+++ b/.scripts/h2load.sh
@@ -11,4 +11,4 @@ cargo build --bin h2load --features="wtx/http2,wtx/nightly" --profile deploy
 cargo run --bin h2load --features="wtx/http2,wtx/nightly" --profile deploy &
 sleep 1
 
-h2load -c100 -m10 -n100000 --no-tls-proto=h2c http://localhost:9000
+h2load -c100 --log-file=/tmp/h2load.txt -m10 -n100000 --no-tls-proto=h2c http://localhost:9000
diff --git a/.scripts/podman-rm.sh b/.scripts/podman-rm.sh
index 708b498b..f9a1b059 100755
--- a/.scripts/podman-rm.sh
+++ b/.scripts/podman-rm.sh
@@ -1,1 +1,2 @@
+podman container rm -fi wtx_mysql
 podman container rm -fi wtx_postgres_scram
diff --git a/.scripts/podman-start.sh b/.scripts/podman-start.sh
index 38081e43..dca02cfe 100755
--- a/.scripts/podman-start.sh
+++ b/.scripts/podman-start.sh
@@ -1,3 +1,14 @@
+podman run \
+    -d \
+    --name wtx_mysql \
+    -e MYSQL_DATABASE=wtx \
+    -e MYSQL_PASSWORD=wtx \
+    -e MYSQL_ROOT_HOST='%' \
+    -e MYSQL_ROOT_PASSWORD=wtx \
+    -e MYSQL_USER=wtx \
+    -p 3306:3306 \
+    docker.io/library/mysql:9
+
 podman run \
     -d \
     --name wtx_postgres_scram \
diff --git a/Cargo.lock b/Cargo.lock
index 55d79403..8260f1e8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,16 +17,6 @@ version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
 
-[[package]]
-name = "aead"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
-dependencies = [
- "crypto-common 0.1.6",
- "generic-array 0.14.7",
-]
-
 [[package]]
 name = "aead"
 version = "0.6.0-rc.0"
@@ -36,17 +26,6 @@ dependencies = [
  "crypto-common 0.2.0-rc.1",
 ]
 
-[[package]]
-name = "aes"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
-dependencies = [
- "cfg-if",
- "cipher 0.4.4",
- "cpufeatures",
-]
-
 [[package]]
 name = "aes"
 version = "0.9.0-pre.2"
@@ -54,35 +33,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e7856582c758ade85d71daf27ec6bcea6c1c73913692b07b8dffea2dc03531c9"
 dependencies = [
  "cfg-if",
- "cipher 0.5.0-pre.7",
+ "cipher",
  "cpufeatures",
 ]
 
-[[package]]
-name = "aes-gcm"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
-dependencies = [
- "aead 0.5.2",
- "aes 0.8.4",
- "cipher 0.4.4",
- "ctr 0.9.2",
- "ghash 0.5.1",
- "subtle",
-]
-
 [[package]]
 name = "aes-gcm"
 version = "0.11.0-pre.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0cce27af05d45b901bb28da33ff8b2b2b2044f595b24fc0f36d4882dae91d484"
 dependencies = [
- "aead 0.6.0-rc.0",
- "aes 0.9.0-pre.2",
- "cipher 0.5.0-pre.7",
- "ctr 0.10.0-pre.2",
- "ghash 0.6.0-rc.0",
+ "aead",
+ "aes",
+ "cipher",
+ "ctr",
+ "ghash",
  "subtle",
 ]
 
@@ -154,27 +119,6 @@ version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
 
-[[package]]
-name = "as-slice"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0"
-dependencies = [
- "generic-array 0.12.4",
- "generic-array 0.13.3",
- "generic-array 0.14.7",
- "stable_deref_trait",
-]
-
-[[package]]
-name = "atomic-polyfill"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
-dependencies = [
- "critical-section",
-]
-
 [[package]]
 name = "autocfg"
 version = "1.4.0"
@@ -183,9 +127,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
 name = "aws-lc-rs"
-version = "1.12.2"
+version = "1.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c2b7ddaa2c56a367ad27a094ad8ef4faacf8a617c2575acb2ba88949df999ca"
+checksum = "4cd755adf9707cf671e31d944a189be3deaaeee11c8bc1d669bb8022ac90fbd0"
 dependencies = [
  "aws-lc-sys",
  "paste",
@@ -194,9 +138,9 @@ dependencies = [
 
 [[package]]
 name = "aws-lc-sys"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71b2ddd3ada61a305e1d8bb6c005d1eaa7d14d903681edfc400406d523a9b491"
+checksum = "0f9dd2e03ee80ca2822dd6ea431163d2ef259f2066a4d6ccaca6d9dcb386aa43"
 dependencies = [
  "bindgen",
  "cc",
@@ -221,12 +165,6 @@ dependencies = [
  "windows-targets",
 ]
 
-[[package]]
-name = "base16ct"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
-
 [[package]]
 name = "base64"
 version = "0.22.1"
@@ -268,7 +206,7 @@ dependencies = [
  "regex",
  "rustc-hash",
  "shlex",
- "syn 2.0.97",
+ "syn 2.0.98",
  "which",
 ]
 
@@ -311,7 +249,7 @@ version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
 dependencies = [
- "generic-array 0.14.7",
+ "generic-array",
 ]
 
 [[package]]
@@ -343,7 +281,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -382,15 +320,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
-version = "1.9.0"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
+checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
 
 [[package]]
 name = "cc"
-version = "1.2.11"
+version = "1.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4730490333d58093109dc02c23174c3f4d490998c3fed3cc8e82d57afedb9cf"
+checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af"
 dependencies = [
  "jobserver",
  "libc",
@@ -431,16 +369,6 @@ dependencies = [
  "windows-targets",
 ]
 
-[[package]]
-name = "cipher"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
-dependencies = [
- "crypto-common 0.1.6",
- "inout 0.1.3",
-]
-
 [[package]]
 name = "cipher"
 version = "0.5.0-pre.7"
@@ -448,7 +376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5b1425e6ce000f05a73096556cabcfb6a10a3ffe3bb4d75416ca8f00819c0b6a"
 dependencies = [
  "crypto-common 0.2.0-rc.1",
- "inout 0.2.0-rc.0",
+ "inout",
 ]
 
 [[package]]
@@ -474,9 +402,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.27"
+version = "4.5.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
+checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -484,9 +412,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.27"
+version = "4.5.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
+checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c"
 dependencies = [
  "anstyle",
  "clap_lex",
@@ -494,14 +422,14 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.5.24"
+version = "4.5.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
+checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed"
 dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -512,9 +440,9 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
 
 [[package]]
 name = "cmake"
-version = "0.1.53"
+version = "0.1.54"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e24a03c8b52922d68a1589ad61032f2c1aa5a8158d2aa0d93c6e9534944bbad6"
+checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
 dependencies = [
  "cc",
 ]
@@ -555,25 +483,13 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
 
-[[package]]
-name = "crypto-bigint"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
-dependencies = [
- "generic-array 0.14.7",
- "rand_core 0.6.4",
- "subtle",
- "zeroize",
-]
-
 [[package]]
 name = "crypto-common"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
 dependencies = [
- "generic-array 0.14.7",
+ "generic-array",
  "typenum",
 ]
 
@@ -588,22 +504,13 @@ dependencies = [
  "rand_core 0.6.4",
 ]
 
-[[package]]
-name = "ctr"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
-dependencies = [
- "cipher 0.4.4",
-]
-
 [[package]]
 name = "ctr"
 version = "0.10.0-pre.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77e1482d284b80d7fddb211666d513dc5e23b0cc3a03ad398ff70543827c789f"
 dependencies = [
- "cipher 0.5.0-pre.7",
+ "cipher",
 ]
 
 [[package]]
@@ -624,7 +531,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -640,9 +547,9 @@ dependencies = [
 
 [[package]]
 name = "document-features"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0"
+checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
 dependencies = [
  "litrs",
 ]
@@ -665,25 +572,6 @@ version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
 
-[[package]]
-name = "elliptic-curve"
-version = "0.13.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
-dependencies = [
- "base16ct",
- "crypto-bigint",
- "digest",
- "ff",
- "generic-array 0.14.7",
- "group",
- "hkdf",
- "rand_core 0.6.4",
- "sec1",
- "subtle",
- "zeroize",
-]
-
 [[package]]
 name = "embassy-net"
 version = "0.5.0"
@@ -696,7 +584,7 @@ dependencies = [
  "embassy-time",
  "embedded-io-async",
  "embedded-nal-async",
- "heapless 0.8.0",
+ "heapless",
  "managed",
  "smoltcp",
 ]
@@ -718,7 +606,7 @@ dependencies = [
  "embedded-io-async",
  "futures-sink",
  "futures-util",
- "heapless 0.8.0",
+ "heapless",
 ]
 
 [[package]]
@@ -736,7 +624,7 @@ dependencies = [
  "embedded-hal 1.0.0",
  "embedded-hal-async",
  "futures-util",
- "heapless 0.8.0",
+ "heapless",
 ]
 
 [[package]]
@@ -813,33 +701,11 @@ dependencies = [
  "embedded-nal",
 ]
 
-[[package]]
-name = "embedded-tls"
-version = "0.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6efb76fdd004a4ef787640177237b83449e6c5847765ea50bf15900061fd601"
-dependencies = [
- "aes-gcm 0.10.3",
- "atomic-polyfill",
- "digest",
- "embedded-io",
- "embedded-io-async",
- "generic-array 0.14.7",
- "heapless 0.6.1",
- "heapless 0.8.0",
- "hkdf",
- "hmac",
- "p256",
- "rand_core 0.6.4",
- "sha2",
- "typenum",
-]
-
 [[package]]
 name = "equivalent"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
 
 [[package]]
 name = "errno"
@@ -857,16 +723,6 @@ version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
-[[package]]
-name = "ff"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
-dependencies = [
- "rand_core 0.6.4",
- "subtle",
-]
-
 [[package]]
 name = "flate2"
 version = "1.0.35"
@@ -884,6 +740,15 @@ version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
 
+[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
 [[package]]
 name = "fs_extra"
 version = "1.3.0"
@@ -926,24 +791,6 @@ dependencies = [
  "pin-utils",
 ]
 
-[[package]]
-name = "generic-array"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
-dependencies = [
- "typenum",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.13.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
-dependencies = [
- "typenum",
-]
-
 [[package]]
 name = "generic-array"
 version = "0.14.7"
@@ -952,7 +799,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
 dependencies = [
  "typenum",
  "version_check",
- "zeroize",
 ]
 
 [[package]]
@@ -978,16 +824,6 @@ dependencies = [
  "windows-targets",
 ]
 
-[[package]]
-name = "ghash"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
-dependencies = [
- "opaque-debug",
- "polyval 0.6.2",
-]
-
 [[package]]
 name = "ghash"
 version = "0.6.0-rc.0"
@@ -995,7 +831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3b92860fda25ab571512af210134cde2c42732cd53253bcee3f21b288b7afbc4"
 dependencies = [
  "opaque-debug",
- "polyval 0.7.0-rc.0",
+ "polyval",
 ]
 
 [[package]]
@@ -1010,26 +846,6 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
 
-[[package]]
-name = "group"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
-dependencies = [
- "ff",
- "rand_core 0.6.4",
- "subtle",
-]
-
-[[package]]
-name = "hash32"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
-dependencies = [
- "byteorder",
-]
-
 [[package]]
 name = "hash32"
 version = "0.3.1"
@@ -1057,25 +873,13 @@ dependencies = [
  "foldhash",
 ]
 
-[[package]]
-name = "heapless"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "634bd4d29cbf24424d0a4bfcbf80c6960129dc24424752a7d1d1390607023422"
-dependencies = [
- "as-slice",
- "generic-array 0.14.7",
- "hash32 0.1.1",
- "stable_deref_trait",
-]
-
 [[package]]
 name = "heapless"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
 dependencies = [
- "hash32 0.3.1",
+ "hash32",
  "stable_deref_trait",
 ]
 
@@ -1091,15 +895,6 @@ version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 
-[[package]]
-name = "hkdf"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
-dependencies = [
- "hmac",
-]
-
 [[package]]
 name = "hmac"
 version = "0.12.1"
@@ -1166,15 +961,6 @@ dependencies = [
  "hashbrown 0.15.2",
 ]
 
-[[package]]
-name = "inout"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
-dependencies = [
- "generic-array 0.14.7",
-]
-
 [[package]]
 name = "inout"
 version = "0.2.0-rc.0"
@@ -1233,9 +1019,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.169"
+version = "0.2.170"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
 
 [[package]]
 name = "libfuzzer-sys"
@@ -1259,9 +1045,9 @@ dependencies = [
 
 [[package]]
 name = "libz-rs-sys"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a90e19106f1b2c93f1fa6cdeec2e56facbf2e403559c1e1c0ddcc6d46e979cdf"
+checksum = "902bc563b5d65ad9bba616b490842ef0651066a1a1dc3ce1087113ffcb873c8d"
 dependencies = [
  "zlib-rs",
 ]
@@ -1280,9 +1066,9 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
 
 [[package]]
 name = "log"
-version = "0.4.25"
+version = "0.4.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
+checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
 
 [[package]]
 name = "managed"
@@ -1319,9 +1105,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.3"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
+checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
 dependencies = [
  "adler2",
 ]
@@ -1371,6 +1157,25 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "num-bigint"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+dependencies = [
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
+dependencies = [
+ "num-traits",
+]
+
 [[package]]
 name = "num-traits"
 version = "0.2.19"
@@ -1391,9 +1196,9 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.20.2"
+version = "1.20.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
 
 [[package]]
 name = "opaque-debug"
@@ -1401,16 +1206,6 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
 
-[[package]]
-name = "p256"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
-dependencies = [
- "elliptic-curve",
- "primeorder",
-]
-
 [[package]]
 name = "password-hash"
 version = "0.5.0"
@@ -1440,14 +1235,20 @@ dependencies = [
 
 [[package]]
 name = "pem"
-version = "3.0.4"
+version = "3.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
+checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
 dependencies = [
  "base64",
  "serde",
 ]
 
+[[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
 [[package]]
 name = "pin-project-lite"
 version = "0.2.16"
@@ -1460,18 +1261,6 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
-[[package]]
-name = "polyval"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "opaque-debug",
- "universal-hash 0.5.1",
-]
-
 [[package]]
 name = "polyval"
 version = "0.7.0-rc.0"
@@ -1481,7 +1270,7 @@ dependencies = [
  "cfg-if",
  "cpufeatures",
  "opaque-debug",
- "universal-hash 0.6.0-rc.0",
+ "universal-hash",
 ]
 
 [[package]]
@@ -1515,16 +1304,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
 dependencies = [
  "proc-macro2",
- "syn 2.0.97",
-]
-
-[[package]]
-name = "primeorder"
-version = "0.13.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
-dependencies = [
- "elliptic-curve",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -1617,7 +1397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
 dependencies = [
  "ppv-lite86",
- "rand_core 0.9.0",
+ "rand_core 0.9.2",
 ]
 
 [[package]]
@@ -1631,12 +1411,12 @@ dependencies = [
 
 [[package]]
 name = "rand_core"
-version = "0.9.0"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
+checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c"
 dependencies = [
  "getrandom 0.3.1",
- "zerocopy 0.8.14",
+ "zerocopy 0.8.20",
 ]
 
 [[package]]
@@ -1694,15 +1474,14 @@ dependencies = [
 
 [[package]]
 name = "ring"
-version = "0.17.8"
+version = "0.17.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
+checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73"
 dependencies = [
  "cc",
  "cfg-if",
  "getrandom 0.2.15",
  "libc",
- "spin",
  "untrusted",
  "windows-sys 0.52.0",
 ]
@@ -1779,9 +1558,9 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.23.22"
+version = "0.23.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7"
+checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
 dependencies = [
  "aws-lc-rs",
  "once_cell",
@@ -1837,44 +1616,31 @@ version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
 
-[[package]]
-name = "sec1"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
-dependencies = [
- "base16ct",
- "der",
- "generic-array 0.14.7",
- "subtle",
- "zeroize",
-]
-
 [[package]]
 name = "serde"
-version = "1.0.217"
+version = "1.0.218"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.217"
+version = "1.0.218"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.138"
+version = "1.0.139"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
+checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6"
 dependencies = [
  "itoa",
  "memchr",
@@ -1891,6 +1657,18 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
 [[package]]
 name = "sha1"
 version = "0.10.6"
@@ -1945,9 +1723,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
 
 [[package]]
 name = "smallvec"
-version = "1.13.2"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
 
 [[package]]
 name = "smoltcp"
@@ -1958,7 +1736,7 @@ dependencies = [
  "bitflags 1.3.2",
  "byteorder",
  "cfg-if",
- "heapless 0.8.0",
+ "heapless",
  "managed",
 ]
 
@@ -1972,12 +1750,6 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
-[[package]]
-name = "spin"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-
 [[package]]
 name = "spki"
 version = "0.7.3"
@@ -2013,9 +1785,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.97"
+version = "2.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dabd04e3b9a8c3c03d5e743f5ef5e1207befc9de704d477f7198cc28049763e"
+checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2030,9 +1802,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
 
 [[package]]
 name = "target-triple"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078"
+checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790"
 
 [[package]]
 name = "termcolor"
@@ -2060,7 +1832,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -2112,7 +1884,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -2127,9 +1899,9 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.8.19"
+version = "0.8.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
+checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -2148,9 +1920,9 @@ dependencies = [
 
 [[package]]
 name = "toml_edit"
-version = "0.22.23"
+version = "0.22.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee"
+checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
 dependencies = [
  "indexmap",
  "serde",
@@ -2178,7 +1950,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -2234,25 +2006,15 @@ dependencies = [
 
 [[package]]
 name = "typenum"
-version = "1.17.0"
+version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.16"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
-
-[[package]]
-name = "universal-hash"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
-dependencies = [
- "crypto-common 0.1.6",
- "subtle",
-]
+checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
 
 [[package]]
 name = "universal-hash"
@@ -2272,9 +2034,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
 
 [[package]]
 name = "uuid"
-version = "1.12.1"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
+checksum = "93d59ca99a559661b96bf898d8fce28ed87935fd2bea9f05983c1464dd6c71b1"
 
 [[package]]
 name = "valuable"
@@ -2331,7 +2093,7 @@ dependencies = [
  "log",
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
  "wasm-bindgen-shared",
 ]
 
@@ -2353,7 +2115,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -2490,9 +2252,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
 name = "winnow"
-version = "0.7.0"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e49d2d35d3fad69b39b94139037ecfb4f359f08958b9c11e7315ce770462419"
+checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
 dependencies = [
  "memchr",
 ]
@@ -2510,7 +2272,7 @@ dependencies = [
 name = "wtx"
 version = "0.27.0"
 dependencies = [
- "aes-gcm 0.11.0-pre.2",
+ "aes-gcm",
  "arbitrary",
  "argon2",
  "aws-lc-rs",
@@ -2522,8 +2284,6 @@ dependencies = [
  "digest",
  "embassy-net",
  "embassy-time",
- "embedded-io-async",
- "embedded-tls",
  "fastrand",
  "flate2",
  "foldhash",
@@ -2533,10 +2293,12 @@ dependencies = [
  "httparse",
  "matchit",
  "memchr",
+ "num-bigint",
  "portable-atomic",
  "portable-atomic-util",
  "quick-protobuf",
  "rand_chacha 0.9.0",
+ "rand_core 0.9.2",
  "ring",
  "rust_decimal",
  "rustls",
@@ -2544,6 +2306,7 @@ dependencies = [
  "rustls-pki-types",
  "serde",
  "serde_json",
+ "serde_urlencoded",
  "sha1",
  "sha2",
  "simdutf8",
@@ -2642,11 +2405,11 @@ dependencies = [
 
 [[package]]
 name = "zerocopy"
-version = "0.8.14"
+version = "0.8.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
+checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c"
 dependencies = [
- "zerocopy-derive 0.8.14",
+ "zerocopy-derive 0.8.20",
 ]
 
 [[package]]
@@ -2657,18 +2420,18 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.8.14"
+version = "0.8.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
+checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
@@ -2688,11 +2451,11 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.97",
+ "syn 2.0.98",
 ]
 
 [[package]]
 name = "zlib-rs"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aada01553a9312bad4b9569035a1f12b05e5ec9770a1a4b323757356928944f8"
+checksum = "8b20717f0917c908dc63de2e44e97f1e6b126ca58d0e391cee86d504eb8fbd05"
diff --git a/Cargo.toml b/Cargo.toml
index 5060aacf..f33b10bb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,5 +16,11 @@ inherits = "release"
 debug = true
 
 [workspace]
-members = ["wtx", "wtx-fuzz", "wtx-instances", "wtx-macros", "wtx-ui"]
+members = [
+    "wtx",
+    "wtx-fuzz",
+    "wtx-instances",
+    "wtx-macros",
+    "wtx-ui"
+]
 resolver = "2"
diff --git a/README.md b/README.md
index 06019789..50cfa7f7 100644
--- a/README.md
+++ b/README.md
@@ -7,17 +7,17 @@
 [![Tests][actions-badge]][actions-url]
 
 [actions-badge]: https://github.com/c410-f3r/wtx/workflows/Tests/badge.svg
-[actions-url]: https://github.com/c410-f3r/wtx/actions?query=workflow%3ATests+branch%3Amaster
+[actions-url]: https://github.com/c410-f3r/wtx/actions?query=workflow%3ATests+branch%3Amain
 [crates-badge]: https://img.shields.io/crates/v/wtx.svg?color=blue
 [crates-url]: https://crates.io/crates/wtx
 [docs-badge]: https://docs.rs/wtx/badge.svg
 [docs-url]: https://docs.rs/wtx
 [license-badge]: https://img.shields.io/badge/license-MPL2-blue.svg
-[license-url]: https://github.com/c410-f3r/wtx/blob/master/LICENSE
+[license-url]: https://github.com/c410-f3r/wtx/blob/main/LICENSE
 [rustc-badge]: https://img.shields.io/badge/rustc-1.84-blue
 [rustc-url]: https://blog.rust-lang.org/2025/01/09/Rust-1.84.0.html
 
-A collection of different transport implementations and related tools focused primarily on web technologies. Features the in-house development of 6 IETF RFCs ([6265](https://datatracker.ietf.org/doc/html/rfc6265), [6455](https://datatracker.ietf.org/doc/html/rfc6455), [7541](https://datatracker.ietf.org/doc/html/rfc7541), [7692](https://datatracker.ietf.org/doc/html/rfc7692), [8441](https://datatracker.ietf.org/doc/html/rfc8441), [9113](https://datatracker.ietf.org/doc/html/rfc9113)), 2 formal specifications ([gRPC](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), [PostgreSQL](https://www.postgresql.org/docs/current/protocol.html)) and several other invented ideas.
+A collection of different transport implementations and related tools focused primarily on web technologies. Features the in-house development of 6 IETF RFCs ([6265](https://datatracker.ietf.org/doc/html/rfc6265), [6455](https://datatracker.ietf.org/doc/html/rfc6455), [7541](https://datatracker.ietf.org/doc/html/rfc7541), [7692](https://datatracker.ietf.org/doc/html/rfc7692), [8441](https://datatracker.ietf.org/doc/html/rfc8441), [9113](https://datatracker.ietf.org/doc/html/rfc9113)), 3 formal specifications ([gRPC](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), [MySQL](https://dev.mysql.com/doc/dev/mysql-server/latest/), [PostgreSQL](https://www.postgresql.org/docs/current/protocol.html)) and several other invented ideas.
 
 1. [Client API Framework](https://c410-f3r.github.io/wtx/client-api-framework/index.html)
 2. [Database Client](https://c410-f3r.github.io/wtx/database-client/index.html)
diff --git a/rust-toolchain b/rust-toolchain
index 3d6d9d19..db172799 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2024-11-22"
+channel = "nightly-2025-02-23"
 components = ["clippy", "miri", "rustfmt", "rust-src"]
 profile = "minimal"
diff --git a/rustfmt.toml b/rustfmt.toml
index 224e3a03..b77d6658 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,7 +1,7 @@
-edition="2021"
+edition = "2024"
 imports_granularity = "Crate"
 newline_style = "Unix"
 reorder_imports = true
-tab_spaces=2
-use_field_init_shorthand=true
-use_small_heuristics="Max"
+tab_spaces = 2
+use_field_init_shorthand = true
+use_small_heuristics = "Max"
diff --git a/wtx-docs/src/client-api-framework/README.md b/wtx-docs/src/client-api-framework/README.md
index 228a0d34..25dd6287 100644
--- a/wtx-docs/src/client-api-framework/README.md
+++ b/wtx-docs/src/client-api-framework/README.md
@@ -16,6 +16,6 @@ Moreover, the project may in the future create automatic bindings for other lang
 
 ## Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/generic-examples/client-api-framework.rs}}
 ```
\ No newline at end of file
diff --git a/wtx-docs/src/database-client/README.md b/wtx-docs/src/database-client/README.md
index 31ab4031..6bb9db8e 100644
--- a/wtx-docs/src/database-client/README.md
+++ b/wtx-docs/src/database-client/README.md
@@ -3,16 +3,32 @@
 
 Provides a set of functions that establish connections, execute queries and manage data transactions with different databases.
 
-At the current time PostgreSQL is the only supported database. Implements <https://www.postgresql.org/docs/16/protocol.html>.
+Independent benchmarks are available at <https://github.com/diesel-rs/metrics>.
 
-More benchmarks are available at <https://github.com/diesel-rs/metrics>.
+## PostgreSQL
+
+Implements a subset of <https://www.postgresql.org/docs/16/protocol.html>. PostgreSQL is a robust, open-source relational database management system that, among other things, supports several data types and usually also excels in concurrent scenarios.
 
 To use this functionality, it is necessary to activate the `postgres` feature.
 
 ![PostgreSQL Benchmark](https://i.imgur.com/vf2tYxY.jpeg)
 
-## Example
+### Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/database-examples/database-client-postgres.rs}}
 ```
+
+## MySQL
+
+Implements a subset of <https://dev.mysql.com/doc/dev/mysql-server/latest/>. MySQL is also a robust, open-source relational database management system generally used in web applications.
+
+`WTX` includes CI coverage for MariaDB and Percona, as such, interactions with these MySQL-based databases shouldn't be a problem.
+
+To use this functionality, it is necessary to activate the `mysql` feature.
+
+### Example
+
+```rust,edition2024,no_run
+{{#rustdoc_include ../../../wtx-instances/database-examples/database-client-mysql.rs}}
+```
\ No newline at end of file
diff --git a/wtx-docs/src/database-schema-manager/README.md b/wtx-docs/src/database-schema-manager/README.md
index f59ac99d..696f5800 100644
--- a/wtx-docs/src/database-schema-manager/README.md
+++ b/wtx-docs/src/database-schema-manager/README.md
@@ -93,7 +93,7 @@ wtx.toml
 
 The library gives freedom to arrange groups and uses some external crates, bringing ~10 additional dependencies into your application. If this overhead is not acceptable, then you probably should discard the library and use the CLI binary instead as part of a custom deployment strategy.
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 extern crate tokio;
 extern crate wtx;
 
@@ -118,7 +118,7 @@ async fn main() {
 
 To make deployment easier, the final binary of your application can embed all necessary migrations through the binary that is available in the `wtx-ui` crate.
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 extern crate wtx;
 
 // This is an example! The actual contents are filled by the `wtx-ui embed-migrations` binary call.
diff --git a/wtx-docs/src/grpc/README.md b/wtx-docs/src/grpc/README.md
index be447892..f666bb1f 100644
--- a/wtx-docs/src/grpc/README.md
+++ b/wtx-docs/src/grpc/README.md
@@ -9,16 +9,18 @@ Due to the lack of an official parser, the definitions of a `Service` must be ma
 
 Independent benchmarks are available <https://github.com/LesnyRumcajs/grpc_bench>.
 
-To use this functionality, it is necessary to activate the `grpc` feature.
-
 ## Client Example
 
-```rust,edition2021,no_run
+To use this functionality, it is necessary to activate the `grpc-client` feature.
+
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/generic-examples/grpc-client.rs}}
 ```
 
 ## Server Example
 
-```rust,edition2021,no_run
+To use this functionality, it is necessary to activate the `grpc-server` feature.
+
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/generic-examples/grpc-server.rs}}
 ```
diff --git a/wtx-docs/src/http-client-pool/README.md b/wtx-docs/src/http-client-pool/README.md
index 0115b3de..833bc2de 100644
--- a/wtx-docs/src/http-client-pool/README.md
+++ b/wtx-docs/src/http-client-pool/README.md
@@ -6,6 +6,6 @@ To use this functionality, it is necessary to activate the `http-client-pool` fe
 
 ## Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/generic-examples/http-client-pool.rs}}
 ```
\ No newline at end of file
diff --git a/wtx-docs/src/http-server-framework/README.md b/wtx-docs/src/http-server-framework/README.md
index f648c885..b7490aba 100644
--- a/wtx-docs/src/http-server-framework/README.md
+++ b/wtx-docs/src/http-server-framework/README.md
@@ -17,6 +17,6 @@ To use this functionality, it is necessary to activate the `http-server-framewor
 
 ## Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/http-server-framework-examples/http-server-framework.rs}}
 ```
\ No newline at end of file
diff --git a/wtx-docs/src/http2/README.md b/wtx-docs/src/http2/README.md
index d74def63..52d26af7 100644
--- a/wtx-docs/src/http2/README.md
+++ b/wtx-docs/src/http2/README.md
@@ -8,12 +8,12 @@ To use this functionality, it is necessary to activate the `http2` feature.
 
 ## Client Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/http2-examples/http2-client.rs}}
 ```
 
 ## Server Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/http2-examples/http2-server.rs}}
 ```
diff --git a/wtx-docs/src/pool/README.md b/wtx-docs/src/pool/README.md
index c2443f67..ed2994c7 100644
--- a/wtx-docs/src/pool/README.md
+++ b/wtx-docs/src/pool/README.md
@@ -8,6 +8,6 @@ To use this functionality, it is necessary to activate the `pool` feature.
 
 ## Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/generic-examples/pool.rs}}
 ```
\ No newline at end of file
diff --git a/wtx-docs/src/web-socket-over-http2/README.md b/wtx-docs/src/web-socket-over-http2/README.md
index 745354ee..c513b104 100644
--- a/wtx-docs/src/web-socket-over-http2/README.md
+++ b/wtx-docs/src/web-socket-over-http2/README.md
@@ -13,6 +13,6 @@ To use this functionality, it is necessary to activate the `http2` and `web-sock
 
 ## Example
 
-```rust,edition2021,no_run
+```rust,2024,no_run
 {{#rustdoc_include ../../../wtx-instances/http2-examples/http2-web-socket.rs}}
 ```
\ No newline at end of file
diff --git a/wtx-docs/src/web-socket/README.md b/wtx-docs/src/web-socket/README.md
index 2769d760..0aaaf005 100644
--- a/wtx-docs/src/web-socket/README.md
+++ b/wtx-docs/src/web-socket/README.md
@@ -27,18 +27,18 @@ To make everything work as intended both parties, client and server, need to imp
 
 ## Client Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/web-socket-examples/web-socket-client.rs}}
 ```
 
 ## Concurrent Client Example
 
-```rust,edition2021,no_run
-{{#rustdoc_include ../../../wtx-instances/web-socket-examples/web-socket-concurrent-client.rs}}
+```rust,edition2024,no_run
+{{#rustdoc_include ../../../wtx-instances/web-socket-examples/web-socket-client-concurrent.rs}}
 ```
 
 ## Server Example
 
-```rust,edition2021,no_run
+```rust,edition2024,no_run
 {{#rustdoc_include ../../../wtx-instances/web-socket-examples/web-socket-server.rs}}
 ```
diff --git a/wtx-fuzz/Cargo.toml b/wtx-fuzz/Cargo.toml
index be1219e2..b12295bc 100644
--- a/wtx-fuzz/Cargo.toml
+++ b/wtx-fuzz/Cargo.toml
@@ -9,7 +9,7 @@ tokio = { default-features = false, features = ["rt"], version = "1.0" }
 wtx = { default-features = false, features = ["arbitrary", "web-socket"], path = "../wtx" }
 
 [package]
-edition = "2021"
+edition = "2024"
 name = "wtx-fuzz"
 publish = false
 version = "0.0.0"
diff --git a/wtx-fuzz/web_socket.rs b/wtx-fuzz/web_socket.rs
index 8aef5a45..27baaba7 100644
--- a/wtx-fuzz/web_socket.rs
+++ b/wtx-fuzz/web_socket.rs
@@ -5,7 +5,7 @@
 
 use tokio::runtime::Builder;
 use wtx::{
-  misc::{simple_seed, BytesStream, Xorshift64},
+  misc::{BytesStream, Xorshift64, simple_seed},
   web_socket::{Frame, OpCode, WebSocket, WebSocketBuffer},
 };
 
diff --git a/wtx-instances/Cargo.toml b/wtx-instances/Cargo.toml
index 03c9b436..54395f7b 100644
--- a/wtx-instances/Cargo.toml
+++ b/wtx-instances/Cargo.toml
@@ -1,4 +1,4 @@
-# Fulfillments Binaries
+# Fulfillment Binaries
 
 [[bin]]
 name = "autobahn-client"
@@ -27,6 +27,11 @@ required-features = ["wtx/http2", "wtx/nightly"]
 
 # Database Examples
 
+[[example]]
+name = "database-client-mysql"
+path = "database-examples/database-client-mysql.rs"
+required-features = ["wtx/mysql"]
+
 [[example]]
 name = "database-client-postgres"
 path = "database-examples/database-client-postgres.rs"
@@ -104,8 +109,8 @@ path = "http2-examples/http2-server.rs"
 required-features = ["wtx/http2", "wtx/tokio-rustls", "wtx/web-socket"]
 
 [[example]]
-name = "http2-web-socket"
-path = "http2-examples/http2-web-socket.rs"
+name = "http2-server-web-socket"
+path = "http2-examples/http2-server-web-socket.rs"
 required-features = ["wtx/http2", "wtx/tokio-rustls", "wtx/web-socket"]
 
 # WebSocket Examples
@@ -116,8 +121,8 @@ path = "web-socket-examples/web-socket-client.rs"
 required-features = ["wtx/web-socket-handshake"]
 
 [[example]]
-name = "web-socket-concurrent-client"
-path = "web-socket-examples/web-socket-concurrent-client.rs"
+name = "web-socket-client-concurrent"
+path = "web-socket-examples/web-socket-client-concurrent.rs"
 required-features = ["wtx/tokio-rustls", "wtx/web-socket-handshake", "wtx/webpki-roots"]
 
 [[example]]
@@ -133,17 +138,18 @@ quick-protobuf = { default-features = false, optional = true, version = "0.8" }
 rand_chacha = { default-features = false, features = ["os_rng"], optional = true, version = "0.9" }
 serde = { default-features = false, optional = true, version = "1.0" }
 serde_json = { default-features = false, features = ["alloc"], optional = true, version = "1.0" }
-tokio = { default-features = false, features = ["macros", "net", "rt-multi-thread"], version = "1.0" }
+tokio = { default-features = false, features = ["io-std", "macros", "net", "rt-multi-thread"], version = "1.0" }
 tokio-rustls = { default-features = false, optional = true, version = "0.26" }
 wtx = { default-features = false, features = ["tokio"], path = "../wtx" }
 wtx-macros = { default-features = false, optional = true, path = "../wtx-macros" }
 
 [features]
 grpc = ["pb-rs", "quick-protobuf", "wtx/grpc", "wtx/quick-protobuf"]
+mysql = ["wtx/mysql"]
 postgres = ["wtx/postgres"]
 
 [package]
-edition = "2021"
+edition = "2024"
 name = "wtx-instances"
 publish = false
 version = "0.0.0"
diff --git a/wtx-instances/build.rs b/wtx-instances/build.rs
index 9af7bff6..b2b0d1e7 100644
--- a/wtx-instances/build.rs
+++ b/wtx-instances/build.rs
@@ -3,9 +3,9 @@
 #[expect(clippy::unwrap_used, reason = "illustration purposes")]
 #[cfg(feature = "grpc")]
 mod grpc {
-  use pb_rs::{types::FileDescriptor, ConfigBuilder};
+  use pb_rs::{ConfigBuilder, types::FileDescriptor};
   use std::{
-    fs::{remove_dir_all, DirBuilder},
+    fs::{DirBuilder, remove_dir_all},
     path::Path,
   };
 
diff --git a/wtx-instances/database-examples/database-client-mysql.rs b/wtx-instances/database-examples/database-client-mysql.rs
new file mode 100644
index 00000000..7c87a451
--- /dev/null
+++ b/wtx-instances/database-examples/database-client-mysql.rs
@@ -0,0 +1,21 @@
+//! Demonstrates a MySQL query.
+//!
+//! This snippet requires ~40 dependencies and has an optimized binary size of ~600K.
+
+extern crate tokio;
+extern crate wtx;
+extern crate wtx_instances;
+
+use wtx::database::{Executor as _, Record, Records};
+
+#[tokio::main]
+async fn main() -> wtx::Result<()> {
+  let uri = "mysql://USER:PASSWORD@localhost/DATABASE";
+  let mut executor = wtx_instances::executor_mysql(&uri).await?;
+  let records = executor
+    .fetch_many_with_stmt("SELECT id, name FROM example;", (), |_| Ok::<_, wtx::Error>(()))
+    .await?;
+  assert_eq!(records.get(0).as_ref().and_then(|record| record.decode("id").ok()), Some(1));
+  assert_eq!(records.get(1).as_ref().and_then(|record| record.decode("name").ok()), Some("two"));
+  Ok(())
+}
diff --git a/wtx-instances/database-examples/database-client-postgres-composite-type.rs b/wtx-instances/database-examples/database-client-postgres-composite-type.rs
index f36419a1..853a76d1 100644
--- a/wtx-instances/database-examples/database-client-postgres-composite-type.rs
+++ b/wtx-instances/database-examples/database-client-postgres-composite-type.rs
@@ -7,9 +7,12 @@ extern crate tokio;
 extern crate wtx;
 extern crate wtx_instances;
 
-use wtx::database::{
-  client::postgres::{DecodeValue, EncodeValue, Postgres, StructDecoder, StructEncoder},
-  Decode, Encode, Executor as _, Record,
+use wtx::{
+  database::{
+    Executor as _, Record,
+    client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, StructDecoder, StructEncoder},
+  },
+  misc::{Decode, Encode},
 };
 
 #[tokio::main]
@@ -32,15 +35,15 @@ async fn main() -> wtx::Result<()> {
 struct CustomCompositeType(u32, u64);
 
 impl Decode<'_, Postgres<wtx::Error>> for CustomCompositeType {
-  fn decode(input: &DecodeValue<'_>) -> Result<Self, wtx::Error> {
-    let mut sd = StructDecoder::<wtx::Error>::new(input);
+  fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, wtx::Error> {
+    let mut sd = StructDecoder::<wtx::Error>::new(dv);
     Ok(Self(sd.decode()?, sd.decode()?))
   }
 }
 
 impl Encode<Postgres<wtx::Error>> for CustomCompositeType {
-  fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), wtx::Error> {
-    let _ev = StructEncoder::<wtx::Error>::new(ev)?.encode(self.0)?.encode(self.1)?;
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), wtx::Error> {
+    let _ev = StructEncoder::<wtx::Error>::new(ew)?.encode(self.0)?.encode(self.1)?;
     Ok(())
   }
 }
diff --git a/wtx-instances/database-examples/database-client-postgres-enum.rs b/wtx-instances/database-examples/database-client-postgres-enum.rs
index a1854394..930fcc6c 100644
--- a/wtx-instances/database-examples/database-client-postgres-enum.rs
+++ b/wtx-instances/database-examples/database-client-postgres-enum.rs
@@ -7,9 +7,12 @@ extern crate tokio;
 extern crate wtx;
 extern crate wtx_instances;
 
-use wtx::database::{
-  client::postgres::{DecodeValue, EncodeValue, Postgres},
-  Decode, Encode, Executor as _, Record,
+use wtx::{
+  database::{
+    Executor as _, Record,
+    client::postgres::{DecodeWrapper, EncodeWrapper, Postgres},
+  },
+  misc::{Decode, Encode},
 };
 
 #[tokio::main]
@@ -33,8 +36,8 @@ enum Enum {
 }
 
 impl Decode<'_, Postgres<wtx::Error>> for Enum {
-  fn decode(input: &DecodeValue<'_>) -> Result<Self, wtx::Error> {
-    let s = <&str as Decode<Postgres<wtx::Error>>>::decode(input)?;
+  fn decode(aux: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, wtx::Error> {
+    let s = <&str as Decode<Postgres<wtx::Error>>>::decode(aux, dv)?;
     Ok(match s {
       "foo" => Self::Foo,
       "bar" => Self::Bar,
@@ -45,13 +48,13 @@ impl Decode<'_, Postgres<wtx::Error>> for Enum {
 }
 
 impl Encode<Postgres<wtx::Error>> for Enum {
-  fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), wtx::Error> {
+  fn encode(&self, aux: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), wtx::Error> {
     let s = match self {
       Self::Foo => "foo",
       Self::Bar => "bar",
       Self::Baz => "baz",
     };
-    <_ as Encode<Postgres<wtx::Error>>>::encode(&s, ev)?;
+    <_ as Encode<Postgres<wtx::Error>>>::encode(&s, aux, ew)?;
     Ok(())
   }
 }
diff --git a/wtx-instances/database-examples/database-client-postgres.rs b/wtx-instances/database-examples/database-client-postgres.rs
index 8fc6d313..3e0a72a8 100644
--- a/wtx-instances/database-examples/database-client-postgres.rs
+++ b/wtx-instances/database-examples/database-client-postgres.rs
@@ -14,7 +14,7 @@ async fn main() -> wtx::Result<()> {
   let mut executor = wtx_instances::executor_postgres(&uri).await?;
   executor
     .transaction(|this| async {
-      this.execute("CREATE TABLE IF NOT EXISTS example(id INT, name VARCHAR)", |_| {}).await?;
+      this.execute("CREATE TABLE IF NOT EXISTS example(id INT, name VARCHAR)", |_| Ok(())).await?;
       this
         .execute_with_stmt("INSERT INTO foo VALUES ($1, $2), ($3, $4)", (1u32, "one", 2u32, "two"))
         .await?;
diff --git a/wtx-instances/generic-examples/client-api-framework.rs b/wtx-instances/generic-examples/client-api-framework.rs
index b5379d8f..0bcce441 100644
--- a/wtx-instances/generic-examples/client-api-framework.rs
+++ b/wtx-instances/generic-examples/client-api-framework.rs
@@ -15,9 +15,9 @@ use core::time::Duration;
 use tokio::net::TcpStream;
 use wtx::{
   client_api_framework::{
-    misc::{Pair, RequestLimit, RequestThrottling},
-    network::{transport::SendingReceivingTransport, HttpParams, WsParams},
     Api,
+    misc::{Pair, RequestLimit, RequestThrottling},
+    network::{HttpParams, WsParams, transport::SendingReceivingTransport},
   },
   data_transformation::dnsn::SerdeJson,
   http::client_pool::{ClientPoolBuilder, ClientPoolTokio},
@@ -81,8 +81,8 @@ mod generic_web_socket_subscription {
   pub type GenericWebSocketSubscriptionRes = u64;
 }
 
-async fn http_pair(
-) -> Pair<PkgsAux<GenericThrottlingApi, SerdeJson, HttpParams>, ClientPoolTokio<fn()>> {
+async fn http_pair()
+-> Pair<PkgsAux<GenericThrottlingApi, SerdeJson, HttpParams>, ClientPoolTokio<fn()>> {
   Pair::new(
     PkgsAux::from_minimum(
       GenericThrottlingApi {
@@ -122,7 +122,7 @@ async fn main() -> wtx::Result<()> {
   let mut hp = http_pair().await;
   let _http_response_tuple = hp
     .trans
-    .send_recv_decode_contained(
+    .send_pkg_recv_decode_contained(
       &mut hp.pkgs_aux.generic_http_request().data(123).build(),
       &mut hp.pkgs_aux,
     )
@@ -132,7 +132,7 @@ async fn main() -> wtx::Result<()> {
   let mut wsp = web_socket_pair().await?;
   let _web_socket_subscription_id = wsp
     .trans
-    .send_recv_decode_contained(
+    .send_pkg_recv_decode_contained(
       &mut wsp.pkgs_aux.generic_web_socket_subscription().data("Hello", None).build(),
       &mut wsp.pkgs_aux,
     )
diff --git a/wtx-instances/generic-examples/grpc-client.rs b/wtx-instances/generic-examples/grpc-client.rs
index c9a545d6..92b2e42d 100644
--- a/wtx-instances/generic-examples/grpc-client.rs
+++ b/wtx-instances/generic-examples/grpc-client.rs
@@ -10,8 +10,8 @@ extern crate wtx_instances;
 use std::borrow::Cow;
 use wtx::{
   data_transformation::dnsn::QuickProtobuf,
-  grpc::Client,
-  http::{client_pool::ClientPoolBuilder, ReqResBuffer, ReqResData},
+  grpc::GrpcClient,
+  http::{ReqResBuffer, ReqResData, client_pool::ClientPoolBuilder},
 };
 use wtx_instances::grpc_bindings::wtx::{GenericRequest, GenericResponse};
 
@@ -25,7 +25,7 @@ async fn main() -> wtx::Result<()> {
   let uri_ref = rrb.uri.to_ref();
   let pool = ClientPoolBuilder::tokio(1).build();
   let mut guard = pool.lock(&uri_ref).await?;
-  let mut client = Client::new(&mut guard.client, QuickProtobuf);
+  let mut client = GrpcClient::new(&mut guard.client, QuickProtobuf);
   let res = client
     .send_unary_req(
       ("wtx", "GenericService", "generic_method"),
@@ -36,7 +36,8 @@ async fn main() -> wtx::Result<()> {
       rrb,
     )
     .await?;
-  let generic_response: GenericResponse = client.des_from_res_bytes(res.rrd.body())?;
+  let generic_response: GenericResponse =
+    client.des_from_res_bytes(&mut res.rrd.body().as_ref())?;
   println!("{:?}", generic_response);
   Ok(())
 }
diff --git a/wtx-instances/generic-examples/grpc-server.rs b/wtx-instances/generic-examples/grpc-server.rs
index 29450de8..c453ae6b 100644
--- a/wtx-instances/generic-examples/grpc-server.rs
+++ b/wtx-instances/generic-examples/grpc-server.rs
@@ -10,10 +10,10 @@ use wtx::{
   data_transformation::dnsn::QuickProtobuf,
   grpc::{GrpcManager, GrpcMiddleware},
   http::{
-    server_framework::{post, Router, ServerFrameworkBuilder, State},
     ReqResBuffer, StatusCode,
+    server_framework::{Router, ServerFrameworkBuilder, State, post},
   },
-  misc::{simple_seed, Xorshift64},
+  misc::{Xorshift64, simple_seed},
 };
 use wtx_instances::grpc_bindings::wtx::{GenericRequest, GenericResponse};
 
@@ -39,7 +39,7 @@ async fn wtx_generic_service_generic_method(
   state: State<'_, (), GrpcManager<QuickProtobuf>, ReqResBuffer>,
 ) -> wtx::Result<StatusCode> {
   let _generic_request: GenericRequest =
-    state.stream_aux.des_from_req_bytes(&state.req.rrd.body)?;
+    state.stream_aux.des_from_req_bytes(&mut state.req.rrd.body.as_ref())?;
   state.req.rrd.clear();
   state.stream_aux.ser_to_res_bytes(
     &mut state.req.rrd.body,
diff --git a/wtx-instances/generic-examples/http-client-pool.rs b/wtx-instances/generic-examples/http-client-pool.rs
index c9f4c2e9..7df89429 100644
--- a/wtx-instances/generic-examples/http-client-pool.rs
+++ b/wtx-instances/generic-examples/http-client-pool.rs
@@ -9,15 +9,19 @@ extern crate wtx;
 extern crate wtx_instances;
 
 use wtx::{
-  http::{client_pool::ClientPoolBuilder, ReqBuilder, ReqResBuffer},
-  misc::{from_utf8_basic, Uri},
+  http::{HttpClient, Method, ReqResBuffer, client_pool::ClientPoolBuilder},
+  misc::{Uri, from_utf8_basic},
 };
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  let uri = Uri::new("http://www.example.com");
-  let res = ReqBuilder::get(ReqResBuffer::empty())
-    .send(&mut ClientPoolBuilder::tokio(1).build().lock(&uri).await?.client, &uri)
+  let uri = Uri::new("SOME_URI");
+  let res = ClientPoolBuilder::tokio(1)
+    .build()
+    .lock(&uri)
+    .await?
+    .client
+    .send_recv_single(Method::Get, &uri, ReqResBuffer::empty())
     .await?;
   println!("{}", from_utf8_basic(&res.rrd.body)?);
   Ok(())
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs b/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs
index f003f7b8..3ac06554 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs
@@ -1,8 +1,8 @@
 //! The `CorsMiddleware` middleware inserts permissive CORS headers in every response.
 
 use wtx::{
-  http::server_framework::{get, CorsMiddleware, Router, ServerFrameworkBuilder},
-  misc::{simple_seed, Xorshift64},
+  http::server_framework::{CorsMiddleware, Router, ServerFrameworkBuilder, get},
+  misc::{Xorshift64, simple_seed},
 };
 
 #[tokio::main]
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs b/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs
index 583b7a6c..b9f9a80b 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs
@@ -2,10 +2,10 @@
 
 use wtx::{
   http::{
-    server_framework::{get, Redirect, Router, ServerFrameworkBuilder, StateClean},
     ReqResBuffer, StatusCode,
+    server_framework::{Redirect, Router, ServerFrameworkBuilder, StateClean, get},
   },
-  misc::{simple_seed, Xorshift64},
+  misc::{Xorshift64, simple_seed},
 };
 
 #[tokio::main]
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework-session.rs b/wtx-instances/http-server-framework-examples/http-server-framework-session.rs
index 0dae349c..2c032cf2 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework-session.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework-session.rs
@@ -21,15 +21,15 @@
 //! ALTER TABLE "session" ADD CONSTRAINT session__user__fk FOREIGN KEY (user_id) REFERENCES "user" (id);
 //! ```
 
-use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng};
+use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng};
 use tokio::net::TcpStream;
 use wtx::{
   database::{Executor, Record},
   http::{
-    server_framework::{get, post, Router, ServerFrameworkBuilder, State, StateClean},
     ReqResBuffer, ReqResData, SessionDecoder, SessionManagerTokio, SessionState, StatusCode,
+    server_framework::{Router, ServerFrameworkBuilder, State, StateClean, get, post},
   },
-  misc::{argon2_pwd, Vector},
+  misc::{Vector, argon2_pwd},
   pool::{PostgresRM, SimplePoolTokio},
 };
 
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework.rs b/wtx-instances/http-server-framework-examples/http-server-framework.rs
index e2f02459..2ee00f56 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework.rs
@@ -11,17 +11,17 @@ extern crate wtx;
 extern crate wtx_instances;
 
 use core::{fmt::Write, ops::ControlFlow};
-use tokio::net::{tcp::OwnedWriteHalf, TcpStream};
+use tokio::net::{TcpStream, tcp::OwnedWriteHalf};
 use wtx::{
   database::{Executor, Record},
   http::{
+    ManualStream, ReqResBuffer, Request, Response, StatusCode,
     server_framework::{
-      get, post, Middleware, PathOwned, Router, SerdeJson, ServerFrameworkBuilder, StateClean,
+      Middleware, PathOwned, Router, SerdeJson, ServerFrameworkBuilder, StateClean, get, post,
     },
-    ManualStream, ReqResBuffer, Request, Response, StatusCode,
   },
   http2::{Http2Buffer, Http2DataTokio, Http2ErrorCode, ServerStream},
-  misc::{simple_seed, Xorshift64},
+  misc::{Xorshift64, simple_seed},
   pool::{PostgresRM, SimplePoolTokio},
 };
 
diff --git a/wtx-instances/http2-examples/http2-client.rs b/wtx-instances/http2-examples/http2-client.rs
index 61abb1cc..dae8cb0d 100644
--- a/wtx-instances/http2-examples/http2-client.rs
+++ b/wtx-instances/http2-examples/http2-client.rs
@@ -10,12 +10,12 @@ use tokio::net::TcpStream;
 use wtx::{
   http::{Method, ReqResBuffer, Request},
   http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2Tokio},
-  misc::{from_utf8_basic, simple_seed, Uri, Xorshift64},
+  misc::{Uri, Xorshift64, from_utf8_basic, simple_seed},
 };
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  let uri = Uri::new("http://www.example.com");
+  let uri = Uri::new("SOME_URI");
   let (frame_reader, mut http2) = Http2Tokio::connect(
     Http2Buffer::new(Xorshift64::from(simple_seed())),
     Http2Params::default(),
diff --git a/wtx-instances/http2-examples/http2-web-socket.rs b/wtx-instances/http2-examples/http2-server-web-socket.rs
similarity index 94%
rename from wtx-instances/http2-examples/http2-web-socket.rs
rename to wtx-instances/http2-examples/http2-server-web-socket.rs
index e631dccd..02ec41e5 100644
--- a/wtx-instances/http2-examples/http2-web-socket.rs
+++ b/wtx-instances/http2-examples/http2-server-web-socket.rs
@@ -10,9 +10,9 @@ extern crate wtx_instances;
 use core::mem;
 use tokio::net::TcpListener;
 use wtx::{
-  http::{is_web_socket_handshake, Headers, ReqResBuffer},
+  http::{Headers, ReqResBuffer, is_web_socket_handshake},
   http2::{Http2Buffer, Http2Params, Http2Tokio, WebSocketOverStream},
-  misc::{simple_seed, Either, TokioRustlsAcceptor, Vector, Xorshift64},
+  misc::{Either, TokioRustlsAcceptor, Vector, Xorshift64, simple_seed},
   web_socket::{Frame, OpCode},
 };
 
diff --git a/wtx-instances/http2-examples/http2-server.rs b/wtx-instances/http2-examples/http2-server.rs
index 2734a2e3..bd1d3278 100644
--- a/wtx-instances/http2-examples/http2-server.rs
+++ b/wtx-instances/http2-examples/http2-server.rs
@@ -9,11 +9,11 @@ use tokio::{io::WriteHalf, net::TcpStream};
 use tokio_rustls::server::TlsStream;
 use wtx::{
   http::{
-    is_web_socket_handshake, AutoStream, ManualServerStreamTokio, OperationMode, OptionedServer,
-    ReqResBuffer, Response, StatusCode,
+    AutoStream, ManualServerStreamTokio, OperationMode, OptionedServer, ReqResBuffer, Response,
+    StatusCode, is_web_socket_handshake,
   },
   http2::{Http2Buffer, Http2Params, WebSocketOverStream},
-  misc::{simple_seed, TokioRustlsAcceptor, Vector, Xorshift64},
+  misc::{TokioRustlsAcceptor, Vector, Xorshift64, simple_seed},
   web_socket::{Frame, OpCode},
 };
 
diff --git a/wtx-instances/src/bin/autobahn-client.rs b/wtx-instances/src/bin/autobahn-client.rs
index b19d114e..1f46bc42 100644
--- a/wtx-instances/src/bin/autobahn-client.rs
+++ b/wtx-instances/src/bin/autobahn-client.rs
@@ -3,7 +3,7 @@
 use tokio::net::TcpStream;
 use wtx::{
   misc::UriRef,
-  web_socket::{compression::Flate2, Frame, OpCode, WebSocketConnector},
+  web_socket::{Frame, OpCode, WebSocketConnector, compression::Flate2},
 };
 
 #[tokio::main]
diff --git a/wtx-instances/src/bin/autobahn-server.rs b/wtx-instances/src/bin/autobahn-server.rs
index ae0c6695..1ab14ed0 100644
--- a/wtx-instances/src/bin/autobahn-server.rs
+++ b/wtx-instances/src/bin/autobahn-server.rs
@@ -6,8 +6,8 @@ use tokio::net::TcpStream;
 use wtx::{
   http::OptionedServer,
   web_socket::{
-    compression::{Flate2, NegotiatedFlate2},
     OpCode, WebSocket, WebSocketBuffer,
+    compression::{Flate2, NegotiatedFlate2},
   },
 };
 
diff --git a/wtx-instances/src/bin/h2load.rs b/wtx-instances/src/bin/h2load.rs
index 73a0194f..fb6a9b78 100644
--- a/wtx-instances/src/bin/h2load.rs
+++ b/wtx-instances/src/bin/h2load.rs
@@ -9,7 +9,7 @@ use wtx::{
     StatusCode,
   },
   http2::{Http2Buffer, Http2Params},
-  misc::{simple_seed, Xorshift64},
+  misc::{Xorshift64, simple_seed},
 };
 
 #[tokio::main]
diff --git a/wtx-instances/src/bin/h2spec-high-server.rs b/wtx-instances/src/bin/h2spec-high-server.rs
index b2637a31..27368c5f 100644
--- a/wtx-instances/src/bin/h2spec-high-server.rs
+++ b/wtx-instances/src/bin/h2spec-high-server.rs
@@ -9,7 +9,7 @@ use wtx::{
     StatusCode,
   },
   http2::{Http2Buffer, Http2Params},
-  misc::{simple_seed, Xorshift64},
+  misc::{Xorshift64, simple_seed},
 };
 
 #[tokio::main]
diff --git a/wtx-instances/src/bin/h2spec-low-server.rs b/wtx-instances/src/bin/h2spec-low-server.rs
index 79ef729a..beec75bf 100644
--- a/wtx-instances/src/bin/h2spec-low-server.rs
+++ b/wtx-instances/src/bin/h2spec-low-server.rs
@@ -7,7 +7,7 @@ use tokio::net::TcpListener;
 use wtx::{
   http::{ReqResBuffer, StatusCode},
   http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2RecvStatus, Http2Tokio, SendDataMode},
-  misc::{simple_seed, Either, Xorshift64},
+  misc::{Either, Xorshift64, simple_seed},
 };
 
 #[tokio::main]
diff --git a/wtx-instances/src/lib.rs b/wtx-instances/src/lib.rs
index e3f8faa6..f1a87395 100644
--- a/wtx-instances/src/lib.rs
+++ b/wtx-instances/src/lib.rs
@@ -18,13 +18,10 @@
 #[cfg(feature = "grpc")]
 pub mod grpc_bindings;
 
-#[cfg(feature = "postgres")]
+#[cfg(any(feature = "mysql", feature = "postgres"))]
 use {
   tokio::net::TcpStream,
-  wtx::{
-    database::client::postgres::{Config, Executor, ExecutorBuffer},
-    misc::{simple_seed, Uri, Xorshift64},
-  },
+  wtx::misc::{Uri, Xorshift64, simple_seed},
 };
 
 /// Certificate
@@ -34,16 +31,43 @@ pub static KEY: &[u8] = include_bytes!("../../.certs/key.pem");
 /// Root CA
 pub static ROOT_CA: &[u8] = include_bytes!("../../.certs/root-ca.crt");
 
+#[cfg(feature = "mysql")]
+#[inline]
+pub async fn executor_mysql(
+  uri_str: &str,
+) -> wtx::Result<
+  wtx::database::client::mysql::MysqlExecutor<
+    wtx::Error,
+    wtx::database::client::mysql::ExecutorBuffer,
+    TcpStream,
+  >,
+> {
+  let uri = Uri::new(uri_str);
+  let mut rng = Xorshift64::from(simple_seed());
+  wtx::database::client::mysql::MysqlExecutor::connect(
+    &wtx::database::client::mysql::Config::from_uri(&uri)?,
+    wtx::database::client::mysql::ExecutorBuffer::new(usize::MAX, &mut rng),
+    TcpStream::connect(uri.hostname_with_implied_port()).await?,
+  )
+  .await
+}
+
 #[cfg(feature = "postgres")]
 #[inline]
 pub async fn executor_postgres(
   uri_str: &str,
-) -> wtx::Result<Executor<wtx::Error, ExecutorBuffer, TcpStream>> {
+) -> wtx::Result<
+  wtx::database::client::postgres::PostgresExecutor<
+    wtx::Error,
+    wtx::database::client::postgres::ExecutorBuffer,
+    TcpStream,
+  >,
+> {
   let uri = Uri::new(uri_str);
   let mut rng = Xorshift64::from(simple_seed());
-  Executor::connect(
-    &Config::from_uri(&uri)?,
-    ExecutorBuffer::new(usize::MAX, &mut rng),
+  wtx::database::client::postgres::PostgresExecutor::connect(
+    &wtx::database::client::postgres::Config::from_uri(&uri)?,
+    wtx::database::client::postgres::ExecutorBuffer::new(usize::MAX, &mut rng),
     &mut rng,
     TcpStream::connect(uri.hostname_with_implied_port()).await?,
   )
diff --git a/wtx-instances/web-socket-examples/web-socket-concurrent-client.rs b/wtx-instances/web-socket-examples/web-socket-client-concurrent.rs
similarity index 96%
rename from wtx-instances/web-socket-examples/web-socket-concurrent-client.rs
rename to wtx-instances/web-socket-examples/web-socket-client-concurrent.rs
index 443cdbf4..4efe69e0 100644
--- a/wtx-instances/web-socket-examples/web-socket-concurrent-client.rs
+++ b/wtx-instances/web-socket-examples/web-socket-client-concurrent.rs
@@ -12,7 +12,7 @@ use wtx::{
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  let uri = Uri::new("wss://www.example.com");
+  let uri = Uri::new("SOME_TLS_URI");
   let tls_connector = TokioRustlsConnector::from_auto()?.push_certs(wtx_instances::ROOT_CA)?;
   let stream = TcpStream::connect(uri.hostname_with_implied_port()).await?;
   let ws = WebSocketConnector::default()
diff --git a/wtx-instances/web-socket-examples/web-socket-client.rs b/wtx-instances/web-socket-examples/web-socket-client.rs
index 52fae7a1..42677610 100644
--- a/wtx-instances/web-socket-examples/web-socket-client.rs
+++ b/wtx-instances/web-socket-examples/web-socket-client.rs
@@ -18,7 +18,7 @@ use wtx::{
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  let uri = Uri::new("ws://www.example.com");
+  let uri = Uri::new("SOME_URI");
   let mut ws = WebSocketConnector::default()
     .connect(TcpStream::connect(uri.hostname_with_implied_port()).await?, &uri.to_ref())
     .await?;
diff --git a/wtx-macros/Cargo.toml b/wtx-macros/Cargo.toml
index 080b2b48..c8684223 100644
--- a/wtx-macros/Cargo.toml
+++ b/wtx-macros/Cargo.toml
@@ -16,7 +16,7 @@ proc-macro = true
 [package]
 categories = ["asynchronous", "data-structures", "network-programming"]
 description = "Procedural macros for wtx"
-edition = "2021"
+edition = "2024"
 exclude = ["tests"]
 keywords = ["api", "client", "io", "network"]
 license = "MPL-2.0"
diff --git a/wtx-macros/src/client_api_framework/api.rs b/wtx-macros/src/client_api_framework/api.rs
index 6bd1c0b7..42ca9e25 100644
--- a/wtx-macros/src/client_api_framework/api.rs
+++ b/wtx-macros/src/client_api_framework/api.rs
@@ -8,8 +8,8 @@ use crate::{
 use proc_macro2::{Ident, Span};
 use quote::ToTokens as _;
 use syn::{
-  parse_macro_input, punctuated::Punctuated, spanned::Spanned as _, AttributeArgs, Item, Path,
-  PathArguments, PathSegment,
+  AttributeArgs, Item, Path, PathArguments, PathSegment, parse_macro_input, punctuated::Punctuated,
+  spanned::Spanned as _,
 };
 
 pub(crate) fn api(
diff --git a/wtx-macros/src/client_api_framework/api/attrs.rs b/wtx-macros/src/client_api_framework/api/attrs.rs
index b4326e3b..ba1a87ee 100644
--- a/wtx-macros/src/client_api_framework/api/attrs.rs
+++ b/wtx-macros/src/client_api_framework/api/attrs.rs
@@ -67,9 +67,5 @@ fn first_nested_meta_path(meta_list: &MetaList) -> Option<&Path> {
   let Some(NestedMeta::Meta(meta)) = meta_list.nested.first() else {
     return None;
   };
-  if let Meta::Path(elem) = meta {
-    Some(elem)
-  } else {
-    None
-  }
+  if let Meta::Path(elem) = meta { Some(elem) } else { None }
 }
diff --git a/wtx-macros/src/client_api_framework/pkg.rs b/wtx-macros/src/client_api_framework/pkg.rs
index 8f35bbbc..54c8724c 100644
--- a/wtx-macros/src/client_api_framework/pkg.rs
+++ b/wtx-macros/src/client_api_framework/pkg.rs
@@ -23,10 +23,9 @@ use proc_macro2::{Ident, Span, TokenStream};
 use quote::ToTokens as _;
 use sir::{sir_final_values::SirFinalValues, sir_pkg_attr::SirPkaAttr};
 use syn::{
-  parse_macro_input,
+  AttributeArgs, Generics, Item, ItemMod, ItemType, VisPublic, Visibility, parse_macro_input,
   punctuated::Punctuated,
   token::{Eq, Pub, Semi, Type},
-  AttributeArgs, Generics, Item, ItemMod, ItemType, VisPublic, Visibility,
 };
 
 pub(crate) fn pkg(
diff --git a/wtx-macros/src/client_api_framework/pkg/data_format.rs b/wtx-macros/src/client_api_framework/pkg/data_format.rs
index 6a4ad2cd..749d495f 100644
--- a/wtx-macros/src/client_api_framework/pkg/data_format.rs
+++ b/wtx-macros/src/client_api_framework/pkg/data_format.rs
@@ -10,6 +10,7 @@ pub(crate) enum DataFormat {
   Json,
   JsonRpc(String),
   Protobuf,
+  Urlencoded,
   Verbatim,
 }
 
@@ -44,6 +45,7 @@ impl DataFormat {
       DataFormat::Json => rslt!(http_mime_type!(ApplicationJson)),
       DataFormat::JsonRpc(_) => rslt!(http_method_and_mime_type!(Post, ApplicationJson)),
       DataFormat::Protobuf => rslt!(http_mime_type!(ApplicationVndGoogleProtobuf)),
+      DataFormat::Urlencoded => rslt!(http_mime_type!(ApplicationXWwwFormUrlEncoded)),
       _ => TokenStream::new(),
     }
   }
@@ -75,6 +77,12 @@ impl DataFormat {
         dfe_ext_res_ctnt_wrapper: ident_fn("VerbatimResponse"),
         dfe_pkgs_aux_call: quote::quote!(verbatim_request(data)),
       },
+      DataFormat::Urlencoded => DataFormatElems {
+        dfe_data_format_builder_fn: ident_fn("build_urlencoded"),
+        dfe_ext_req_ctnt_wrapper: ident_fn("VerbatimRequest"),
+        dfe_ext_res_ctnt_wrapper: ident_fn("VerbatimResponse"),
+        dfe_pkgs_aux_call: quote::quote!(verbatim_request(data)),
+      },
       DataFormat::Verbatim => DataFormatElems {
         dfe_data_format_builder_fn: ident_fn("build_verbatim"),
         dfe_ext_req_ctnt_wrapper: ident_fn("VerbatimRequest"),
@@ -117,6 +125,7 @@ impl<'attrs> TryFrom<&'attrs NestedMeta> for DataFormat {
         "borsh" => Ok(Self::Borsh),
         "json" => Ok(Self::Json),
         "protobuf" => Ok(Self::Protobuf),
+        "urlencoded" => Ok(Self::Urlencoded),
         "verbatim" => Ok(Self::Verbatim),
         _ => Err(crate::Error::UnknownDataFormat),
       }
diff --git a/wtx-macros/src/client_api_framework/pkg/fir/fir_aux_item_values.rs b/wtx-macros/src/client_api_framework/pkg/fir/fir_aux_item_values.rs
index 28af4dd2..3deb8639 100644
--- a/wtx-macros/src/client_api_framework/pkg/fir/fir_aux_item_values.rs
+++ b/wtx-macros/src/client_api_framework/pkg/fir/fir_aux_item_values.rs
@@ -7,8 +7,8 @@ use crate::{
 };
 use proc_macro2::Span;
 use syn::{
-  punctuated::Punctuated, GenericParam, ImplItem, ImplItemMethod, Item, Token, Type, Visibility,
-  WherePredicate,
+  GenericParam, ImplItem, ImplItemMethod, Item, Token, Type, Visibility, WherePredicate,
+  punctuated::Punctuated,
 };
 
 #[derive(Debug)]
diff --git a/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_field_field_attr.rs b/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_field_field_attr.rs
index be542fae..9808256c 100644
--- a/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_field_field_attr.rs
+++ b/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_field_field_attr.rs
@@ -1,8 +1,8 @@
 use crate::client_api_framework::pkg::keywords;
 use proc_macro2::Ident;
 use syn::{
-  parse::{Parse, ParseStream},
   LitStr, Token,
+  parse::{Parse, ParseStream},
 };
 
 #[derive(Debug)]
diff --git a/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_item_values.rs b/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_item_values.rs
index badae18f..7d1fe9ce 100644
--- a/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_item_values.rs
+++ b/wtx-macros/src/client_api_framework/pkg/fir/fir_custom_item_values.rs
@@ -1,7 +1,7 @@
 use crate::client_api_framework::pkg::{
   enum_struct_or_type::EnumStructOrType, fir::fir_custom_field_field_attr::FirCustomFieldFieldAttr,
 };
-use syn::{punctuated::Punctuated, GenericParam, Ident, Token, Type, WherePredicate};
+use syn::{GenericParam, Ident, Token, Type, WherePredicate, punctuated::Punctuated};
 
 #[derive(Clone, Copy, Debug)]
 pub(crate) struct FirCustomItemValuesRef<'any, 'module> {
diff --git a/wtx-macros/src/client_api_framework/pkg/fir/fir_hook_item_values.rs b/wtx-macros/src/client_api_framework/pkg/fir/fir_hook_item_values.rs
index ddaa45b9..1133d336 100644
--- a/wtx-macros/src/client_api_framework/pkg/fir/fir_hook_item_values.rs
+++ b/wtx-macros/src/client_api_framework/pkg/fir/fir_hook_item_values.rs
@@ -13,7 +13,7 @@ macro_rules! create_fir_hook_item_values {
     };
     use proc_macro2::TokenStream;
     use syn::{
-      punctuated::Punctuated, FnArg, GenericParam, Item, ItemFn, Pat, Token, WherePredicate,
+      FnArg, GenericParam, Item, ItemFn, Pat, Token, WherePredicate, punctuated::Punctuated,
     };
 
     pub(crate) struct $struct<'module> {
diff --git a/wtx-macros/src/client_api_framework/pkg/fir/fir_pkg_attr.rs b/wtx-macros/src/client_api_framework/pkg/fir/fir_pkg_attr.rs
index 552e9f0c..3c332089 100644
--- a/wtx-macros/src/client_api_framework/pkg/fir/fir_pkg_attr.rs
+++ b/wtx-macros/src/client_api_framework/pkg/fir/fir_pkg_attr.rs
@@ -1,4 +1,4 @@
-use syn::{punctuated::Punctuated, Meta, MetaList, NestedMeta, Path, Token};
+use syn::{Meta, MetaList, NestedMeta, Path, Token, punctuated::Punctuated};
 
 const EMPTY_NESTED_META: &Punctuated<NestedMeta, Token![,]> = &Punctuated::new();
 
@@ -48,9 +48,5 @@ fn first_nested_meta_path(meta_list: &MetaList) -> Option<&Path> {
   let Some(NestedMeta::Meta(meta)) = meta_list.nested.first() else {
     return None;
   };
-  if let Meta::Path(elem) = meta {
-    Some(elem)
-  } else {
-    None
-  }
+  if let Meta::Path(elem) = meta { Some(elem) } else { None }
 }
diff --git a/wtx-macros/src/client_api_framework/pkg/misc.rs b/wtx-macros/src/client_api_framework/pkg/misc.rs
index b60ff680..1eb08203 100644
--- a/wtx-macros/src/client_api_framework/pkg/misc.rs
+++ b/wtx-macros/src/client_api_framework/pkg/misc.rs
@@ -1,9 +1,9 @@
 use proc_macro2::Span;
 use quote::ToTokens as _;
 use syn::{
-  parse::Parse, punctuated::Punctuated, spanned::Spanned as _, token::Paren,
   AngleBracketedGenericArguments, Attribute, GenericArgument, GenericParam, PathArguments,
-  PathSegment, Token, Type, TypePath, TypeTuple,
+  PathSegment, Token, Type, TypePath, TypeTuple, parse::Parse, punctuated::Punctuated,
+  spanned::Spanned as _, token::Paren,
 };
 
 pub(crate) const EMPTY_GEN_ARGS: &Punctuated<GenericArgument, Token![,]> = &Punctuated::new();
@@ -70,11 +70,7 @@ pub(crate) fn is_unit_type(ty_tuple: &TypeTuple) -> bool {
 }
 
 pub(crate) fn manage_unique_attribute<T>(opt: Option<&T>, span: Span) -> crate::Result<()> {
-  if opt.is_some() {
-    Err(crate::Error::DuplicatedGlobalPkgAttr(span))
-  } else {
-    Ok(())
-  }
+  if opt.is_some() { Err(crate::Error::DuplicatedGlobalPkgAttr(span)) } else { Ok(()) }
 }
 
 pub(crate) fn split_params(
diff --git a/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values.rs b/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values.rs
index a25fc53f..cf32a14a 100644
--- a/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values.rs
+++ b/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values.rs
@@ -7,15 +7,15 @@ use crate::{
       fir_aux_item_values::FirAuxItemValues, fir_custom_item_values::FirCustomItemValuesRef,
       fir_params_items_values::FirParamsItemValues, fir_req_item_values::FirReqItemValues,
     },
-    misc::{from_camel_case_to_snake_case, split_params, EMPTY_GEN_PARAMS},
+    misc::{EMPTY_GEN_PARAMS, from_camel_case_to_snake_case, split_params},
     sir::sir_pkg_attr::SirPkaAttr,
   },
   misc::{create_ident, extend_with_tmp_suffix},
 };
 use proc_macro2::{Ident, Span, TokenStream};
 use syn::{
-  punctuated::Punctuated, GenericArgument, GenericParam, ImplItemMethod, PathSegment, Token,
-  WherePredicate,
+  GenericArgument, GenericParam, ImplItemMethod, PathSegment, Token, WherePredicate,
+  punctuated::Punctuated,
 };
 
 pub(crate) struct SirAuxItemValues {
diff --git a/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_creators.rs b/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_creators.rs
index e2435c14..b4e40b90 100644
--- a/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_creators.rs
+++ b/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_creators.rs
@@ -3,7 +3,7 @@ use crate::{
     enum_struct_or_type::EnumStructOrType,
     fir::{fir_aux_item_values::FirAuxItemValues, fir_custom_item_values::FirCustomItemValuesRef},
     misc::{
-      inner_angle_bracketed_values, is_unit_type, split_params, EMPTY_GEN_ARGS, EMPTY_PATH_SEGS,
+      EMPTY_GEN_ARGS, EMPTY_PATH_SEGS, inner_angle_bracketed_values, is_unit_type, split_params,
     },
     sir::sir_aux_item_values::{
       BuilderCommonValues, BuilderExtendedValues, CreateMethodReturningBuilderParams,
@@ -132,11 +132,7 @@ impl SirAuxItemValues {
     let (fn_params, fn_where_predicates) = parts_from_generics(&iim.sig.generics);
     let fn_args_iter_fn = || {
       iim.sig.inputs.iter().filter_map(|fn_arg| {
-        if let FnArg::Typed(pat_type) = fn_arg {
-          Some(pat_type)
-        } else {
-          None
-        }
+        if let FnArg::Typed(pat_type) = fn_arg { Some(pat_type) } else { None }
       })
     };
 
diff --git a/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_pushers.rs b/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_pushers.rs
index d8dc59f3..4d30b8e7 100644
--- a/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_pushers.rs
+++ b/wtx-macros/src/client_api_framework/pkg/sir/sir_aux_item_values/sir_items_values_pushers.rs
@@ -14,7 +14,7 @@ use crate::{
   misc::EMPTY_WHERE_PREDS,
 };
 use proc_macro2::{Ident, Span, TokenStream};
-use syn::{punctuated::Punctuated, GenericParam, Lifetime, LifetimeDef};
+use syn::{GenericParam, Lifetime, LifetimeDef, punctuated::Punctuated};
 
 impl SirAuxItemValues {
   pub(super) fn push_builder_method_returning_builder(
diff --git a/wtx-macros/src/client_api_framework/pkg/sir/sir_final_values.rs b/wtx-macros/src/client_api_framework/pkg/sir/sir_final_values.rs
index d70ec9ed..e6604a9a 100644
--- a/wtx-macros/src/client_api_framework/pkg/sir/sir_final_values.rs
+++ b/wtx-macros/src/client_api_framework/pkg/sir/sir_final_values.rs
@@ -141,17 +141,13 @@ impl<'attrs, 'module, 'others>
         let is_mut_lf = is_mut.then(|| quote::quote! { '__is_mut }).into_iter();
         let tp = {
           let tt = Self::transport_params(transport_group);
-          if is_mut {
-            quote::quote!(&'__is_mut mut #tt)
-          } else {
-            tt
-          }
+          if is_mut { quote::quote!(&'__is_mut mut #tt) } else { tt }
         };
         package_impls.push(quote::quote!(
           impl<
             #(#is_mut_lf,)* #(#lts,)* #(#tys,)* __API, __DRSR, __TRANSPORT
           > wtx::client_api_framework::pkg::Package<
-          __API, __DRSR, __TRANSPORT, #tp
+            __API, __DRSR, __TRANSPORT, #tp
           > for #camel_case_pkg_ident<
             #(#fpiv_params_iter0,)*
             wtx::data_transformation::format::#dfe_ext_req_ctnt_wrapper<#freqdiv_ident<#freqdiv_params>>
@@ -163,10 +159,10 @@ impl<'attrs, 'module, 'others>
             #(#freqdiv_where_predicates_iter,)*
             wtx::data_transformation::format::#dfe_ext_req_ctnt_wrapper<
               #freqdiv_ident<#freqdiv_params>
-            >: wtx::data_transformation::dnsn::Serialize<__DRSR>,
+            >: wtx::misc::Encode<wtx::data_transformation::dnsn::De<__DRSR>>,
             for<'__de> wtx::data_transformation::format::#dfe_ext_res_ctnt_wrapper<
               #fresdiv_ident<#(#res_lf_iter0)*>
-            >: wtx::data_transformation::dnsn::Deserialize<'__de, __DRSR>,
+            >: wtx::misc::DecodeSeq<'__de, wtx::data_transformation::dnsn::De<__DRSR>>,
             __API: wtx::client_api_framework::Api<
               Error = <<#id as wtx::client_api_framework::ApiId>::Api as wtx::client_api_framework::Api>::Error,
               Id = #id
diff --git a/wtx-macros/src/client_api_framework/transport_group.rs b/wtx-macros/src/client_api_framework/transport_group.rs
index 6f09feb6..aaad2d59 100644
--- a/wtx-macros/src/client_api_framework/transport_group.rs
+++ b/wtx-macros/src/client_api_framework/transport_group.rs
@@ -1,7 +1,7 @@
 use crate::misc::single_elem;
 use proc_macro2::{Span, TokenStream};
 use quote::ToTokens as _;
-use syn::{punctuated::Punctuated, Meta, NestedMeta, Path, PathSegment, Token};
+use syn::{Meta, NestedMeta, Path, PathSegment, Token, punctuated::Punctuated};
 
 #[derive(Debug)]
 pub(crate) enum TransportGroup {
diff --git a/wtx-macros/src/from_records.rs b/wtx-macros/src/from_records.rs
index b05155e0..8db808fd 100644
--- a/wtx-macros/src/from_records.rs
+++ b/wtx-macros/src/from_records.rs
@@ -4,10 +4,10 @@ mod keywords {
 
 use crate::misc::parts_from_generics;
 use syn::{
+  Data, DeriveInput, Fields, GenericParam, Ident, Path, Type,
   parse::{Parse, ParseStream},
   parse_macro_input,
   spanned::Spanned as _,
-  Data, DeriveInput, Fields, GenericParam, Ident, Path, Type,
 };
 
 pub(crate) fn from_records(
@@ -30,7 +30,7 @@ pub(crate) fn from_records(
   let additional_where_predicates = params.iter().filter_map(|el| {
     if let GenericParam::Type(type_param) = el {
       let ident = &type_param.ident;
-      Some(quote::quote! { #ident: wtx::database::Decode<'exec, #database>, })
+      Some(quote::quote! { #ident: wtx::misc::Decode<'exec, #database>, })
     } else {
       None
     }
diff --git a/wtx-macros/src/http.rs b/wtx-macros/src/http.rs
index 0f98935a..7a9c29f5 100644
--- a/wtx-macros/src/http.rs
+++ b/wtx-macros/src/http.rs
@@ -1,5 +1,5 @@
 use quote::quote;
-use syn::{parse_macro_input, Data, DeriveInput, Fields};
+use syn::{Data, DeriveInput, Fields, parse_macro_input};
 
 pub(crate) fn conn_aux(item: proc_macro::TokenStream) -> crate::Result<proc_macro::TokenStream> {
   let input = parse_macro_input::parse::<DeriveInput>(item)?;
diff --git a/wtx-macros/src/misc.rs b/wtx-macros/src/misc.rs
index 9af9a57b..727363ee 100644
--- a/wtx-macros/src/misc.rs
+++ b/wtx-macros/src/misc.rs
@@ -1,9 +1,9 @@
 use proc_macro2::{Ident, Span, TokenStream};
 use syn::{
-  punctuated::Punctuated,
-  token::{Bracket, Pound},
   AttrStyle, Attribute, GenericParam, Generics, Path, PathArguments, PathSegment, Token,
   WherePredicate,
+  punctuated::Punctuated,
+  token::{Bracket, Pound},
 };
 
 pub(crate) const EMPTY_WHERE_PREDS: &Punctuated<WherePredicate, Token![,]> = &Punctuated::new();
diff --git a/wtx-ui/Cargo.toml b/wtx-ui/Cargo.toml
index f31274ee..45d72091 100644
--- a/wtx-ui/Cargo.toml
+++ b/wtx-ui/Cargo.toml
@@ -20,7 +20,7 @@ authors = ["Caio Fernandes <c410.f3r@gmail.com>"]
 categories = ["asynchronous", "command-line-interface", "gui"]
 description = "Different user interfaces for WTX"
 documentation = "https://docs.rs/wtx-ui"
-edition = "2021"
+edition = "2024"
 keywords = ["io", "network", "websocket"]
 license = "MPL-2.0"
 name = "wtx-ui"
diff --git a/wtx-ui/src/http_client.rs b/wtx-ui/src/http_client.rs
index 42a9b1ed..81637c7e 100644
--- a/wtx-ui/src/http_client.rs
+++ b/wtx-ui/src/http_client.rs
@@ -1,8 +1,8 @@
 use crate::clap::HttpClient;
 use std::{fs::OpenOptions, io::Write};
 use wtx::{
-  http::{client_pool::ClientPoolBuilder, Header, KnownHeaderName, ReqBuilder, ReqResBuffer},
-  misc::{from_utf8_basic, str_split_once1, tracing_tree_init, Uri},
+  http::{Header, HttpClient as _, KnownHeaderName, ReqResBuffer, client_pool::ClientPoolBuilder},
+  misc::{Uri, from_utf8_basic, str_split_once1, tracing_tree_init},
 };
 
 pub(crate) async fn http_client(http_client: HttpClient) {
@@ -38,12 +38,13 @@ pub(crate) async fn http_client(http_client: HttpClient) {
   }
   let uri = Uri::new(uri);
   let uri_ref = uri.to_ref();
-  let res = ReqBuilder::get(rrb)
-    .method(method)
-    .send(
-      &mut ClientPoolBuilder::tokio_rustls(1).build().lock(&uri_ref).await.unwrap().client,
-      &uri_ref,
-    )
+  let res = ClientPoolBuilder::tokio_rustls(1)
+    .build()
+    .lock(&uri_ref)
+    .await
+    .unwrap()
+    .client
+    .send_recv_single(method, &uri_ref, rrb)
     .await
     .unwrap();
   if let Some(elem) = output {
diff --git a/wtx-ui/src/schema_manager.rs b/wtx-ui/src/schema_manager.rs
index ca726346..8611f963 100644
--- a/wtx-ui/src/schema_manager.rs
+++ b/wtx-ui/src/schema_manager.rs
@@ -3,11 +3,11 @@ use std::{borrow::Cow, env::current_dir, path::Path};
 use tokio::net::TcpStream;
 use wtx::{
   database::{
-    client::postgres::{Config, Executor, ExecutorBuffer},
-    schema_manager::{Commands, DbMigration, SchemaManagement, DEFAULT_CFG_FILE_NAME},
-    Database, Identifier, DEFAULT_URI_VAR,
+    DEFAULT_URI_VAR, Identifier,
+    client::postgres::{Config, ExecutorBuffer, PostgresExecutor},
+    schema_manager::{Commands, DEFAULT_CFG_FILE_NAME, DbMigration, SchemaManagement},
   },
-  misc::{simple_seed, UriRef, Vector, Xorshift64},
+  misc::{DEController, UriRef, Vector, Xorshift64, simple_seed},
 };
 
 pub(crate) async fn schema_manager(sm: SchemaManager) -> wtx::Result<()> {
@@ -22,7 +22,7 @@ pub(crate) async fn schema_manager(sm: SchemaManager) -> wtx::Result<()> {
   match uri.scheme() {
     "postgres" | "postgresql" => {
       let mut rng = Xorshift64::from(simple_seed());
-      let executor = Executor::connect(
+      let executor = PostgresExecutor::connect(
         &Config::from_uri(&uri)?,
         ExecutorBuffer::new(usize::MAX, &mut rng),
         &mut rng,
@@ -50,7 +50,7 @@ fn toml_file_path(sm: &SchemaManager) -> wtx::Result<Cow<'_, Path>> {
 async fn handle_commands<E>(
   executor: E,
   sm: &SchemaManager,
-) -> Result<(), <E::Database as Database>::Error>
+) -> Result<(), <E::Database as DEController>::Error>
 where
   E: SchemaManagement,
 {
diff --git a/wtx/Cargo.toml b/wtx/Cargo.toml
index bcc65c40..12da7b05 100644
--- a/wtx/Cargo.toml
+++ b/wtx/Cargo.toml
@@ -11,8 +11,6 @@ crypto-common = { default-features = false, optional = true, version = "0.1" }
 digest = { default-features = false, features = ["mac"], optional = true, version = "0.10" }
 embassy-net = { default-features = false, features = ["tcp"], optional = true, version = "0.5" }
 embassy-time = { default-features = false, optional = true, version = "0.3" }
-embedded-io-async = { default-features = false, optional = true, version = "0.6" }
-embedded-tls = { default-features = false, optional = true, version = "0.17" }
 fastrand = { default-features = false, optional = true, version = "2.0" }
 flate2 = { default-features = false, features = ["zlib-rs"], optional = true, version = "1.0" }
 foldhash = { default-features = false, optional = true, version = "0.1" }
@@ -22,17 +20,21 @@ hmac = { default-features = false, optional = true, version = "0.12" }
 httparse = { default-features = false, optional = true, version = "1.0" }
 matchit = { default-features = false, optional = true, version = "0.8" }
 memchr = { default-features = false, optional = true, version = "2.0" }
+num-bigint = { default-features = false, optional = true, version = "0.4" }
 portable-atomic = { default-features = false, features = ["fallback"], optional = true, version = "1.0" }
 portable-atomic-util = { default-features = false, features = ["alloc"], optional = true, version = "0.2" }
 quick-protobuf = { default-features = false, optional = true, version = "0.8" }
 rand_chacha = { default-features = false, optional = true, version = "0.9" }
+rand_core = { default-features = false, optional = true, version = "0.9" }
 ring = { default-features = false, optional = true, version = "0.17" }
+#rsa = { branch = "baloo/rand-core/0.9.0", default-features = false, optional = true, git = "https://github.com/baloo/RSA" }
 rust_decimal = { default-features = false, features = ["maths"], optional = true, version = "1.0" }
 rustls = { default-features = false, features = ["tls12"], optional = true, version = "0.23" }
 rustls-pemfile = { default-features = false, optional = true, version = "2.0" }
 rustls-pki-types = { default-features = false, optional = true, version = "1.0" }
 serde = { default-features = false, features = ["alloc", "derive"], optional = true, version = "1.0" }
 serde_json = { default-features = false, features = ["alloc"], optional = true, version = "1.0" }
+serde_urlencoded = { default-features = false, optional = true, version = "0.7" }
 sha1 = { default-features = false, optional = true, version = "0.10" }
 sha2 = { default-features = false, optional = true, version = "0.10" }
 simdutf8 = { default-features = false, features = ["aarch64_neon"], optional = true, version = "0.1" }
@@ -54,7 +56,6 @@ client-api-framework = ["data-transformation"]
 data-transformation = []
 database = []
 default = []
-embedded-tls = ["embedded-io-async", "dep:embedded-tls"]
 executor = []
 foldhash = ["dep:foldhash", "hashbrown?/default-hasher"]
 grpc = ["data-transformation"]
@@ -67,18 +68,21 @@ http-cookie-secure = ["aes-gcm/aes", "aes-gcm/alloc", "base64", "digest", "http-
 http-server-framework = ["http2"]
 http-session = ["chrono/now", "chrono/serde", "http-cookie-secure", "serde_json"]
 http2 = ["foldhash", "hashbrown", "http"]
-nightly = [] #FIXME(STABLE): "hashbrown?/nightly"
+mysql = ["database", "foldhash", "hashbrown", "num-bigint", "rand-compat", "sha2"]
+nightly = [] # FIXME(stable): "hashbrown?/nightly"
 optimization = ["memchr", "simdutf8"]
 pool = []
 portable-atomic-util = ["portable-atomic", "dep:portable-atomic-util"]
 postgres = ["base64", "crypto-common", "database", "digest", "foldhash", "hashbrown", "hmac", "sha2"]
 quick-protobuf = ["dep:quick-protobuf", "std"]
 rand_chacha = ["dep:rand_chacha", "getrandom"]
+rand-compat = ["rand_core"]
 rustls = ["dep:rustls", "rustls-pki-types"]
-schema-manager = ["database", "chrono"]
+schema-manager = ["database", "chrono/now"]
 schema-manager-dev = ["schema-manager"]
 serde = ["cl-aux?/serde", "dep:serde"]
 serde_json = ["serde", "dep:serde_json", "std"]
+serde_urlencoded = ["serde", "dep:serde_urlencoded", "std"]
 std = [
   "aes-gcm?/std",
   "argon2?/std",
@@ -89,8 +93,6 @@ std = [
   "crypto-common?/std",
   "digest?/std",
   "embassy-time?/std",
-  "embedded-io-async?/std",
-  "embedded-tls?/std",
   "fastrand?/std",
   "foldhash?/std",
   "getrandom?/std",
@@ -132,15 +134,27 @@ authors = ["Caio Fernandes <c410.f3r@gmail.com>"]
 categories = ["asynchronous", "database", "network-programming", "no-std", "web-programming"]
 description = "A collection of different transport implementations and related tools focused primarily on web technologies."
 documentation = "https://docs.rs/wtx"
-edition = "2021"
-exclude = ["tests"]
+edition = "2024"
+exclude = [
+  "tests",
+  "src/client_api_framework/tests.rs",
+  "src/data_transformation/dnsn/tests.rs",
+  "src/database/client/postgres/integration_tests.rs",
+  "src/database/schema_manager/integration_tests",
+  "src/database/schema_manager/integration_tests.rs",
+  "src/http2/tests.rs",
+  "src/misc/blocks_deque/tests.rs",
+  "src/misc/deque/tests.rs",
+  "src/tests.rs",
+  "src/web_socket/handshake/tests.rs",
+]
 homepage = "https://c410-f3r.github.io/wtx"
 keywords = ["api", "database", "http", "network", "websocket"]
 license = "MPL-2.0"
 name = "wtx"
 readme = "README.md"
 repository = "https://github.com/c410-f3r/wtx"
-rust-version = "1.84"
+rust-version = "1.85"
 version = "0.27.0"
 
 [package.metadata.docs.rs]
diff --git a/wtx/src/client_api_framework/misc.rs b/wtx/src/client_api_framework/misc.rs
index 2b7372e8..c11e4504 100644
--- a/wtx/src/client_api_framework/misc.rs
+++ b/wtx/src/client_api_framework/misc.rs
@@ -8,11 +8,12 @@ mod request_throttling;
 
 use crate::{
   client_api_framework::{
+    Api,
     network::transport::Transport,
     pkg::{Package, PkgsAux},
-    Api,
   },
-  data_transformation::dnsn::Serialize,
+  data_transformation::dnsn::EncodeWrapper,
+  misc::Encode,
 };
 pub use from_bytes::FromBytes;
 pub use pair::{Pair, PairMut};
@@ -20,28 +21,6 @@ pub use request_counter::RequestCounter;
 pub use request_limit::RequestLimit;
 pub use request_throttling::RequestThrottling;
 
-/// Used in all implementations of [`crate::Transport::send`] and/or
-/// [`crate::Transport::send_recv``].
-#[inline]
-pub(crate) fn log_req<A, DRSR, P, T, TP>(
-  _pkg: &mut P,
-  _pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
-  _trans: &mut T,
-) where
-  A: Api,
-  P: Package<A, DRSR, T, TP>,
-  T: Transport<TP>,
-{
-  _debug!(trans_ty = display(_trans.ty()), "Request: {:?}", {
-    use crate::data_transformation::dnsn::Serialize;
-    let mut vec = crate::misc::Vector::new();
-    _pkg
-      .ext_req_content_mut()
-      .to_bytes(&mut vec, &mut _pkgs_aux.drsr)
-      .and_then(|_| Ok(alloc::string::String::from(crate::misc::from_utf8_basic(&vec)?)))
-  });
-}
-
 /// Used in [`crate::network::transport::Transport::send_recv_decode_contained`] and all implementations of
 /// [`crate::Requests::decode_responses`].
 ///
@@ -53,7 +32,18 @@ pub(crate) fn log_res(_res: &[u8]) {
 }
 
 #[inline]
-pub(crate) async fn manage_after_sending_related<A, DRSR, P, T, TP>(
+pub(crate) async fn manage_after_sending_bytes<A, DRSR, TP>(
+  pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+) -> Result<(), A::Error>
+where
+  A: Api,
+{
+  pkgs_aux.api.after_sending().await?;
+  Ok(())
+}
+
+#[inline]
+pub(crate) async fn manage_after_sending_pkg<A, DRSR, P, T, TP>(
   pkg: &mut P,
   pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
   trans: &mut T,
@@ -74,7 +64,23 @@ where
 }
 
 #[inline]
-pub(crate) async fn manage_before_sending_related<A, DRSR, P, T, TP>(
+pub(crate) async fn manage_before_sending_bytes<A, DRSR, T, TP>(
+  bytes: &[u8],
+  pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+  trans: &mut T,
+) -> Result<(), A::Error>
+where
+  A: Api,
+  T: Transport<TP>,
+{
+  pkgs_aux.byte_buffer.clear();
+  log_req_bytes(bytes, trans);
+  pkgs_aux.api.before_sending().await?;
+  Ok(())
+}
+
+#[inline]
+pub(crate) async fn manage_before_sending_pkg<A, DRSR, P, T, TP>(
   pkg: &mut P,
   pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
   trans: &mut T,
@@ -84,7 +90,8 @@ where
   P: Package<A, DRSR, T, TP>,
   T: Transport<TP>,
 {
-  log_req(pkg, pkgs_aux, trans);
+  pkgs_aux.byte_buffer.clear();
+  log_req_pkg(pkg, pkgs_aux, trans);
   pkgs_aux.api.before_sending().await?;
   pkg
     .before_sending(
@@ -92,6 +99,34 @@ where
       (trans, &mut pkgs_aux.tp),
     )
     .await?;
-  pkg.ext_req_content_mut().to_bytes(&mut pkgs_aux.byte_buffer, &mut pkgs_aux.drsr)?;
+  pkg
+    .ext_req_content_mut()
+    .encode(&mut pkgs_aux.drsr, &mut EncodeWrapper::_new(&mut pkgs_aux.byte_buffer))?;
   Ok(())
 }
+
+#[inline]
+fn log_req_bytes<T, TP>(_bytes: &[u8], _trans: &mut T)
+where
+  T: Transport<TP>,
+{
+  _debug!(trans_ty = display(_trans.ty()), "Request: {:?}", crate::misc::from_utf8_basic(_bytes));
+}
+
+#[inline]
+fn log_req_pkg<A, DRSR, P, T, TP>(
+  _pkg: &mut P,
+  _pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+  _trans: &mut T,
+) where
+  A: Api,
+  P: Package<A, DRSR, T, TP>,
+  T: Transport<TP>,
+{
+  let idx = _pkgs_aux.byte_buffer.len();
+  let _rslt = _pkg
+    .ext_req_content_mut()
+    .encode(&mut _pkgs_aux.drsr, &mut EncodeWrapper::_new(&mut _pkgs_aux.byte_buffer));
+  log_req_bytes(_pkgs_aux.byte_buffer.get(idx..).unwrap_or_default(), _trans);
+  _pkgs_aux.byte_buffer.truncate(idx);
+}
diff --git a/wtx/src/client_api_framework/misc/request_counter.rs b/wtx/src/client_api_framework/misc/request_counter.rs
index 54679dea..be11e9ca 100644
--- a/wtx/src/client_api_framework/misc/request_counter.rs
+++ b/wtx/src/client_api_framework/misc/request_counter.rs
@@ -1,6 +1,6 @@
 use crate::{
   client_api_framework::misc::RequestLimit,
-  misc::{sleep, GenericTime},
+  misc::{GenericTime, sleep},
 };
 use core::time::Duration;
 
diff --git a/wtx/src/client_api_framework/network/http.rs b/wtx/src/client_api_framework/network/http.rs
index 6aff90d0..749841c1 100644
--- a/wtx/src/client_api_framework/network/http.rs
+++ b/wtx/src/client_api_framework/network/http.rs
@@ -22,7 +22,7 @@ impl HttpParams {
         mime: None,
         uri: UriString::new(uri),
       },
-      HttpResParams { headers: Headers::new(), status_code: StatusCode::Forbidden },
+      HttpResParams { status_code: StatusCode::Forbidden },
     )
   }
 }
@@ -46,33 +46,21 @@ impl TransportParams for HttpParams {
   type ExternalResponseParams = HttpResParams;
 
   #[inline]
-  fn ext_req_params(&self) -> &Self::ExternalRequestParams {
-    &self.0
+  fn ext_params(&self) -> (&Self::ExternalRequestParams, &Self::ExternalResponseParams) {
+    (&self.0, &self.1)
   }
 
   #[inline]
-  fn ext_req_params_mut(&mut self) -> &mut Self::ExternalRequestParams {
-    &mut self.0
-  }
-
-  #[inline]
-  fn ext_res_params(&self) -> &Self::ExternalResponseParams {
-    &self.1
-  }
-
-  #[inline]
-  fn ext_res_params_mut(&mut self) -> &mut Self::ExternalResponseParams {
-    &mut self.1
+  fn ext_params_mut(
+    &mut self,
+  ) -> (&mut Self::ExternalRequestParams, &mut Self::ExternalResponseParams) {
+    (&mut self.0, &mut self.1)
   }
 
   #[inline]
   fn reset(&mut self) {
-    self.0.headers.clear();
-    self.0.method = Method::Get;
-    self.0.mime = None;
-    self.0.uri.truncate_with_initial_len();
-    self.1.headers.clear();
-    self.1.status_code = StatusCode::Forbidden;
+    self.0.reset();
+    self.1.reset();
   }
 }
 
@@ -89,11 +77,27 @@ pub struct HttpReqParams {
   pub uri: UriString,
 }
 
+impl HttpReqParams {
+  /// Sets the inner parameters with their default values.
+  #[inline]
+  pub fn reset(&mut self) {
+    self.headers.clear();
+    self.method = Method::Get;
+    self.mime = None;
+  }
+}
+
 #[doc = generic_trans_res_params_doc!("HTTP")]
 #[derive(Debug)]
 pub struct HttpResParams {
-  /// Http headers.
-  pub headers: Headers,
   /// Status code.
   pub status_code: StatusCode,
 }
+
+impl HttpResParams {
+  /// Sets the inner parameters with their default values.
+  #[inline]
+  pub fn reset(&mut self) {
+    self.status_code = StatusCode::InternalServerError;
+  }
+}
diff --git a/wtx/src/client_api_framework/network/transport.rs b/wtx/src/client_api_framework/network/transport.rs
index 1f1302cf..ea5996a1 100644
--- a/wtx/src/client_api_framework/network/transport.rs
+++ b/wtx/src/client_api_framework/network/transport.rs
@@ -6,7 +6,7 @@ mod sending_receiving_transport;
 mod sending_transport;
 mod transport_params;
 mod unit;
-#[cfg(feature = "http-client-pool")]
+#[cfg(feature = "http2")]
 mod wtx_http;
 #[cfg(feature = "web-socket")]
 mod wtx_ws;
@@ -47,8 +47,8 @@ where
 mod tests {
   use crate::{
     client_api_framework::pkg::Package,
-    data_transformation::dnsn::{Deserialize, Serialize},
-    misc::Vector,
+    data_transformation::dnsn::{De, DecodeWrapper, EncodeWrapper},
+    misc::{Decode, DecodeSeq, Encode, Vector},
   };
 
   #[derive(Debug, Eq, PartialEq)]
@@ -83,10 +83,10 @@ mod tests {
   #[derive(Debug, Eq, PartialEq)]
   pub(crate) struct _Ping;
 
-  impl<DRSR> Serialize<DRSR> for _Ping {
+  impl<DRSR> Encode<De<DRSR>> for _Ping {
     #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut DRSR) -> crate::Result<()> {
-      bytes.extend_from_copyable_slice(b"ping")?;
+    fn encode(&self, _: &mut DRSR, ew: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+      ew.vector.extend_from_copyable_slice(b"ping")?;
       Ok(())
     }
   }
@@ -94,15 +94,18 @@ mod tests {
   #[derive(Debug, Eq, PartialEq)]
   pub(crate) struct _Pong(pub(crate) &'static str);
 
-  impl<'de, DRSR> Deserialize<'de, DRSR> for _Pong {
-    #[inline]
-    fn from_bytes(bytes: &[u8], _: &mut DRSR) -> crate::Result<Self> {
-      assert_eq!(bytes, b"ping");
+  impl<'de, DRSR> Decode<'de, De<DRSR>> for _Pong {
+    fn decode(_: &mut DRSR, _: &mut DecodeWrapper<'de>) -> crate::Result<Self> {
       Ok(Self("pong"))
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(_: &mut Vector<Self>, _: &'de [u8], _: &mut DRSR) -> crate::Result<()> {
+  impl<'de, DRSR> DecodeSeq<'de, De<DRSR>> for _Pong {
+    fn decode_seq(
+      _: &mut DRSR,
+      _: &mut Vector<Self>,
+      _: &mut DecodeWrapper<'de>,
+    ) -> crate::Result<()> {
       Ok(())
     }
   }
diff --git a/wtx/src/client_api_framework/network/transport/external_params.rs b/wtx/src/client_api_framework/network/transport/external_params.rs
new file mode 100644
index 00000000..e69de29b
diff --git a/wtx/src/client_api_framework/network/transport/mock.rs b/wtx/src/client_api_framework/network/transport/mock.rs
index 5884467d..851f3b8e 100644
--- a/wtx/src/client_api_framework/network/transport/mock.rs
+++ b/wtx/src/client_api_framework/network/transport/mock.rs
@@ -2,13 +2,16 @@
 
 use crate::{
   client_api_framework::{
-    misc::{manage_after_sending_related, manage_before_sending_related, FromBytes},
+    Api, ClientApiFrameworkError,
+    misc::{
+      FromBytes, manage_after_sending_bytes, manage_after_sending_pkg, manage_before_sending_bytes,
+      manage_before_sending_pkg,
+    },
     network::{
-      transport::{RecievingTransport, SendingTransport, Transport, TransportParams},
       TransportGroup,
+      transport::{RecievingTransport, SendingTransport, Transport, TransportParams},
     },
     pkg::{Package, PkgsAux},
-    Api, ClientApiFrameworkError,
   },
   misc::{Deque, Lease, Vector},
 };
@@ -31,7 +34,7 @@ pub type MockStr<TP> = Mock<str, TP>;
 ///   pkg::PkgsAux,
 /// };
 /// let _ = MockStr::default()
-///   .send_recv_decode_contained(&mut (), &mut PkgsAux::from_minimum((), (), ()))
+///   .send_pkg_recv_decode_contained(&mut (), &mut PkgsAux::from_minimum((), (), ()))
 ///   .await?;
 /// # Ok(()) }
 /// ```
@@ -114,7 +117,23 @@ where
   <T as ToOwned>::Owned: Debug + FromBytes,
 {
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
+    &mut self,
+    bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> Result<(), A::Error>
+  where
+    A: Api,
+  {
+    manage_before_sending_bytes(bytes, pkgs_aux, &mut *self).await?;
+    self.requests.push(Cow::Owned(FromBytes::from_bytes(&pkgs_aux.byte_buffer)?))?;
+    pkgs_aux.byte_buffer.clear();
+    manage_after_sending_bytes(pkgs_aux).await?;
+    Ok(())
+  }
+
+  #[inline]
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -123,10 +142,10 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
   {
-    manage_before_sending_related(pkg, pkgs_aux, &mut *self).await?;
+    manage_before_sending_pkg(pkg, pkgs_aux, &mut *self).await?;
     self.requests.push(Cow::Owned(FromBytes::from_bytes(&pkgs_aux.byte_buffer)?))?;
     pkgs_aux.byte_buffer.clear();
-    manage_after_sending_related(pkg, pkgs_aux, &mut *self).await?;
+    manage_after_sending_pkg(pkg, pkgs_aux, &mut *self).await?;
     Ok(())
   }
 }
diff --git a/wtx/src/client_api_framework/network/transport/recieving_transport.rs b/wtx/src/client_api_framework/network/transport/recieving_transport.rs
index 7a9b3d99..d3918c1d 100644
--- a/wtx/src/client_api_framework/network/transport/recieving_transport.rs
+++ b/wtx/src/client_api_framework/network/transport/recieving_transport.rs
@@ -1,12 +1,12 @@
 use crate::{
   client_api_framework::{
+    Api,
     misc::log_res,
     network::transport::Transport,
     pkg::{Package, PkgsAux},
-    Api,
   },
-  data_transformation::dnsn::Deserialize,
-  misc::Lease,
+  data_transformation::dnsn::DecodeWrapper,
+  misc::{Decode, Lease},
 };
 use core::{future::Future, ops::Range};
 
@@ -39,9 +39,9 @@ pub trait RecievingTransport<TP>: Sized + Transport<TP> {
     async {
       let range = self.recv(pkgs_aux).await?;
       log_res(pkgs_aux.byte_buffer.lease());
-      Ok(P::ExternalResponseContent::from_bytes(
-        pkgs_aux.byte_buffer.get(range).unwrap_or_default(),
+      Ok(P::ExternalResponseContent::decode(
         &mut pkgs_aux.drsr,
+        &mut DecodeWrapper::_new(pkgs_aux.byte_buffer.get(range).unwrap_or_default()),
       )?)
     }
   }
diff --git a/wtx/src/client_api_framework/network/transport/sending_receiving_transport.rs b/wtx/src/client_api_framework/network/transport/sending_receiving_transport.rs
index 7860b49b..28126716 100644
--- a/wtx/src/client_api_framework/network/transport/sending_receiving_transport.rs
+++ b/wtx/src/client_api_framework/network/transport/sending_receiving_transport.rs
@@ -1,12 +1,12 @@
 use crate::{
   client_api_framework::{
+    Api,
     misc::log_res,
     network::transport::{RecievingTransport, SendingTransport},
     pkg::{BatchElems, BatchPkg, Package, PkgsAux},
-    Api,
   },
-  data_transformation::dnsn::{Deserialize, Serialize},
-  misc::{Lease, Vector},
+  data_transformation::dnsn::{De, DecodeWrapper},
+  misc::{Decode, DecodeSeq, Encode, Lease, Vector},
 };
 use core::{future::Future, ops::Range};
 
@@ -16,11 +16,29 @@ use core::{future::Future, ops::Range};
 ///
 /// * `DRSR`: `D`eserialize`R`/`S`erialize`R`
 pub trait SendingReceivingTransport<TP>: RecievingTransport<TP> + SendingTransport<TP> {
-  /// Sends a request and then awaits its counterpart data response.
+  /// Sends a sequence of bytes and then awaits its counterpart data response.
   ///
   /// The returned bytes are stored in `pkgs_aux` and its length is returned by this method.
   #[inline]
-  fn send_recv<A, DRSR, P>(
+  fn send_bytes_recv<A>(
+    &mut self,
+    bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> impl Future<Output = Result<Range<usize>, A::Error>>
+  where
+    A: Api,
+  {
+    async {
+      self.send_bytes(bytes, pkgs_aux).await?;
+      self.recv(pkgs_aux).await
+    }
+  }
+
+  /// Sends a package and then awaits its counterpart data response.
+  ///
+  /// The returned bytes are stored in `pkgs_aux` and its length is returned by this method.
+  #[inline]
+  fn send_pkg_recv<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -30,17 +48,17 @@ pub trait SendingReceivingTransport<TP>: RecievingTransport<TP> + SendingTranspo
     P: Package<A, DRSR, Self::Inner, TP>,
   {
     async {
-      self.send(pkg, pkgs_aux).await?;
+      self.send_pkg(pkg, pkgs_aux).await?;
       self.recv(pkgs_aux).await
     }
   }
 
-  /// Convenient method similar to [`Self::send_recv_decode_contained`] but used for batch
+  /// Convenient method similar to [`Self::send_pkg_recv_decode_contained`] but used for batch
   /// requests.
   ///
   /// All the expected data must be available in a single response.
   #[inline]
-  fn send_recv_decode_batch<'pkgs, 'pkgs_aux, A, DRSR, P>(
+  fn send_pkg_recv_decode_batch<'pkgs, 'pkgs_aux, A, DRSR, P>(
     &mut self,
     buffer: &mut Vector<P::ExternalResponseContent<'pkgs_aux>>,
     pkgs: &'pkgs mut [P],
@@ -49,24 +67,24 @@ pub trait SendingReceivingTransport<TP>: RecievingTransport<TP> + SendingTranspo
   where
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
-    BatchElems<'pkgs, A, DRSR, P, Self::Inner, TP>: Serialize<DRSR>,
+    BatchElems<'pkgs, A, DRSR, P, Self::Inner, TP>: Encode<De<DRSR>>,
   {
     async {
-      let range = self.send_recv(&mut BatchPkg::new(pkgs), pkgs_aux).await?;
+      let range = self.send_pkg_recv(&mut BatchPkg::new(pkgs), pkgs_aux).await?;
       log_res(pkgs_aux.byte_buffer.lease());
-      P::ExternalResponseContent::seq_from_bytes(
-        buffer,
-        pkgs_aux.byte_buffer.get(range).unwrap_or_default(),
+      P::ExternalResponseContent::decode_seq(
         &mut pkgs_aux.drsr,
+        buffer,
+        &mut DecodeWrapper::_new(pkgs_aux.byte_buffer.get(range).unwrap_or_default()),
       )?;
       Ok(())
     }
   }
 
-  /// Internally calls [`Self::send_recv`] and then tries to decode the defined response specified
+  /// Internally calls [`Self::send_pkg_recv`] and then tries to decode the defined response specified
   /// in [`Package::ExternalResponseContent`].
   #[inline]
-  fn send_recv_decode_contained<'de, A, DRSR, P>(
+  fn send_pkg_recv_decode_contained<'de, A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &'de mut PkgsAux<A, DRSR, TP>,
@@ -76,11 +94,11 @@ pub trait SendingReceivingTransport<TP>: RecievingTransport<TP> + SendingTranspo
     P: Package<A, DRSR, Self::Inner, TP>,
   {
     async {
-      let range = self.send_recv(pkg, pkgs_aux).await?;
+      let range = self.send_pkg_recv(pkg, pkgs_aux).await?;
       log_res(pkgs_aux.byte_buffer.lease());
-      Ok(P::ExternalResponseContent::from_bytes(
-        pkgs_aux.byte_buffer.get(range).unwrap_or_default(),
+      Ok(P::ExternalResponseContent::decode(
         &mut pkgs_aux.drsr,
+        &mut DecodeWrapper::_new(pkgs_aux.byte_buffer.get(range).unwrap_or_default()),
       )?)
     }
   }
diff --git a/wtx/src/client_api_framework/network/transport/sending_transport.rs b/wtx/src/client_api_framework/network/transport/sending_transport.rs
index 64e880b0..fccb92c8 100644
--- a/wtx/src/client_api_framework/network/transport/sending_transport.rs
+++ b/wtx/src/client_api_framework/network/transport/sending_transport.rs
@@ -1,7 +1,7 @@
 use crate::client_api_framework::{
+  Api,
   network::transport::Transport,
   pkg::{Package, PkgsAux},
-  Api,
 };
 use core::future::Future;
 
@@ -11,8 +11,17 @@ use core::future::Future;
 ///
 /// * `DRSR`: `D`eserialize`R`/`S`erialize`R`
 pub trait SendingTransport<TP>: Transport<TP> {
-  /// Sends a request without trying to retrieve any counterpart data.
-  fn send<A, DRSR, P>(
+  /// Sends a sequence of bytes without trying to retrieve any counterpart data.
+  fn send_bytes<A>(
+    &mut self,
+    bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> impl Future<Output = Result<(), A::Error>>
+  where
+    A: Api;
+
+  /// Sends a package without trying to retrieve any counterpart data.
+  fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -27,7 +36,19 @@ where
   T: SendingTransport<TP>,
 {
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
+    &mut self,
+    bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> Result<(), A::Error>
+  where
+    A: Api,
+  {
+    (**self).send_bytes(bytes, pkgs_aux).await
+  }
+
+  #[inline]
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -36,6 +57,6 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
   {
-    (**self).send(pkg, pkgs_aux).await
+    (**self).send_pkg(pkg, pkgs_aux).await
   }
 }
diff --git a/wtx/src/client_api_framework/network/transport/transport_params.rs b/wtx/src/client_api_framework/network/transport/transport_params.rs
index 6e85ce22..5ccd205b 100644
--- a/wtx/src/client_api_framework/network/transport/transport_params.rs
+++ b/wtx/src/client_api_framework/network/transport/transport_params.rs
@@ -5,17 +5,33 @@ pub trait TransportParams {
   /// For example, HTTP has response headers.
   type ExternalResponseParams;
 
+  /// External Request and Response Parameters.
+  fn ext_params(&self) -> (&Self::ExternalRequestParams, &Self::ExternalResponseParams);
+
+  /// Mutable version of [TransportParams::ext_params].
+  fn ext_params_mut(
+    &mut self,
+  ) -> (&mut Self::ExternalRequestParams, &mut Self::ExternalResponseParams);
+
   /// External Request Parameters.
-  fn ext_req_params(&self) -> &Self::ExternalRequestParams;
+  fn ext_req_params(&self) -> &Self::ExternalRequestParams {
+    self.ext_params().0
+  }
 
   /// Mutable version of [`Self::ext_req_params`].
-  fn ext_req_params_mut(&mut self) -> &mut Self::ExternalRequestParams;
+  fn ext_req_params_mut(&mut self) -> &mut Self::ExternalRequestParams {
+    self.ext_params_mut().0
+  }
 
   /// External Response Parameters.
-  fn ext_res_params(&self) -> &Self::ExternalResponseParams;
+  fn ext_res_params(&self) -> &Self::ExternalResponseParams {
+    self.ext_params().1
+  }
 
   /// Mutable version of [`Self::ext_res_params`].
-  fn ext_res_params_mut(&mut self) -> &mut Self::ExternalResponseParams;
+  fn ext_res_params_mut(&mut self) -> &mut Self::ExternalResponseParams {
+    self.ext_params_mut().1
+  }
 
   /// Sets the inner parameters with their default values.
   fn reset(&mut self);
@@ -26,23 +42,15 @@ impl TransportParams for () {
   type ExternalResponseParams = ();
 
   #[inline]
-  fn ext_req_params(&self) -> &Self::ExternalRequestParams {
-    self
-  }
-
-  #[inline]
-  fn ext_req_params_mut(&mut self) -> &mut Self::ExternalRequestParams {
-    self
-  }
-
-  #[inline]
-  fn ext_res_params(&self) -> &Self::ExternalResponseParams {
-    self
+  fn ext_params(&self) -> (&Self::ExternalRequestParams, &Self::ExternalResponseParams) {
+    (&(), &())
   }
 
   #[inline]
-  fn ext_res_params_mut(&mut self) -> &mut Self::ExternalResponseParams {
-    self
+  fn ext_params_mut(
+    &mut self,
+  ) -> (&mut Self::ExternalRequestParams, &mut Self::ExternalResponseParams) {
+    (self, alloc::boxed::Box::leak(alloc::boxed::Box::new(())))
   }
 
   #[inline]
@@ -57,23 +65,15 @@ where
   type ExternalResponseParams = TP::ExternalResponseParams;
 
   #[inline]
-  fn ext_req_params(&self) -> &Self::ExternalRequestParams {
-    (**self).ext_req_params()
+  fn ext_params(&self) -> (&Self::ExternalRequestParams, &Self::ExternalResponseParams) {
+    (**self).ext_params()
   }
 
   #[inline]
-  fn ext_req_params_mut(&mut self) -> &mut Self::ExternalRequestParams {
-    (**self).ext_req_params_mut()
-  }
-
-  #[inline]
-  fn ext_res_params(&self) -> &Self::ExternalResponseParams {
-    (**self).ext_res_params()
-  }
-
-  #[inline]
-  fn ext_res_params_mut(&mut self) -> &mut Self::ExternalResponseParams {
-    (**self).ext_res_params_mut()
+  fn ext_params_mut(
+    &mut self,
+  ) -> (&mut Self::ExternalRequestParams, &mut Self::ExternalResponseParams) {
+    (**self).ext_params_mut()
   }
 
   #[inline]
diff --git a/wtx/src/client_api_framework/network/transport/unit.rs b/wtx/src/client_api_framework/network/transport/unit.rs
index 29371716..5d5e965e 100644
--- a/wtx/src/client_api_framework/network/transport/unit.rs
+++ b/wtx/src/client_api_framework/network/transport/unit.rs
@@ -1,11 +1,14 @@
 use crate::client_api_framework::{
-  misc::{manage_after_sending_related, manage_before_sending_related},
+  Api,
+  misc::{
+    manage_after_sending_bytes, manage_after_sending_pkg, manage_before_sending_bytes,
+    manage_before_sending_pkg,
+  },
   network::{
-    transport::{RecievingTransport, SendingTransport, Transport},
     TransportGroup,
+    transport::{RecievingTransport, SendingTransport, Transport},
   },
   pkg::{Package, PkgsAux},
-  Api,
 };
 use core::ops::Range;
 
@@ -21,7 +24,21 @@ impl<TP> RecievingTransport<TP> for () {
 
 impl<TP> SendingTransport<TP> for () {
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
+    &mut self,
+    bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> Result<(), A::Error>
+  where
+    A: Api,
+  {
+    manage_before_sending_bytes(bytes, pkgs_aux, self).await?;
+    manage_after_sending_bytes(pkgs_aux).await?;
+    Ok(())
+  }
+
+  #[inline]
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -30,8 +47,8 @@ impl<TP> SendingTransport<TP> for () {
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
   {
-    manage_before_sending_related(pkg, pkgs_aux, self).await?;
-    manage_after_sending_related(pkg, pkgs_aux, self).await?;
+    manage_before_sending_pkg(pkg, pkgs_aux, self).await?;
+    manage_after_sending_pkg(pkg, pkgs_aux, self).await?;
     Ok(())
   }
 }
@@ -42,7 +59,7 @@ impl<TP> SendingTransport<TP> for () {
 /// # async fn fun() -> wtx::Result<()> {
 /// use wtx::client_api_framework::{network::transport::SendingReceivingTransport, pkg::PkgsAux};
 /// let _ =
-///   ().send_recv_decode_contained(&mut (), &mut PkgsAux::from_minimum((), (), ())).await?;
+///   ().send_pkg_recv_decode_contained(&mut (), &mut PkgsAux::from_minimum((), (), ())).await?;
 /// # Ok(()) }
 /// ```
 impl<TP> Transport<TP> for () {
@@ -57,6 +74,6 @@ mod tests {
   #[tokio::test]
   async fn unit() {
     let mut pa = PkgsAux::from_minimum((), (), ());
-    assert_eq!(().send_recv_decode_contained(&mut (), &mut pa).await.unwrap(), ());
+    assert_eq!(().send_pkg_recv_decode_contained(&mut (), &mut pa).await.unwrap(), ());
   }
 }
diff --git a/wtx/src/client_api_framework/network/transport/wtx_http.rs b/wtx/src/client_api_framework/network/transport/wtx_http.rs
index b399d7f3..8ee10874 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_http.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_http.rs
@@ -1,37 +1,27 @@
 use crate::{
   client_api_framework::{
-    misc::{manage_after_sending_related, manage_before_sending_related},
+    Api,
+    misc::{
+      manage_after_sending_bytes, manage_after_sending_pkg, manage_before_sending_bytes,
+      manage_before_sending_pkg,
+    },
     network::{
+      HttpParams, HttpReqParams, HttpResParams, TransportGroup,
       transport::{RecievingTransport, SendingTransport, Transport, TransportParams},
-      HttpParams, HttpReqParams, TransportGroup,
     },
     pkg::{Package, PkgsAux},
-    Api,
-  },
-  http::{
-    client_pool::{ClientPool, ClientPoolResource},
-    Header, KnownHeaderName, ReqBuilder, ReqResBuffer, WTX_USER_AGENT,
   },
+  http::{Header, HttpClient, KnownHeaderName, Method, ReqResBuffer, Response, WTX_USER_AGENT},
   http2::{Http2, Http2Buffer, Http2Data},
-  misc::{LeaseMut, Lock, RefCounter, StreamWriter},
-  pool::{ResourceManager, SimplePoolResource},
+  misc::{LeaseMut, Lock, RefCounter, StreamWriter, UriRef},
 };
 use core::{mem, ops::Range};
 
-impl<AUX, HD, RL, RM, SW, TP> RecievingTransport<TP> for ClientPool<RL, RM>
+impl<HD, SW, TP> RecievingTransport<TP> for Http2<HD, true>
 where
   HD: RefCounter,
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-  RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
-  RM: ResourceManager<
-    CreateAux = str,
-    Error = crate::Error,
-    RecycleAux = str,
-    Resource = ClientPoolResource<AUX, Http2<HD, true>>,
-  >,
   SW: StreamWriter,
-  for<'any> RL: 'any,
-  for<'any> RM: 'any,
 {
   #[inline]
   async fn recv<A, DRSR>(
@@ -44,102 +34,27 @@ where
     Ok(0..pkgs_aux.byte_buffer.len())
   }
 }
-impl<AUX, HD, RL, RM, SW, TP> SendingTransport<TP> for ClientPool<RL, RM>
+impl<HD, SW, TP> SendingTransport<TP> for Http2<HD, true>
 where
   HD: RefCounter,
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-  RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
-  RM: ResourceManager<
-    CreateAux = str,
-    Error = crate::Error,
-    RecycleAux = str,
-    Resource = ClientPoolResource<AUX, Http2<HD, true>>,
-  >,
   SW: StreamWriter,
   TP: LeaseMut<HttpParams>,
-  for<'any> RL: 'any,
-  for<'any> RM: 'any,
 {
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
     &mut self,
-    pkg: &mut P,
-    pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+    mut bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
   ) -> Result<(), A::Error>
   where
     A: Api,
-    P: Package<A, DRSR, Self::Inner, TP>,
   {
-    response(
-      &mut self.lock(&pkgs_aux.tp.lease_mut().ext_req_params_mut().uri.to_ref()).await?.client,
-      pkg,
-      pkgs_aux,
-    )
-    .await?;
-    Ok(())
+    send_bytes(&mut bytes, self, pkgs_aux).await
   }
-}
-impl<AUX, HD, RL, RM, SW, TP> Transport<TP> for ClientPool<RL, RM>
-where
-  HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-  RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
-  RM: ResourceManager<
-    CreateAux = str,
-    Error = crate::Error,
-    RecycleAux = str,
-    Resource = ClientPoolResource<AUX, Http2<HD, true>>,
-  >,
-  SW: StreamWriter,
-{
-  const GROUP: TransportGroup = TransportGroup::HTTP;
-  type Inner = Http2<HD, true>;
-}
 
-impl<AUX, HD, RL, RM, SW, TP> RecievingTransport<TP> for &ClientPool<RL, RM>
-where
-  HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-  RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
-  RM: ResourceManager<
-    CreateAux = str,
-    Error = crate::Error,
-    RecycleAux = str,
-    Resource = ClientPoolResource<AUX, Http2<HD, true>>,
-  >,
-  SW: StreamWriter,
-  for<'any> RL: 'any,
-  for<'any> RM: 'any,
-{
-  #[inline]
-  async fn recv<A, DRSR>(
-    &mut self,
-    pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
-  ) -> Result<Range<usize>, A::Error>
-  where
-    A: Api,
-  {
-    Ok(0..pkgs_aux.byte_buffer.len())
-  }
-}
-impl<AUX, HD, RL, RM, SW, TP> SendingTransport<TP> for &ClientPool<RL, RM>
-where
-  HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-  RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
-  RM: ResourceManager<
-    CreateAux = str,
-    Error = crate::Error,
-    RecycleAux = str,
-    Resource = ClientPoolResource<AUX, Http2<HD, true>>,
-  >,
-  SW: StreamWriter,
-  TP: LeaseMut<HttpParams>,
-  for<'any> RL: 'any,
-  for<'any> RM: 'any,
-{
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -148,118 +63,334 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
   {
-    response(
-      &mut self.lock(&pkgs_aux.tp.lease_mut().ext_req_params_mut().uri.to_ref()).await?.client,
-      pkg,
-      pkgs_aux,
-    )
-    .await?;
-    Ok(())
+    send_pkg(self, pkg, pkgs_aux).await
   }
 }
-impl<AUX, HD, RL, RM, SW, TP> Transport<TP> for &ClientPool<RL, RM>
+impl<HD, SW, TP> Transport<TP> for Http2<HD, true>
 where
   HD: RefCounter,
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-  RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
-  RM: ResourceManager<
-    CreateAux = str,
-    Error = crate::Error,
-    RecycleAux = str,
-    Resource = ClientPoolResource<AUX, Http2<HD, true>>,
-  >,
   SW: StreamWriter,
-  for<'any> RL: 'any,
-  for<'any> RM: 'any,
 {
   const GROUP: TransportGroup = TransportGroup::HTTP;
-  type Inner = Http2<HD, true>;
+  type Inner = Self;
 }
 
-impl<HD, SW, TP> RecievingTransport<TP> for Http2<HD, true>
-where
-  HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-  SW: StreamWriter,
-{
-  #[inline]
-  async fn recv<A, DRSR>(
-    &mut self,
-    pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
-  ) -> Result<Range<usize>, A::Error>
-  where
-    A: Api,
-  {
-    Ok(0..pkgs_aux.byte_buffer.len())
-  }
-}
-impl<HD, SW, TP> SendingTransport<TP> for Http2<HD, true>
+#[inline]
+async fn send<A, AUX, DRSR, HD, SW, TP>(
+  mut aux: AUX,
+  client: &mut Http2<HD, true>,
+  pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+  before_sending: impl AsyncFnOnce(
+    &mut AUX,
+    &mut PkgsAux<A, DRSR, TP>,
+    &mut Http2<HD, true>,
+  ) -> Result<(), A::Error>,
+  send: impl AsyncFnOnce(
+    &mut AUX,
+    Method,
+    ReqResBuffer,
+    &mut Http2<HD, true>,
+    &UriRef<'_>,
+  ) -> crate::Result<Response<ReqResBuffer>>,
+  after_sending: impl AsyncFnOnce(
+    &mut AUX,
+    &mut PkgsAux<A, DRSR, TP>,
+    &mut Http2<HD, true>,
+  ) -> Result<(), A::Error>,
+) -> Result<(), A::Error>
 where
+  A: Api,
   HD: RefCounter,
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   SW: StreamWriter,
   TP: LeaseMut<HttpParams>,
 {
-  #[inline]
-  async fn send<A, DRSR, P>(
-    &mut self,
-    pkg: &mut P,
-    pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
-  ) -> Result<(), A::Error>
-  where
-    A: Api,
-    P: Package<A, DRSR, Self::Inner, TP>,
-  {
-    response(self, pkg, pkgs_aux).await?;
-    Ok(())
+  before_sending(&mut aux, pkgs_aux, client).await?;
+  let tp = pkgs_aux.tp.lease_mut();
+  let (req_params, res_params) = tp.ext_params_mut();
+  let HttpReqParams { headers, method, mime, uri } = req_params;
+  let HttpResParams { status_code } = res_params;
+  headers.push_from_iter(Header::from_name_and_value(
+    KnownHeaderName::UserAgent.into(),
+    [WTX_USER_AGENT.as_bytes()],
+  ))?;
+  if let Some(elem) = mime {
+    headers.push_from_iter(Header::from_name_and_value(
+      KnownHeaderName::ContentType.into(),
+      [elem.as_str().as_bytes()],
+    ))?;
   }
+  let mut rrb = ReqResBuffer::empty();
+  mem::swap(&mut rrb.headers, headers);
+  // Only servers use the URI buffer so there is no need for URI swaps
+  let mut res = send(&mut aux, *method, rrb, client, &uri.to_ref()).await?;
+  mem::swap(&mut res.rrd.headers, headers);
+  *status_code = res.status_code;
+  after_sending(&mut aux, pkgs_aux, client).await?;
+  Ok(())
 }
-impl<HD, SW, TP> Transport<TP> for Http2<HD, true>
+
+#[inline]
+async fn send_bytes<A, DRSR, HD, SW, TP>(
+  bytes: &[u8],
+  client: &mut Http2<HD, true>,
+  pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+) -> Result<(), A::Error>
 where
+  A: Api,
   HD: RefCounter,
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   SW: StreamWriter,
+  TP: LeaseMut<HttpParams>,
 {
-  const GROUP: TransportGroup = TransportGroup::HTTP;
-  type Inner = Self;
+  send(
+    bytes,
+    client,
+    pkgs_aux,
+    async move |aux, pa, tr| manage_before_sending_bytes(aux, pa, tr).await,
+    async move |aux, method, mut rrb, tr, uri| {
+      let stream = tr.send_req(method, uri, (aux, &mut rrb.headers)).await?;
+      tr.recv_res(rrb, stream).await
+    },
+    async move |_, pa, _| manage_after_sending_bytes(pa).await,
+  )
+  .await
 }
 
 #[inline]
-async fn response<A, DRSR, HD, P, SW, TP>(
-  mut client: &mut Http2<HD, true>,
+async fn send_pkg<A, DRSR, HD, P, SW, TP>(
+  client: &mut Http2<HD, true>,
   pkg: &mut P,
   pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
 ) -> Result<(), A::Error>
 where
   A: Api,
-  P: Package<A, DRSR, Http2<HD, true>, TP>,
   HD: RefCounter,
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+  P: Package<A, DRSR, Http2<HD, true>, TP>,
   SW: StreamWriter,
   TP: LeaseMut<HttpParams>,
 {
-  pkgs_aux.byte_buffer.clear();
-  pkgs_aux.tp.lease_mut().ext_req_params_mut().headers.clear();
-  manage_before_sending_related(pkg, pkgs_aux, &mut client).await?;
-  let HttpReqParams { headers, method, mime, uri } = pkgs_aux.tp.lease_mut().ext_req_params_mut();
-  headers.push_from_iter(Header::from_name_and_value(
-    KnownHeaderName::UserAgent.into(),
-    [WTX_USER_AGENT.as_bytes()],
-  ))?;
-  if let Some(elem) = mime {
-    headers.push_from_iter(Header::from_name_and_value(
-      KnownHeaderName::ContentType.into(),
-      [elem.as_str().as_bytes()],
-    ))?;
+  send(
+    pkg,
+    client,
+    pkgs_aux,
+    async move |aux, pa, tr| manage_before_sending_pkg(aux, pa, tr).await,
+    async move |_, method, rrb, tr, uri| tr.send_recv_single(method, uri, rrb).await,
+    async move |aux, pa, tr| manage_after_sending_pkg(aux, pa, tr).await,
+  )
+  .await
+}
+
+#[cfg(feature = "http-client-pool")]
+mod http_client_pool {
+  use crate::{
+    client_api_framework::{
+      Api,
+      network::{
+        HttpParams, TransportGroup,
+        transport::{
+          RecievingTransport, SendingTransport, Transport, TransportParams,
+          wtx_http::{send_bytes, send_pkg},
+        },
+      },
+      pkg::{Package, PkgsAux},
+    },
+    http::client_pool::{ClientPool, ClientPoolResource},
+    http2::{Http2, Http2Buffer, Http2Data},
+    misc::{LeaseMut, Lock, RefCounter, StreamWriter},
+    pool::{ResourceManager, SimplePoolResource},
+  };
+  use core::ops::Range;
+
+  impl<AUX, HD, RL, RM, SW, TP> RecievingTransport<TP> for ClientPool<RL, RM>
+  where
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+    RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
+    RM: ResourceManager<
+        CreateAux = str,
+        Error = crate::Error,
+        RecycleAux = str,
+        Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+      >,
+    SW: StreamWriter,
+    for<'any> RL: 'any,
+    for<'any> RM: 'any,
+  {
+    #[inline]
+    async fn recv<A, DRSR>(
+      &mut self,
+      pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+    ) -> Result<Range<usize>, A::Error>
+    where
+      A: Api,
+    {
+      Ok(0..pkgs_aux.byte_buffer.len())
+    }
+  }
+  impl<AUX, HD, RL, RM, SW, TP> SendingTransport<TP> for ClientPool<RL, RM>
+  where
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+    RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
+    RM: ResourceManager<
+        CreateAux = str,
+        Error = crate::Error,
+        RecycleAux = str,
+        Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+      >,
+    SW: StreamWriter,
+    TP: LeaseMut<HttpParams>,
+    for<'any> RL: 'any,
+    for<'any> RM: 'any,
+  {
+    #[inline]
+    async fn send_bytes<A>(
+      &mut self,
+      mut bytes: &[u8],
+      pkgs_aux: &mut PkgsAux<A, (), TP>,
+    ) -> Result<(), A::Error>
+    where
+      A: Api,
+    {
+      send_bytes(
+        &mut bytes,
+        &mut self.lock(&pkgs_aux.tp.lease_mut().ext_req_params_mut().uri.to_ref()).await?.client,
+        pkgs_aux,
+      )
+      .await
+    }
+
+    #[inline]
+    async fn send_pkg<A, DRSR, P>(
+      &mut self,
+      pkg: &mut P,
+      pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+    ) -> Result<(), A::Error>
+    where
+      A: Api,
+      P: Package<A, DRSR, Self::Inner, TP>,
+    {
+      send_pkg(
+        &mut self.lock(&pkgs_aux.tp.lease_mut().ext_req_params_mut().uri.to_ref()).await?.client,
+        pkg,
+        pkgs_aux,
+      )
+      .await
+    }
+  }
+  impl<AUX, HD, RL, RM, SW, TP> Transport<TP> for ClientPool<RL, RM>
+  where
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+    RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
+    RM: ResourceManager<
+        CreateAux = str,
+        Error = crate::Error,
+        RecycleAux = str,
+        Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+      >,
+    SW: StreamWriter,
+  {
+    const GROUP: TransportGroup = TransportGroup::HTTP;
+    type Inner = Http2<HD, true>;
+  }
+
+  impl<AUX, HD, RL, RM, SW, TP> RecievingTransport<TP> for &ClientPool<RL, RM>
+  where
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+    RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
+    RM: ResourceManager<
+        CreateAux = str,
+        Error = crate::Error,
+        RecycleAux = str,
+        Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+      >,
+    SW: StreamWriter,
+    for<'any> RL: 'any,
+    for<'any> RM: 'any,
+  {
+    #[inline]
+    async fn recv<A, DRSR>(
+      &mut self,
+      pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+    ) -> Result<Range<usize>, A::Error>
+    where
+      A: Api,
+    {
+      Ok(0..pkgs_aux.byte_buffer.len())
+    }
+  }
+  impl<AUX, HD, RL, RM, SW, TP> SendingTransport<TP> for &ClientPool<RL, RM>
+  where
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+    RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
+    RM: ResourceManager<
+        CreateAux = str,
+        Error = crate::Error,
+        RecycleAux = str,
+        Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+      >,
+    SW: StreamWriter,
+    TP: LeaseMut<HttpParams>,
+    for<'any> RL: 'any,
+    for<'any> RM: 'any,
+  {
+    #[inline]
+    async fn send_bytes<A>(
+      &mut self,
+      mut bytes: &[u8],
+      pkgs_aux: &mut PkgsAux<A, (), TP>,
+    ) -> Result<(), A::Error>
+    where
+      A: Api,
+    {
+      send_bytes(
+        &mut bytes,
+        &mut self.lock(&pkgs_aux.tp.lease_mut().ext_req_params_mut().uri.to_ref()).await?.client,
+        pkgs_aux,
+      )
+      .await
+    }
+
+    #[inline]
+    async fn send_pkg<A, DRSR, P>(
+      &mut self,
+      pkg: &mut P,
+      pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+    ) -> Result<(), A::Error>
+    where
+      A: Api,
+      P: Package<A, DRSR, Self::Inner, TP>,
+    {
+      send_pkg(
+        &mut self.lock(&pkgs_aux.tp.lease_mut().ext_req_params_mut().uri.to_ref()).await?.client,
+        pkg,
+        pkgs_aux,
+      )
+      .await
+    }
+  }
+  impl<AUX, HD, RL, RM, SW, TP> Transport<TP> for &ClientPool<RL, RM>
+  where
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+    RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
+    RM: ResourceManager<
+        CreateAux = str,
+        Error = crate::Error,
+        RecycleAux = str,
+        Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+      >,
+    SW: StreamWriter,
+    for<'any> RL: 'any,
+    for<'any> RM: 'any,
+  {
+    const GROUP: TransportGroup = TransportGroup::HTTP;
+    type Inner = Http2<HD, true>;
   }
-  let mut rrb = ReqResBuffer::empty();
-  mem::swap(&mut rrb.body, &mut pkgs_aux.byte_buffer);
-  mem::swap(&mut rrb.headers, headers);
-  let mut res = ReqBuilder::get(rrb).method(*method).send(client, &uri.to_ref()).await?;
-  mem::swap(&mut pkgs_aux.byte_buffer, &mut res.rrd.body);
-  mem::swap(headers, &mut res.rrd.headers);
-  pkgs_aux.tp.lease_mut().ext_res_params_mut().status_code = res.status_code;
-  manage_after_sending_related(pkg, pkgs_aux, &mut client).await?;
-  pkgs_aux.tp.lease_mut().reset();
-  Ok(())
 }
diff --git a/wtx/src/client_api_framework/network/transport/wtx_ws.rs b/wtx/src/client_api_framework/network/transport/wtx_ws.rs
index 40772686..3a51d422 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_ws.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_ws.rs
@@ -5,15 +5,18 @@ mod web_socket_writer_part_owned;
 
 use crate::{
   client_api_framework::{
-    misc::{manage_after_sending_related, manage_before_sending_related},
+    Api, ClientApiFrameworkError,
+    misc::{
+      manage_after_sending_bytes, manage_after_sending_pkg, manage_before_sending_bytes,
+      manage_before_sending_pkg,
+    },
     network::{
-      transport::{Transport, TransportParams},
       WsParams, WsReqParamsTy,
+      transport::{Transport, TransportParams},
     },
     pkg::{Package, PkgsAux},
-    Api, ClientApiFrameworkError,
   },
-  misc::{FnMutFut, LeaseMut, Vector},
+  misc::{LeaseMut, Vector},
   web_socket::{Frame, OpCode},
 };
 use core::ops::Range;
@@ -30,30 +33,75 @@ async fn recv<A, DRSR, TP>(
   Ok(0..pkgs_aux.byte_buffer.len())
 }
 
-async fn send<A, DRSR, P, T, TP>(
-  pkg: &mut P,
+async fn send<A, AUX, DRSR, T, TP>(
+  aux: &mut AUX,
   pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
   trans: &mut T,
-  mut cb: impl for<'any> FnMutFut<
-    (Frame<&'any mut Vector<u8>, true>, &'any mut T),
-    Result = crate::Result<()>,
-  >,
+  before_sending: impl AsyncFnOnce(&mut AUX, &mut PkgsAux<A, DRSR, TP>, &mut T) -> Result<(), A::Error>,
+  send: impl AsyncFnOnce(&mut AUX, &mut Vector<u8>, OpCode, &mut T) -> crate::Result<()>,
+  after_sending: impl AsyncFnOnce(&mut AUX, &mut PkgsAux<A, DRSR, TP>, &mut T) -> Result<(), A::Error>,
 ) -> Result<(), A::Error>
 where
   A: Api,
-  P: Package<A, DRSR, T, TP>,
   T: Transport<TP>,
   TP: LeaseMut<WsParams>,
 {
-  pkgs_aux.byte_buffer.clear();
-  manage_before_sending_related(pkg, pkgs_aux, &mut *trans).await?;
+  before_sending(aux, pkgs_aux, &mut *trans).await?;
   let op_code = match pkgs_aux.tp.lease_mut().ext_req_params_mut().ty {
     WsReqParamsTy::Bytes => OpCode::Binary,
     WsReqParamsTy::String => OpCode::Text,
   };
-  cb.call((Frame::new_fin(op_code, &mut pkgs_aux.byte_buffer), trans)).await?;
+  send(aux, &mut pkgs_aux.byte_buffer, op_code, trans).await?;
   pkgs_aux.byte_buffer.clear();
-  manage_after_sending_related(pkg, pkgs_aux, trans).await?;
+  after_sending(aux, pkgs_aux, &mut *trans).await?;
   pkgs_aux.tp.lease_mut().reset();
   Ok(())
 }
+
+async fn send_bytes<A, DRSR, T, TP>(
+  mut bytes: &[u8],
+  pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+  trans: &mut T,
+  cb: impl AsyncFnOnce(Frame<&mut Vector<u8>, true>, &mut T) -> crate::Result<()>,
+) -> Result<(), A::Error>
+where
+  A: Api,
+  T: Transport<TP>,
+  TP: LeaseMut<WsParams>,
+{
+  send(
+    &mut bytes,
+    pkgs_aux,
+    trans,
+    async move |aux, pa, tr| manage_before_sending_bytes(aux, pa, tr).await,
+    async move |aux, buffer, op_code, trans| {
+      buffer.extend_from_copyable_slice(aux)?;
+      cb(Frame::new_fin(op_code, buffer), trans).await
+    },
+    async move |_, pa, _| manage_after_sending_bytes(pa).await,
+  )
+  .await
+}
+
+async fn send_pkg<A, DRSR, P, T, TP>(
+  pkg: &mut P,
+  pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
+  trans: &mut T,
+  cb: impl AsyncFnOnce(Frame<&mut Vector<u8>, true>, &mut T) -> crate::Result<()>,
+) -> Result<(), A::Error>
+where
+  A: Api,
+  P: Package<A, DRSR, T, TP>,
+  T: Transport<TP>,
+  TP: LeaseMut<WsParams>,
+{
+  send(
+    pkg,
+    pkgs_aux,
+    trans,
+    async move |aux, pa, tr| manage_before_sending_pkg(aux, pa, tr).await,
+    async move |_, buffer, op_code, trans| cb(Frame::new_fin(op_code, buffer), trans).await,
+    async move |aux, pa, tr| manage_after_sending_pkg(aux, pa, tr).await,
+  )
+  .await
+}
diff --git a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket.rs b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket.rs
index 1684420c..57477927 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket.rs
@@ -1,17 +1,17 @@
 use crate::{
   client_api_framework::{
+    Api,
     network::{
+      TransportGroup, WsParams,
       transport::{
-        wtx_ws::{recv, send},
         RecievingTransport, SendingTransport, Transport,
+        wtx_ws::{recv, send_bytes, send_pkg},
       },
-      TransportGroup, WsParams,
     },
     pkg::{Package, PkgsAux},
-    Api,
   },
   misc::{LeaseMut, Stream, Vector},
-  web_socket::{compression::NegotiatedCompression, Frame, WebSocket, WebSocketBuffer},
+  web_socket::{Frame, WebSocket, WebSocketBuffer, compression::NegotiatedCompression},
 };
 use core::ops::Range;
 
@@ -41,7 +41,19 @@ where
   WSB: LeaseMut<WebSocketBuffer>,
 {
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
+    &mut self,
+    mut bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> Result<(), A::Error>
+  where
+    A: Api,
+  {
+    send_bytes(&mut bytes, pkgs_aux, self, cb).await
+  }
+
+  #[inline]
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -50,8 +62,7 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
   {
-    send(pkg, pkgs_aux, self, cb).await?;
-    Ok(())
+    send_pkg(pkg, pkgs_aux, self, cb).await
   }
 }
 
diff --git a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_parts_owned.rs b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_parts_owned.rs
index bf0475aa..599fd127 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_parts_owned.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_parts_owned.rs
@@ -1,16 +1,16 @@
 use crate::{
   client_api_framework::{
+    Api,
     network::{
-      transport::{RecievingTransport, SendingTransport, Transport},
       TransportGroup, WsParams,
+      transport::{RecievingTransport, SendingTransport, Transport},
     },
     pkg::{Package, PkgsAux},
-    Api,
   },
   misc::{LeaseMut, Lock, StreamReader, StreamWriter},
   web_socket::{
-    compression::NegotiatedCompression, WebSocketCommonPartOwned, WebSocketPartsOwned,
-    WebSocketWriterPartOwned,
+    WebSocketCommonPartOwned, WebSocketPartsOwned, WebSocketWriterPartOwned,
+    compression::NegotiatedCompression,
   },
 };
 use core::ops::Range;
@@ -44,7 +44,19 @@ where
   TP: LeaseMut<WsParams>,
 {
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
+    &mut self,
+    bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> Result<(), A::Error>
+  where
+    A: Api,
+  {
+    self.writer.send_bytes(bytes, pkgs_aux).await
+  }
+
+  #[inline]
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -53,7 +65,7 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
   {
-    self.writer.send(pkg, pkgs_aux).await
+    self.writer.send_pkg(pkg, pkgs_aux).await
   }
 }
 
diff --git a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_reader_part_owned.rs b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_reader_part_owned.rs
index ba08afe0..3accda87 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_reader_part_owned.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_reader_part_owned.rs
@@ -1,15 +1,15 @@
 use crate::{
   client_api_framework::{
+    Api,
     network::{
-      transport::{wtx_ws::recv, RecievingTransport, Transport},
       TransportGroup, WsParams,
+      transport::{RecievingTransport, Transport, wtx_ws::recv},
     },
     pkg::PkgsAux,
-    Api,
   },
   misc::{LeaseMut, Lock, StreamReader, StreamWriter},
   web_socket::{
-    compression::NegotiatedCompression, WebSocketCommonPartOwned, WebSocketReaderPartOwned,
+    WebSocketCommonPartOwned, WebSocketReaderPartOwned, compression::NegotiatedCompression,
   },
 };
 use core::ops::Range;
diff --git a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_writer_part_owned.rs b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_writer_part_owned.rs
index def61580..def98b8a 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_writer_part_owned.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_ws/web_socket_writer_part_owned.rs
@@ -1,15 +1,18 @@
 use crate::{
   client_api_framework::{
+    Api,
     network::{
-      transport::{wtx_ws::send, SendingTransport, Transport},
       TransportGroup, WsParams,
+      transport::{
+        SendingTransport, Transport,
+        wtx_ws::{send_bytes, send_pkg},
+      },
     },
     pkg::{Package, PkgsAux},
-    Api,
   },
   misc::{LeaseMut, Lock, StreamWriter, Vector},
   web_socket::{
-    compression::NegotiatedCompression, Frame, WebSocketCommonPartOwned, WebSocketWriterPartOwned,
+    Frame, WebSocketCommonPartOwned, WebSocketWriterPartOwned, compression::NegotiatedCompression,
   },
 };
 
@@ -21,7 +24,19 @@ where
   TP: LeaseMut<WsParams>,
 {
   #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
+    &mut self,
+    mut bytes: &[u8],
+    pkgs_aux: &mut PkgsAux<A, (), TP>,
+  ) -> Result<(), A::Error>
+  where
+    A: Api,
+  {
+    send_bytes(&mut bytes, pkgs_aux, self, cb).await
+  }
+
+  #[inline]
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     pkg: &mut P,
     pkgs_aux: &mut PkgsAux<A, DRSR, TP>,
@@ -30,8 +45,7 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Inner, TP>,
   {
-    send(pkg, pkgs_aux, self, cb).await?;
-    Ok(())
+    send_pkg(pkg, pkgs_aux, self, cb).await
   }
 }
 
diff --git a/wtx/src/client_api_framework/network/ws.rs b/wtx/src/client_api_framework/network/ws.rs
index b1e12692..6761e071 100644
--- a/wtx/src/client_api_framework/network/ws.rs
+++ b/wtx/src/client_api_framework/network/ws.rs
@@ -35,23 +35,15 @@ impl TransportParams for WsParams {
   type ExternalResponseParams = WsResParams;
 
   #[inline]
-  fn ext_req_params(&self) -> &Self::ExternalRequestParams {
-    &self.0
+  fn ext_params(&self) -> (&Self::ExternalRequestParams, &Self::ExternalResponseParams) {
+    (&self.0, &self.1)
   }
 
   #[inline]
-  fn ext_req_params_mut(&mut self) -> &mut Self::ExternalRequestParams {
-    &mut self.0
-  }
-
-  #[inline]
-  fn ext_res_params(&self) -> &Self::ExternalResponseParams {
-    &self.1
-  }
-
-  #[inline]
-  fn ext_res_params_mut(&mut self) -> &mut Self::ExternalResponseParams {
-    &mut self.1
+  fn ext_params_mut(
+    &mut self,
+  ) -> (&mut Self::ExternalRequestParams, &mut Self::ExternalResponseParams) {
+    (&mut self.0, &mut self.1)
   }
 
   #[inline]
diff --git a/wtx/src/client_api_framework/pkg.rs b/wtx/src/client_api_framework/pkg.rs
index 423c39d2..5708052d 100644
--- a/wtx/src/client_api_framework/pkg.rs
+++ b/wtx/src/client_api_framework/pkg.rs
@@ -8,8 +8,8 @@ mod pkgs_aux;
 
 use crate::{
   client_api_framework::Api,
-  data_transformation::dnsn::{Deserialize, Serialize},
-  misc::Vector,
+  data_transformation::dnsn::De,
+  misc::{DecodeSeq, Encode, Vector},
 };
 pub use batch_pkg::{BatchElems, BatchPkg};
 use core::future::Future;
@@ -29,9 +29,9 @@ where
   A: Api,
 {
   /// The expected data format that is going to be sent to an external actor.
-  type ExternalRequestContent: Serialize<DRSR>;
+  type ExternalRequestContent: Encode<De<DRSR>>;
   /// The expected data format returned by an external actor.
-  type ExternalResponseContent<'de>: Deserialize<'de, DRSR>;
+  type ExternalResponseContent<'de>: DecodeSeq<'de, De<DRSR>>;
   /// Any additional parameters used by this package.
   type PackageParams;
 
diff --git a/wtx/src/client_api_framework/pkg/batch_pkg.rs b/wtx/src/client_api_framework/pkg/batch_pkg.rs
index 0ffc5242..4ceb889c 100644
--- a/wtx/src/client_api_framework/pkg/batch_pkg.rs
+++ b/wtx/src/client_api_framework/pkg/batch_pkg.rs
@@ -1,7 +1,7 @@
 use crate::{
-  client_api_framework::{pkg::Package, Api},
-  data_transformation::dnsn::Serialize,
-  misc::Vector,
+  client_api_framework::{Api, pkg::Package},
+  data_transformation::dnsn::De,
+  misc::{Encode, Vector},
 };
 use core::marker::PhantomData;
 
@@ -20,7 +20,7 @@ impl<'slice, A, DRSR, P, T, TP> BatchPkg<'slice, A, DRSR, P, T, TP> {
 impl<'slice, A, DRSR, P, T, TP> Package<A, DRSR, T, TP> for BatchPkg<'slice, A, DRSR, P, T, TP>
 where
   A: Api,
-  BatchElems<'slice, A, DRSR, P, T, TP>: Serialize<DRSR>,
+  BatchElems<'slice, A, DRSR, P, T, TP>: Encode<De<DRSR>>,
   P: Package<A, DRSR, T, TP>,
 {
   type ExternalRequestContent = BatchElems<'slice, A, DRSR, P, T, TP>;
@@ -33,7 +33,7 @@ where
     (api, bytes, drsr): (&mut A, &mut Vector<u8>, &mut DRSR),
     (trans, trans_params): (&mut T, &mut TP),
   ) -> Result<(), A::Error> {
-    for elem in &mut *self.0 .0 {
+    for elem in &mut *self.0.0 {
       elem.after_sending((api, bytes, drsr), (trans, trans_params)).await?;
     }
     Ok(())
@@ -45,7 +45,7 @@ where
     (api, bytes, drsr): (&mut A, &mut Vector<u8>, &mut DRSR),
     (trans, trans_params): (&mut T, &mut TP),
   ) -> Result<(), A::Error> {
-    for elem in &mut *self.0 .0 {
+    for elem in &mut *self.0.0 {
       elem.before_sending((api, bytes, drsr), (trans, trans_params)).await?;
     }
     Ok(())
@@ -80,17 +80,16 @@ pub struct BatchElems<'slice, A, DRSR, P, T, TP>(&'slice mut [P], PhantomData<(A
 mod serde_json {
   use crate::{
     client_api_framework::{
+      Api,
       network::transport::Transport,
       pkg::{BatchElems, Package},
-      Api,
     },
-    data_transformation::dnsn::SerdeJson,
-    misc::Vector,
+    data_transformation::dnsn::{De, EncodeWrapper, SerdeJson},
+    misc::Encode,
   };
-  use serde::Serializer;
+  use serde::Serializer as _;
 
-  impl<A, DRSR, P, T, TP> crate::data_transformation::dnsn::Serialize<SerdeJson>
-    for BatchElems<'_, A, DRSR, P, T, TP>
+  impl<A, DRSR, P, T, TP> Encode<De<SerdeJson>> for BatchElems<'_, A, DRSR, P, T, TP>
   where
     A: Api,
     P: Package<A, DRSR, T, TP>,
@@ -98,8 +97,8 @@ mod serde_json {
     T: Transport<TP>,
   {
     #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut SerdeJson) -> crate::Result<()> {
-      serde_json::Serializer::new(bytes)
+    fn encode(&self, _: &mut SerdeJson, ew: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+      serde_json::Serializer::new(&mut *ew.vector)
         .collect_seq(self.0.iter().map(Package::ext_req_content))?;
       Ok(())
     }
diff --git a/wtx/src/client_api_framework/pkg/pkg_with_helper.rs b/wtx/src/client_api_framework/pkg/pkg_with_helper.rs
index 78bf7d01..d0b81be5 100644
--- a/wtx/src/client_api_framework/pkg/pkg_with_helper.rs
+++ b/wtx/src/client_api_framework/pkg/pkg_with_helper.rs
@@ -1,6 +1,6 @@
 use crate::{
-  client_api_framework::{pkg::Package, Api},
-  data_transformation::{format::JsonRpcRequest, Id},
+  client_api_framework::{Api, pkg::Package},
+  data_transformation::{Id, format::JsonRpcRequest},
   misc::Vector,
 };
 use core::{
diff --git a/wtx/src/client_api_framework/pkg/pkgs_aux.rs b/wtx/src/client_api_framework/pkg/pkgs_aux.rs
index 9fb60642..bc23ef28 100644
--- a/wtx/src/client_api_framework/pkg/pkgs_aux.rs
+++ b/wtx/src/client_api_framework/pkg/pkgs_aux.rs
@@ -1,7 +1,7 @@
 use crate::{
   data_transformation::{
-    format::{JsonRpcRequest, VerbatimRequest},
     Id,
+    format::{JsonRpcRequest, VerbatimRequest},
   },
   misc::Vector,
 };
diff --git a/wtx/src/data_transformation/dnsn.rs b/wtx/src/data_transformation/dnsn.rs
index 74529ce4..0ac3a7a6 100644
--- a/wtx/src/data_transformation/dnsn.rs
+++ b/wtx/src/data_transformation/dnsn.rs
@@ -9,12 +9,15 @@ mod tests;
 
 #[cfg(feature = "borsh")]
 mod borsh;
-mod deserialize;
+mod de;
+mod decode_wrapper;
+mod encode_wrapper;
 #[cfg(feature = "quick-protobuf")]
 mod quick_protobuf;
 #[cfg(feature = "serde_json")]
 mod serde_json;
-mod serialize;
+#[cfg(feature = "serde_urlencoded")]
+mod urlencoded;
 
 #[cfg(feature = "borsh")]
 pub use self::borsh::*;
@@ -22,5 +25,8 @@ pub use self::borsh::*;
 pub use self::quick_protobuf::*;
 #[cfg(feature = "serde_json")]
 pub use self::serde_json::*;
-pub use deserialize::*;
-pub use serialize::*;
+pub use de::De;
+pub use decode_wrapper::DecodeWrapper;
+pub use encode_wrapper::EncodeWrapper;
+#[cfg(feature = "serde_urlencoded")]
+pub use urlencoded::Urlencoded;
diff --git a/wtx/src/data_transformation/dnsn/de.rs b/wtx/src/data_transformation/dnsn/de.rs
new file mode 100644
index 00000000..7559cb1c
--- /dev/null
+++ b/wtx/src/data_transformation/dnsn/de.rs
@@ -0,0 +1,46 @@
+use crate::{
+  data_transformation::dnsn::{DecodeWrapper, EncodeWrapper},
+  misc::{Decode, DecodeSeq, Encode},
+};
+
+/// `D`ecode/`E`ncode
+#[derive(Debug)]
+pub struct De<DRSR>(core::marker::PhantomData<DRSR>);
+
+impl<DRSR> crate::misc::DEController for De<DRSR> {
+  type Aux = DRSR;
+  type DecodeWrapper<'inner, 'outer>
+    = DecodeWrapper<'inner>
+  where
+    'inner: 'outer;
+  type Error = crate::Error;
+  type EncodeWrapper<'inner, 'outer>
+    = EncodeWrapper<'inner>
+  where
+    'inner: 'outer;
+}
+
+impl<DRSR> Decode<'_, De<DRSR>> for () {
+  #[inline]
+  fn decode(_: &mut DRSR, _: &mut DecodeWrapper<'_>) -> crate::Result<Self> {
+    Ok(())
+  }
+}
+
+impl<DRSR> DecodeSeq<'_, De<DRSR>> for () {
+  #[inline]
+  fn decode_seq(
+    _: &mut DRSR,
+    _: &mut crate::misc::Vector<Self>,
+    _: &mut DecodeWrapper<'_>,
+  ) -> crate::Result<()> {
+    Ok(())
+  }
+}
+
+impl<DRSR> Encode<De<DRSR>> for () {
+  #[inline]
+  fn encode(&self, _: &mut DRSR, _: &mut EncodeWrapper<'_>) -> Result<(), crate::Error> {
+    Ok(())
+  }
+}
diff --git a/wtx/src/data_transformation/dnsn/decode_wrapper.rs b/wtx/src/data_transformation/dnsn/decode_wrapper.rs
new file mode 100644
index 00000000..b387d8b3
--- /dev/null
+++ b/wtx/src/data_transformation/dnsn/decode_wrapper.rs
@@ -0,0 +1,21 @@
+use crate::misc::Lease;
+
+/// Struct used for decoding elements in MySQL.
+#[derive(Debug, PartialEq)]
+pub struct DecodeWrapper<'de> {
+  pub(crate) bytes: &'de [u8],
+}
+
+impl<'de> DecodeWrapper<'de> {
+  #[inline]
+  pub(crate) fn _new(bytes: &'de [u8]) -> Self {
+    Self { bytes }
+  }
+}
+
+impl Lease<[u8]> for DecodeWrapper<'_> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.bytes
+  }
+}
diff --git a/wtx/src/data_transformation/dnsn/deserialize.rs b/wtx/src/data_transformation/dnsn/deserialize.rs
deleted file mode 100644
index 4b3a8d7e..00000000
--- a/wtx/src/data_transformation/dnsn/deserialize.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use crate::misc::Vector;
-
-/// Marker trait that has different bounds according to the given set of enabled deserializers.
-pub trait Deserialize<'de, DRSR>
-where
-  Self: Sized,
-{
-  /// Tries to create itself based on the passed amount of bytes.
-  fn from_bytes(bytes: &'de [u8], drsr: &mut DRSR) -> crate::Result<Self>;
-
-  /// Similar to [`Self::from_bytes`] but deals with sequences instead of a single element.
-  fn seq_from_bytes(
-    buffer: &mut Vector<Self>,
-    bytes: &'de [u8],
-    drsr: &mut DRSR,
-  ) -> crate::Result<()>;
-}
-
-impl<'de, DRSR> Deserialize<'de, DRSR> for () {
-  #[inline]
-  fn from_bytes(_: &'de [u8], _: &mut DRSR) -> crate::Result<Self> {
-    Ok(())
-  }
-
-  #[inline]
-  fn seq_from_bytes(_: &mut Vector<Self>, _: &'de [u8], _: &mut DRSR) -> crate::Result<()> {
-    Ok(())
-  }
-}
diff --git a/wtx/src/data_transformation/dnsn/encode_wrapper.rs b/wtx/src/data_transformation/dnsn/encode_wrapper.rs
new file mode 100644
index 00000000..77b7a2ca
--- /dev/null
+++ b/wtx/src/data_transformation/dnsn/encode_wrapper.rs
@@ -0,0 +1,21 @@
+use crate::misc::{Lease, Vector};
+
+/// Struct used for encoding elements in MySQL.
+#[derive(Debug)]
+pub struct EncodeWrapper<'any> {
+  pub(crate) vector: &'any mut Vector<u8>,
+}
+
+impl<'any> EncodeWrapper<'any> {
+  #[inline]
+  pub(crate) fn _new(vector: &'any mut Vector<u8>) -> Self {
+    Self { vector }
+  }
+}
+
+impl<'any> Lease<[u8]> for EncodeWrapper<'any> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.vector
+  }
+}
diff --git a/wtx/src/data_transformation/dnsn/serialize.rs b/wtx/src/data_transformation/dnsn/serialize.rs
deleted file mode 100644
index ef5dba88..00000000
--- a/wtx/src/data_transformation/dnsn/serialize.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use crate::misc::Vector;
-
-/// Marker trait that has different bounds according to the given set of enabled serializers.
-pub trait Serialize<DRSR> {
-  /// Tries to encode itself into the specified amount of mutable bytes.
-  fn to_bytes(&mut self, bytes: &mut Vector<u8>, drsr: &mut DRSR) -> crate::Result<()>;
-}
-
-impl<DRSR> Serialize<DRSR> for () {
-  #[inline]
-  fn to_bytes(&mut self, _: &mut Vector<u8>, _: &mut DRSR) -> crate::Result<()> {
-    Ok(())
-  }
-}
-
-impl<DRSR, T> Serialize<DRSR> for &mut T
-where
-  T: Serialize<DRSR>,
-{
-  #[inline]
-  fn to_bytes(&mut self, bytes: &mut Vector<u8>, drsr: &mut DRSR) -> crate::Result<()> {
-    (*self).to_bytes(bytes, drsr)
-  }
-}
diff --git a/wtx/src/data_transformation/dnsn/urlencoded.rs b/wtx/src/data_transformation/dnsn/urlencoded.rs
new file mode 100644
index 00000000..db99c3bf
--- /dev/null
+++ b/wtx/src/data_transformation/dnsn/urlencoded.rs
@@ -0,0 +1,19 @@
+use crate::misc::{Lease, LeaseMut};
+
+/// Type that indicates messages encoded or decoded with percent-encoding
+#[derive(Debug, Default)]
+pub struct Urlencoded;
+
+impl Lease<Urlencoded> for Urlencoded {
+  #[inline]
+  fn lease(&self) -> &Urlencoded {
+    self
+  }
+}
+
+impl LeaseMut<Urlencoded> for Urlencoded {
+  #[inline]
+  fn lease_mut(&mut self) -> &mut Urlencoded {
+    self
+  }
+}
diff --git a/wtx/src/data_transformation/format/graph_ql/graph_ql_request.rs b/wtx/src/data_transformation/format/graph_ql/graph_ql_request.rs
index ce4ca770..49c6d4dc 100644
--- a/wtx/src/data_transformation/format/graph_ql/graph_ql_request.rs
+++ b/wtx/src/data_transformation/format/graph_ql/graph_ql_request.rs
@@ -1,4 +1,7 @@
-use crate::{data_transformation::dnsn::Serialize, misc::Vector};
+use crate::{
+  data_transformation::dnsn::{De, DecodeWrapper, EncodeWrapper},
+  misc::{Decode, DecodeSeq, Encode, Vector},
+};
 
 /// `GraphQL` request/operation, can be a query or a mutation.
 #[cfg_attr(feature = "serde", derive(serde::Serialize))]
@@ -14,44 +17,43 @@ pub struct GraphQlRequest<ON, Q, V> {
   pub variables: Option<V>,
 }
 
-impl<ON, Q, V> Serialize<()> for GraphQlRequest<ON, Q, V> {
+impl<'de, ON, Q, V> Decode<'de, De<()>> for GraphQlRequest<ON, Q, V>
+where
+  Q: Default,
+{
   #[inline]
-  fn to_bytes(&mut self, _: &mut Vector<u8>, _: &mut ()) -> crate::Result<()> {
-    Ok(())
+  fn decode(_: &mut (), _: &mut DecodeWrapper<'de>) -> crate::Result<Self> {
+    Ok(Self { operation_name: None, query: Q::default(), variables: None })
   }
 }
 
-impl<DRSR, ON, Q, V> Serialize<&mut DRSR> for GraphQlRequest<ON, Q, V>
+impl<'de, ON, Q, V> DecodeSeq<'de, De<()>> for GraphQlRequest<ON, Q, V>
 where
-  GraphQlRequest<ON, Q, V>: Serialize<DRSR>,
+  Q: Default,
 {
   #[inline]
-  fn to_bytes(&mut self, bytes: &mut Vector<u8>, drsr: &mut &mut DRSR) -> crate::Result<()> {
-    self.to_bytes(bytes, drsr)
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut DecodeWrapper<'de>) -> crate::Result<()> {
+    Ok(())
+  }
+}
+
+impl<ON, Q, V> Encode<De<()>> for GraphQlRequest<ON, Q, V> {
+  #[inline]
+  fn encode(&self, _: &mut (), _: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+    Ok(())
   }
 }
 
 #[cfg(feature = "serde_json")]
 mod serde_json {
-  use crate::{
-    data_transformation::{dnsn::SerdeJson, format::GraphQlRequest},
-    misc::Vector,
-  };
+  use crate::data_transformation::{dnsn::SerdeJson, format::GraphQlRequest};
   use serde::Serialize;
 
-  impl<ON, Q, V> crate::data_transformation::dnsn::Serialize<SerdeJson> for GraphQlRequest<ON, Q, V>
-  where
-    ON: Serialize,
-    Q: Serialize,
-    V: Serialize,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut SerdeJson) -> crate::Result<()> {
-      if size_of::<Self>() == 0 {
-        return Ok(());
-      }
-      serde_json::to_writer(bytes, self)?;
-      Ok(())
+  _impl_enc! {
+    GraphQlRequest<ON: Serialize, Q: Serialize, V: Serialize>,
+    SerdeJson,
+    |this, _aux, ew| {
+      serde_json::to_writer(&mut *ew.vector, this)?;
     }
   }
 }
diff --git a/wtx/src/data_transformation/format/graph_ql/graph_ql_response.rs b/wtx/src/data_transformation/format/graph_ql/graph_ql_response.rs
index d27fe03c..d8eacb71 100644
--- a/wtx/src/data_transformation/format/graph_ql/graph_ql_response.rs
+++ b/wtx/src/data_transformation/format/graph_ql/graph_ql_response.rs
@@ -1,9 +1,9 @@
 use crate::{
   data_transformation::{
-    dnsn::{Deserialize, Serialize},
+    dnsn::{De, DecodeWrapper, EncodeWrapper},
     format::GraphQlResponseError,
   },
-  misc::Vector,
+  misc::{Decode, DecodeSeq, Encode, Vector},
 };
 
 /// Replied from an issued [`crate::data_transformation::format::GraphQlRequest`].
@@ -13,54 +13,30 @@ pub struct GraphQlResponse<D, E> {
   pub result: Result<D, Vector<GraphQlResponseError<E>>>,
 }
 
-impl<'de, D, E> Deserialize<'de, ()> for GraphQlResponse<D, E>
+impl<'de, D, E> Decode<'de, De<()>> for GraphQlResponse<D, E>
 where
   D: Default,
 {
   #[inline]
-  fn from_bytes(_: &[u8], _: &mut ()) -> crate::Result<Self> {
+  fn decode(_: &mut (), _: &mut DecodeWrapper<'de>) -> crate::Result<Self> {
     Ok(Self { result: Ok(D::default()) })
   }
-
-  #[inline]
-  fn seq_from_bytes(_: &mut Vector<Self>, _: &'de [u8], _: &mut ()) -> crate::Result<()> {
-    Ok(())
-  }
 }
 
-impl<'de, D, DRSR, E> Deserialize<'de, &mut DRSR> for GraphQlResponse<D, E>
+impl<'de, D, E> DecodeSeq<'de, De<()>> for GraphQlResponse<D, E>
 where
-  GraphQlResponse<D, E>: Deserialize<'de, DRSR>,
+  D: Default,
 {
   #[inline]
-  fn from_bytes(bytes: &'de [u8], drsr: &mut &mut DRSR) -> crate::Result<Self> {
-    <GraphQlResponse<D, E>>::from_bytes(bytes, drsr)
-  }
-
-  #[inline]
-  fn seq_from_bytes(
-    buffer: &mut Vector<Self>,
-    bytes: &'de [u8],
-    drsr: &mut &mut DRSR,
-  ) -> crate::Result<()> {
-    <GraphQlResponse<D, E>>::seq_from_bytes(buffer, bytes, drsr)
-  }
-}
-
-impl<D, E> Serialize<()> for GraphQlResponse<D, E> {
-  #[inline]
-  fn to_bytes(&mut self, _: &mut Vector<u8>, _: &mut ()) -> crate::Result<()> {
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut DecodeWrapper<'de>) -> crate::Result<()> {
     Ok(())
   }
 }
 
-impl<D, DRSR, E> Serialize<&mut DRSR> for GraphQlResponse<D, E>
-where
-  GraphQlResponse<D, E>: Serialize<DRSR>,
-{
+impl<D, E> Encode<De<()>> for GraphQlResponse<D, E> {
   #[inline]
-  fn to_bytes(&mut self, bytes: &mut Vector<u8>, drsr: &mut &mut DRSR) -> crate::Result<()> {
-    self.to_bytes(bytes, drsr)
+  fn encode(&self, _: &mut (), _: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+    Ok(())
   }
 }
 
@@ -72,9 +48,9 @@ mod serde {
   };
   use core::marker::PhantomData;
   use serde::{
+    Deserialize, Serialize,
     de::{Deserializer, MapAccess, Visitor},
     ser::{SerializeStruct, Serializer},
-    Deserialize, Serialize,
   };
 
   impl<'de, D, E> Deserialize<'de> for GraphQlResponse<D, E>
@@ -87,6 +63,13 @@ mod serde {
     where
       DE: Deserializer<'de>,
     {
+      #[derive(Debug, serde::Deserialize)]
+      #[serde(field_identifier, rename_all = "lowercase")]
+      enum Field {
+        Data,
+        Errors,
+      }
+
       struct CustomVisitor<'de, D, E>(PhantomData<(D, E)>, PhantomData<&'de ()>)
       where
         D: Deserialize<'de>,
@@ -167,59 +150,37 @@ mod serde {
       state.end()
     }
   }
-
-  #[derive(Debug, serde::Deserialize)]
-  #[serde(field_identifier, rename_all = "lowercase")]
-  enum Field {
-    Data,
-    Errors,
-  }
 }
 
 #[cfg(feature = "serde_json")]
 mod serde_json {
-  use crate::{
-    data_transformation::{
-      dnsn::SerdeJson,
-      format::{misc::collect_using_serde_json, GraphQlResponse},
-    },
-    misc::Vector,
+  use crate::data_transformation::{
+    dnsn::SerdeJson,
+    format::{GraphQlResponse, misc::collect_using_serde_json},
   };
   use serde::{Deserialize, Serialize};
 
-  impl<'de, D, E> crate::data_transformation::dnsn::Deserialize<'de, SerdeJson>
-    for GraphQlResponse<D, E>
-  where
-    D: Deserialize<'de>,
-    E: Deserialize<'de>,
-  {
-    #[inline]
-    fn from_bytes(bytes: &'de [u8], _: &mut SerdeJson) -> crate::Result<Self> {
-      Ok(serde_json::from_slice(bytes)?)
+  _impl_dec! {
+    GraphQlResponse<D: Deserialize<'de>, E: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, dw| {
+      Ok(serde_json::from_slice(dw.bytes)?)
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(
-      buffer: &mut Vector<Self>,
-      bytes: &'de [u8],
-      _: &mut SerdeJson,
-    ) -> crate::Result<()> {
-      collect_using_serde_json(buffer, bytes)
+  _impl_dec_seq! {
+    GraphQlResponse<D: Deserialize<'de>, E: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, buffer, dw| {
+      collect_using_serde_json(buffer, &mut dw.bytes)
     }
   }
 
-  impl<D, E> crate::data_transformation::dnsn::Serialize<SerdeJson> for GraphQlResponse<D, E>
-  where
-    D: Serialize,
-    E: Serialize,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut SerdeJson) -> crate::Result<()> {
-      if size_of::<Self>() == 0 {
-        return Ok(());
-      }
-      serde_json::to_writer(bytes, &self.result)?;
-      Ok(())
+  _impl_enc! {
+    GraphQlResponse<D: Serialize, E: Serialize>,
+    SerdeJson,
+    |this, _aux, ew| {
+      serde_json::to_writer(&mut *ew.vector, &this.result)?;
     }
   }
 }
diff --git a/wtx/src/data_transformation/format/json_rpc/json_rpc_request.rs b/wtx/src/data_transformation/format/json_rpc/json_rpc_request.rs
index 88da3e2f..4eab7233 100644
--- a/wtx/src/data_transformation/format/json_rpc/json_rpc_request.rs
+++ b/wtx/src/data_transformation/format/json_rpc/json_rpc_request.rs
@@ -1,6 +1,9 @@
 use crate::{
-  data_transformation::{dnsn::Serialize, Id},
-  misc::{Lease, Vector},
+  data_transformation::{
+    Id,
+    dnsn::{De, DecodeWrapper, EncodeWrapper},
+  },
+  misc::{Decode, DecodeSeq, Encode, Lease, Vector},
 };
 use core::{
   borrow::Borrow,
@@ -21,20 +24,23 @@ pub struct JsonRpcRequest<P> {
   pub params: P,
 }
 
-impl<P> Serialize<()> for JsonRpcRequest<P> {
+impl<'de, P> Decode<'de, De<()>> for JsonRpcRequest<P>
+where
+  P: Default,
+{
   #[inline]
-  fn to_bytes(&mut self, _: &mut Vector<u8>, _: &mut ()) -> crate::Result<()> {
-    Ok(())
+  fn decode(_: &mut (), _: &mut DecodeWrapper<'de>) -> crate::Result<Self> {
+    Ok(Self { id: 0, method: "", params: P::default() })
   }
 }
 
-impl<DRSR, P> Serialize<&mut DRSR> for JsonRpcRequest<P>
+impl<'de, P> DecodeSeq<'de, De<()>> for JsonRpcRequest<P>
 where
-  JsonRpcRequest<P>: Serialize<DRSR>,
+  P: Default,
 {
   #[inline]
-  fn to_bytes(&mut self, bytes: &mut Vector<u8>, drsr: &mut &mut DRSR) -> crate::Result<()> {
-    self.to_bytes(bytes, drsr)
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut DecodeWrapper<'de>) -> crate::Result<()> {
+    Ok(())
   }
 }
 
@@ -45,6 +51,13 @@ impl<P> Borrow<Id> for JsonRpcRequest<P> {
   }
 }
 
+impl<P> Encode<De<()>> for JsonRpcRequest<P> {
+  #[inline]
+  fn encode(&self, _: &mut (), _: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+    Ok(())
+  }
+}
+
 impl<P> Eq for JsonRpcRequest<P> {}
 
 impl<P> Hash for JsonRpcRequest<P> {
@@ -89,8 +102,8 @@ impl<P> PartialOrd for JsonRpcRequest<P> {
 mod serde {
   use crate::data_transformation::format::JsonRpcRequest;
   use serde::{
-    ser::{SerializeStruct, Serializer},
     Serialize,
+    ser::{SerializeStruct, Serializer},
   };
 
   impl<P> Serialize for JsonRpcRequest<P>
@@ -116,19 +129,14 @@ mod serde {
 
 #[cfg(feature = "serde_json")]
 mod serde_json {
-  use crate::{
-    data_transformation::{dnsn::SerdeJson, format::JsonRpcRequest},
-    misc::Vector,
-  };
+  use crate::data_transformation::{dnsn::SerdeJson, format::JsonRpcRequest};
+  use serde::Serialize;
 
-  impl<P> crate::data_transformation::dnsn::Serialize<SerdeJson> for JsonRpcRequest<P>
-  where
-    P: serde::Serialize,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut SerdeJson) -> crate::Result<()> {
-      serde_json::to_writer(bytes, self)?;
-      Ok(())
+  _impl_enc! {
+    JsonRpcRequest<R: Serialize>,
+    SerdeJson,
+    |this, _aux, ew| {
+      serde_json::to_writer(&mut *ew.vector, this)?;
     }
   }
 }
diff --git a/wtx/src/data_transformation/format/json_rpc/json_rpc_response.rs b/wtx/src/data_transformation/format/json_rpc/json_rpc_response.rs
index e460b3fe..8b019053 100644
--- a/wtx/src/data_transformation/format/json_rpc/json_rpc_response.rs
+++ b/wtx/src/data_transformation/format/json_rpc/json_rpc_response.rs
@@ -1,9 +1,9 @@
 use crate::{
   data_transformation::{
-    dnsn::{Deserialize, Serialize},
     Id,
+    dnsn::{De, DecodeWrapper, EncodeWrapper},
   },
-  misc::{Lease, Vector},
+  misc::{Decode, DecodeSeq, Encode, Lease, Vector},
 };
 use alloc::boxed::Box;
 use core::{
@@ -25,51 +25,37 @@ pub struct JsonRpcResponse<R> {
   pub result: crate::Result<R>,
 }
 
-impl<'de, D> Deserialize<'de, ()> for JsonRpcResponse<D>
-where
-  D: Default,
-{
-  #[inline]
-  fn from_bytes(_: &'de [u8], _: &mut ()) -> crate::Result<Self> {
-    Ok(Self { id: 0, method: None, result: Ok(D::default()) })
-  }
-
+impl<P> Borrow<Id> for JsonRpcResponse<P> {
   #[inline]
-  fn seq_from_bytes(_: &mut Vector<Self>, _: &'de [u8], _: &mut ()) -> crate::Result<()> {
-    Ok(())
+  fn borrow(&self) -> &Id {
+    &self.id
   }
 }
 
-impl<'de, D, DRSR> Deserialize<'de, &mut DRSR> for JsonRpcResponse<D>
+impl<'de, R> Decode<'de, De<()>> for JsonRpcResponse<R>
 where
-  JsonRpcResponse<D>: Deserialize<'de, DRSR>,
+  R: Default,
 {
   #[inline]
-  fn from_bytes(bytes: &'de [u8], drsr: &mut &mut DRSR) -> crate::Result<Self> {
-    <JsonRpcResponse<D>>::from_bytes(bytes, drsr)
-  }
-
-  #[inline]
-  fn seq_from_bytes(
-    buffer: &mut Vector<Self>,
-    bytes: &'de [u8],
-    drsr: &mut &mut DRSR,
-  ) -> crate::Result<()> {
-    <JsonRpcResponse<D>>::seq_from_bytes(buffer, bytes, drsr)
+  fn decode(_: &mut (), _: &mut DecodeWrapper<'de>) -> crate::Result<Self> {
+    Ok(Self { id: 0, method: None, result: Ok(R::default()) })
   }
 }
 
-impl<D> Serialize<()> for JsonRpcResponse<D> {
+impl<'de, R> DecodeSeq<'de, De<()>> for JsonRpcResponse<R>
+where
+  R: Default,
+{
   #[inline]
-  fn to_bytes(&mut self, _: &mut Vector<u8>, _: &mut ()) -> crate::Result<()> {
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut DecodeWrapper<'de>) -> crate::Result<()> {
     Ok(())
   }
 }
 
-impl<P> Borrow<Id> for JsonRpcResponse<P> {
+impl<D> Encode<De<()>> for JsonRpcResponse<D> {
   #[inline]
-  fn borrow(&self) -> &Id {
-    &self.id
+  fn encode(&self, _: &mut (), _: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+    Ok(())
   }
 }
 
@@ -116,14 +102,14 @@ impl<R> PartialOrd for JsonRpcResponse<R> {
 #[cfg(feature = "serde")]
 mod serde {
   use crate::data_transformation::{
-    format::{JsonRpcResponse, JsonRpcResponseError},
     DataTransformationError,
+    format::{JsonRpcResponse, JsonRpcResponseError},
   };
   use core::marker::PhantomData;
   use serde::{
+    Deserialize, Serialize,
     de::{Deserializer, MapAccess, Visitor},
     ser::{SerializeStruct, Serializer},
-    Deserialize, Serialize,
   };
 
   impl<'de, R> Deserialize<'de> for JsonRpcResponse<R>
@@ -264,41 +250,33 @@ mod serde {
 
 #[cfg(feature = "serde_json")]
 mod serde_json {
-  use crate::{
-    data_transformation::{
-      dnsn::SerdeJson,
-      format::{misc::collect_using_serde_json, JsonRpcResponse},
-    },
-    misc::Vector,
+  use crate::data_transformation::{
+    dnsn::SerdeJson,
+    format::{JsonRpcResponse, misc::collect_using_serde_json},
   };
+  use serde::{Deserialize, Serialize};
 
-  impl<'de, R> crate::data_transformation::dnsn::Deserialize<'de, SerdeJson> for JsonRpcResponse<R>
-  where
-    R: serde::Deserialize<'de>,
-  {
-    #[inline]
-    fn from_bytes(bytes: &'de [u8], _: &mut SerdeJson) -> crate::Result<Self> {
-      Ok(serde_json::from_slice(bytes)?)
+  _impl_dec! {
+    JsonRpcResponse<R: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, dw| {
+      Ok(serde_json::from_slice(dw.bytes)?)
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(
-      buffer: &mut Vector<Self>,
-      bytes: &'de [u8],
-      _: &mut SerdeJson,
-    ) -> crate::Result<()> {
-      collect_using_serde_json(buffer, bytes)
+  _impl_dec_seq! {
+    JsonRpcResponse<R: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, buffer, dw| {
+      collect_using_serde_json(buffer, &mut dw.bytes)
     }
   }
 
-  impl<R> crate::data_transformation::dnsn::Serialize<SerdeJson> for JsonRpcResponse<R>
-  where
-    R: serde::Serialize,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut SerdeJson) -> crate::Result<()> {
-      serde_json::to_writer(bytes, self)?;
-      Ok(())
+  _impl_enc! {
+    JsonRpcResponse<R: Serialize>,
+    SerdeJson,
+    |this, _aux, ew| {
+      serde_json::to_writer(&mut *ew.vector, this)?;
     }
   }
 }
diff --git a/wtx/src/data_transformation/format/misc.rs b/wtx/src/data_transformation/format/misc.rs
index ae7bfdb4..2f352ee2 100644
--- a/wtx/src/data_transformation/format/misc.rs
+++ b/wtx/src/data_transformation/format/misc.rs
@@ -6,13 +6,13 @@ mod serde_json {
   use crate::misc::Vector;
   use core::{any::type_name, fmt::Formatter};
   use serde::{
-    de::{Deserializer, Error, SeqAccess, Visitor},
     Deserialize,
+    de::{Deserializer, Error, SeqAccess, Visitor},
   };
 
   pub(crate) fn collect_using_serde_json<'de, T>(
     buffer: &mut Vector<T>,
-    bytes: &'de [u8],
+    bytes: &mut &'de [u8],
   ) -> crate::Result<()>
   where
     T: Deserialize<'de>,
@@ -65,7 +65,7 @@ mod serde_json {
     fn array_is_deserialized() {
       let json = r#"[{"a":1,"b":90},{"a":7,"b":567}]"#;
       let mut vector = Vector::<Foo>::new();
-      collect_using_serde_json(&mut vector, json.as_bytes()).unwrap();
+      collect_using_serde_json(&mut vector, &mut json.as_bytes()).unwrap();
       assert_eq!(vector.as_slice(), &[Foo { a: 1, b: 90 }, Foo { a: 7, b: 567 }]);
     }
   }
diff --git a/wtx/src/data_transformation/format/verbatim/verbatim_request.rs b/wtx/src/data_transformation/format/verbatim/verbatim_request.rs
index 62887bef..504b7fc2 100644
--- a/wtx/src/data_transformation/format/verbatim/verbatim_request.rs
+++ b/wtx/src/data_transformation/format/verbatim/verbatim_request.rs
@@ -1,125 +1,167 @@
-use crate::{data_transformation::dnsn::Serialize, misc::Vector};
+use crate::{
+  data_transformation::dnsn::{De, DecodeWrapper, EncodeWrapper},
+  misc::{Decode, DecodeSeq, Encode, Vector},
+};
 
 /// A wrapper for data types that don't require a special pre-fixed structure.
 #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
+#[cfg_attr(feature = "serde", serde(transparent))]
 pub struct VerbatimRequest<D> {
   /// Actual data
   pub data: D,
 }
 
-impl<D> Serialize<()> for VerbatimRequest<D> {
+impl<'de, D> Decode<'de, De<()>> for VerbatimRequest<D>
+where
+  D: Default,
+{
   #[inline]
-  fn to_bytes(&mut self, _: &mut Vector<u8>, _: &mut ()) -> crate::Result<()> {
-    Ok(())
+  fn decode(_: &mut (), _: &mut DecodeWrapper<'de>) -> crate::Result<Self> {
+    Ok(Self { data: D::default() })
   }
 }
 
-impl<D, DRSR> Serialize<&mut DRSR> for VerbatimRequest<D>
+impl<'de, D> DecodeSeq<'de, De<()>> for VerbatimRequest<D>
 where
-  VerbatimRequest<D>: Serialize<DRSR>,
+  D: Default,
 {
   #[inline]
-  fn to_bytes(&mut self, bytes: &mut Vector<u8>, drsr: &mut &mut DRSR) -> crate::Result<()> {
-    self.to_bytes(bytes, drsr)
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut DecodeWrapper<'de>) -> crate::Result<()> {
+    Ok(())
+  }
+}
+
+impl<D> Encode<De<()>> for VerbatimRequest<D> {
+  #[inline]
+  fn encode(&self, _: &mut (), _: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+    Ok(())
   }
 }
 
 #[cfg(feature = "borsh")]
 mod borsh {
-  use crate::{
-    data_transformation::{dnsn::Borsh, format::VerbatimRequest},
-    misc::Vector,
-  };
+  use crate::data_transformation::{DataTransformationError, dnsn::Borsh, format::VerbatimRequest};
   use borsh::{BorshDeserialize, BorshSerialize};
 
-  impl<'de, D> crate::data_transformation::dnsn::Deserialize<'de, Borsh> for VerbatimRequest<D>
-  where
-    D: BorshDeserialize,
-  {
-    #[inline]
-    fn from_bytes(mut bytes: &'de [u8], _: &mut Borsh) -> crate::Result<Self> {
-      Ok(Self { data: D::deserialize(&mut bytes)? })
+  _impl_dec! {
+    VerbatimRequest<D: BorshDeserialize>,
+    Borsh,
+    |_aux, dw| {
+      Ok(Self { data: D::deserialize(&mut dw.bytes)? })
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(_: &mut Vector<Self>, _: &'de [u8], _: &mut Borsh) -> crate::Result<()> {
-      Ok(())
+  _impl_dec_seq! {
+    VerbatimRequest<D: BorshDeserialize>,
+    Borsh,
+    |_aux, _buffer, _dw| {
+      Err(DataTransformationError::UnsupportedOperation.into())
     }
   }
 
-  impl<D> crate::data_transformation::dnsn::Serialize<Borsh> for VerbatimRequest<D>
-  where
-    D: BorshSerialize,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut Borsh) -> crate::Result<()> {
-      self.data.serialize(bytes)?;
-      Ok(())
+  _impl_enc! {
+    VerbatimRequest<D: BorshSerialize>,
+    Borsh,
+    |this, _aux, ew| {
+      this.data.serialize(&mut ew.vector)?;
     }
   }
 }
 
 #[cfg(feature = "quick-protobuf")]
 mod quick_protobuf {
-  use crate::{
-    data_transformation::{
-      dnsn::{Deserialize, QuickProtobuf, Serialize},
-      format::VerbatimRequest,
-      DataTransformationError,
-    },
-    misc::Vector,
+  use crate::data_transformation::{
+    DataTransformationError, dnsn::QuickProtobuf, format::VerbatimRequest,
   };
   use quick_protobuf::{BytesReader, MessageRead, MessageWrite, Writer};
 
-  impl<'de, D> Deserialize<'de, QuickProtobuf> for VerbatimRequest<D>
-  where
-    D: MessageRead<'de>,
-  {
-    #[inline]
-    fn from_bytes(bytes: &'de [u8], _: &mut QuickProtobuf) -> crate::Result<Self> {
-      Ok(Self { data: MessageRead::from_reader(&mut BytesReader::from_bytes(bytes), bytes)? })
+  _impl_dec! {
+    VerbatimRequest<D: MessageRead<'de>>,
+    QuickProtobuf,
+    |_aux, dw| {
+      Ok(Self { data: MessageRead::from_reader(&mut BytesReader::from_bytes(dw.bytes), dw.bytes)? })
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(
-      _: &mut Vector<Self>,
-      _: &'de [u8],
-      _: &mut QuickProtobuf,
-    ) -> crate::Result<()> {
+  _impl_dec_seq! {
+    VerbatimRequest<D: MessageRead<'de>>,
+    QuickProtobuf,
+    |_aux, _buffer, _dw| {
       Err(DataTransformationError::UnsupportedOperation.into())
     }
   }
 
-  impl<D> Serialize<QuickProtobuf> for VerbatimRequest<D>
-  where
-    D: MessageWrite,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut QuickProtobuf) -> crate::Result<()> {
-      self.data.write_message(&mut Writer::new(bytes))?;
-      Ok(())
+  _impl_enc! {
+    VerbatimRequest<D: MessageWrite>,
+    QuickProtobuf,
+    |this, _aux, ew| {
+      this.data.write_message(&mut Writer::new(&mut *ew.vector))?;
     }
   }
 }
 
 #[cfg(feature = "serde_json")]
 mod serde_json {
-  use crate::{
-    data_transformation::{dnsn::SerdeJson, format::VerbatimRequest},
-    misc::Vector,
+  use crate::data_transformation::{
+    dnsn::SerdeJson,
+    format::{VerbatimRequest, misc::collect_using_serde_json},
+  };
+  use serde::{Deserialize, Serialize};
+
+  _impl_dec! {
+    VerbatimRequest<D: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, dw| {
+      Ok(serde_json::from_slice(dw.bytes)?)
+    }
+  }
+
+  _impl_dec_seq! {
+    VerbatimRequest<D: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, buffer, dw| {
+      collect_using_serde_json(buffer, &mut dw.bytes)
+    }
+  }
+
+  _impl_enc! {
+    VerbatimRequest<D: Serialize>,
+    SerdeJson,
+    |this, _aux, ew| {
+      serde_json::to_writer(&mut *ew.vector, &this.data)?;
+    }
+  }
+}
+
+#[cfg(feature = "serde_urlencoded")]
+mod urlencoded {
+  use crate::data_transformation::{
+    DataTransformationError, dnsn::Urlencoded, format::VerbatimRequest,
   };
+  use serde::{Deserialize, Serialize};
+
+  _impl_dec! {
+    VerbatimRequest<D: Deserialize<'de>>,
+    Urlencoded,
+    |_aux, dw| {
+      Ok(serde_urlencoded::from_bytes(dw.bytes)?)
+    }
+  }
+
+  _impl_dec_seq! {
+    VerbatimRequest<D: Deserialize<'de>>,
+    Urlencoded,
+    |_aux, _buffer, _dw| {
+      Err(DataTransformationError::UnsupportedOperation.into())
+    }
+  }
 
-  impl<D> crate::data_transformation::dnsn::Serialize<SerdeJson> for VerbatimRequest<D>
-  where
-    D: serde::Serialize,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut SerdeJson) -> crate::Result<()> {
-      if size_of::<D>() == 0 {
-        return Ok(());
-      }
-      serde_json::to_writer(bytes, &self.data)?;
-      Ok(())
+  _impl_enc! {
+    VerbatimRequest<D: Serialize>,
+    Urlencoded,
+    |this, _aux, ew| {
+      ew.vector.extend_from_copyable_slice(serde_urlencoded::to_string(&this.data)?.as_bytes())?;
     }
   }
 }
diff --git a/wtx/src/data_transformation/format/verbatim/verbatim_response.rs b/wtx/src/data_transformation/format/verbatim/verbatim_response.rs
index ff732aa0..826d7e22 100644
--- a/wtx/src/data_transformation/format/verbatim/verbatim_response.rs
+++ b/wtx/src/data_transformation/format/verbatim/verbatim_response.rs
@@ -1,6 +1,6 @@
 use crate::{
-  data_transformation::dnsn::{Deserialize, Serialize},
-  misc::Vector,
+  data_transformation::dnsn::{De, DecodeWrapper, EncodeWrapper},
+  misc::{Decode, DecodeSeq, Encode, Vector},
 };
 
 #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
@@ -12,164 +12,158 @@ pub struct VerbatimResponse<D> {
   pub data: D,
 }
 
-impl<'de, D> Deserialize<'de, ()> for VerbatimResponse<D>
+impl<'de, D> Decode<'de, De<()>> for VerbatimResponse<D>
 where
   D: Default,
 {
   #[inline]
-  fn from_bytes(_: &[u8], _: &mut ()) -> crate::Result<Self> {
+  fn decode(_: &mut (), _: &mut DecodeWrapper<'de>) -> crate::Result<Self> {
     Ok(Self { data: D::default() })
   }
-
-  #[inline]
-  fn seq_from_bytes(_: &mut Vector<Self>, _: &'de [u8], _: &mut ()) -> crate::Result<()> {
-    Ok(())
-  }
 }
 
-impl<'de, D, DRSR> Deserialize<'de, &mut DRSR> for VerbatimResponse<D>
+impl<'de, D> DecodeSeq<'de, De<()>> for VerbatimResponse<D>
 where
-  VerbatimResponse<D>: Deserialize<'de, DRSR>,
+  D: Default,
 {
   #[inline]
-  fn from_bytes(bytes: &'de [u8], drsr: &mut &mut DRSR) -> crate::Result<Self> {
-    <VerbatimResponse<D>>::from_bytes(bytes, drsr)
-  }
-
-  #[inline]
-  fn seq_from_bytes(
-    buffer: &mut Vector<Self>,
-    bytes: &'de [u8],
-    drsr: &mut &mut DRSR,
-  ) -> crate::Result<()> {
-    <VerbatimResponse<D>>::seq_from_bytes(buffer, bytes, drsr)
-  }
-}
-
-impl<D> Serialize<()> for VerbatimResponse<D> {
-  #[inline]
-  fn to_bytes(&mut self, _: &mut Vector<u8>, _: &mut ()) -> crate::Result<()> {
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut DecodeWrapper<'de>) -> crate::Result<()> {
     Ok(())
   }
 }
 
-impl<D, DRSR> Serialize<&mut DRSR> for VerbatimResponse<D>
-where
-  VerbatimResponse<D>: Serialize<DRSR>,
-{
+impl<D> Encode<De<()>> for VerbatimResponse<D> {
   #[inline]
-  fn to_bytes(&mut self, bytes: &mut Vector<u8>, drsr: &mut &mut DRSR) -> crate::Result<()> {
-    self.to_bytes(bytes, drsr)
+  fn encode(&self, _: &mut (), _: &mut EncodeWrapper<'_>) -> crate::Result<()> {
+    Ok(())
   }
 }
 
 #[cfg(feature = "borsh")]
 mod borsh {
-  use crate::{
-    data_transformation::{dnsn::Borsh, format::VerbatimResponse, DataTransformationError},
-    misc::Vector,
+  use crate::data_transformation::{
+    DataTransformationError, dnsn::Borsh, format::VerbatimResponse,
   };
-  use borsh::BorshDeserialize;
-
-  impl<'de, D> crate::data_transformation::dnsn::Deserialize<'de, Borsh> for VerbatimResponse<D>
-  where
-    D: BorshDeserialize,
-  {
-    #[inline]
-    fn from_bytes(mut bytes: &'de [u8], _: &mut Borsh) -> crate::Result<Self> {
-      Ok(Self { data: D::deserialize(&mut bytes)? })
+  use borsh::{BorshDeserialize, BorshSerialize};
+
+  _impl_dec! {
+    VerbatimResponse<D: BorshDeserialize>,
+    Borsh,
+    |_aux, dw| {
+      Ok(Self { data: D::deserialize(&mut dw.bytes)? })
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(_: &mut Vector<Self>, _: &'de [u8], _: &mut Borsh) -> crate::Result<()> {
+  _impl_dec_seq! {
+    VerbatimResponse<D: BorshDeserialize>,
+    Borsh,
+    |_aux, _buffer, _dw| {
       Err(DataTransformationError::UnsupportedOperation.into())
     }
   }
+
+  _impl_enc! {
+    VerbatimResponse<D: BorshSerialize>,
+    Borsh,
+    |this, _aux, ew| {
+      this.data.serialize(&mut ew.vector)?;
+    }
+  }
 }
 
 #[cfg(feature = "quick-protobuf")]
 mod quick_protobuf {
-  use crate::{
-    data_transformation::{
-      dnsn::{Deserialize, QuickProtobuf, Serialize},
-      format::VerbatimResponse,
-      DataTransformationError,
-    },
-    misc::Vector,
+  use crate::data_transformation::{
+    DataTransformationError, dnsn::QuickProtobuf, format::VerbatimResponse,
   };
   use quick_protobuf::{BytesReader, MessageRead, MessageWrite, Writer};
 
-  impl<'de, D> Deserialize<'de, QuickProtobuf> for VerbatimResponse<D>
-  where
-    D: MessageRead<'de>,
-  {
-    #[inline]
-    fn from_bytes(bytes: &'de [u8], _: &mut QuickProtobuf) -> crate::Result<Self> {
-      Ok(Self { data: MessageRead::from_reader(&mut BytesReader::from_bytes(bytes), bytes)? })
+  _impl_dec! {
+    VerbatimResponse<D: MessageRead<'de>>,
+    QuickProtobuf,
+    |_aux, dw| {
+      Ok(Self { data: MessageRead::from_reader(&mut BytesReader::from_bytes(dw.bytes), dw.bytes)? })
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(
-      _: &mut Vector<Self>,
-      _: &'de [u8],
-      _: &mut QuickProtobuf,
-    ) -> crate::Result<()> {
+  _impl_dec_seq! {
+    VerbatimResponse<D: MessageRead<'de>>,
+    QuickProtobuf,
+    |_aux, _buffer, _dw| {
       Err(DataTransformationError::UnsupportedOperation.into())
     }
   }
 
-  impl<D> Serialize<QuickProtobuf> for VerbatimResponse<D>
-  where
-    D: MessageWrite,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut QuickProtobuf) -> crate::Result<()> {
-      self.data.write_message(&mut Writer::new(bytes))?;
-      Ok(())
+  _impl_enc! {
+    VerbatimResponse<D: MessageWrite>,
+    QuickProtobuf,
+    |this, _aux, ew| {
+      this.data.write_message(&mut Writer::new(&mut *ew.vector))?;
     }
   }
 }
 
 #[cfg(feature = "serde_json")]
 mod serde_json {
-  use crate::{
-    data_transformation::{
-      dnsn::SerdeJson,
-      format::{misc::collect_using_serde_json, VerbatimResponse},
-    },
-    misc::Vector,
+  use crate::data_transformation::{
+    dnsn::SerdeJson,
+    format::{VerbatimResponse, misc::collect_using_serde_json},
   };
+  use serde::{Deserialize, Serialize};
 
-  impl<'de, D> crate::data_transformation::dnsn::Deserialize<'de, SerdeJson> for VerbatimResponse<D>
-  where
-    D: serde::Deserialize<'de>,
-  {
-    #[inline]
-    fn from_bytes(bytes: &'de [u8], _: &mut SerdeJson) -> crate::Result<Self> {
-      Ok(Self { data: serde_json::from_slice(bytes)? })
+  _impl_dec! {
+    VerbatimResponse<D: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, dw| {
+      Ok(serde_json::from_slice(dw.bytes)?)
     }
+  }
 
-    #[inline]
-    fn seq_from_bytes(
-      buffer: &mut Vector<Self>,
-      bytes: &'de [u8],
-      _: &mut SerdeJson,
-    ) -> crate::Result<()> {
-      collect_using_serde_json(buffer, bytes)
+  _impl_dec_seq! {
+    VerbatimResponse<D: Deserialize<'de>>,
+    SerdeJson,
+    |_aux, buffer, dw| {
+      collect_using_serde_json(buffer, &mut dw.bytes)
+    }
+  }
+
+  _impl_enc! {
+    VerbatimResponse<D: Serialize>,
+    SerdeJson,
+    |this, _aux, ew| {
+      serde_json::to_writer(&mut *ew.vector, &this.data)?;
+    }
+  }
+}
+
+#[cfg(feature = "serde_urlencoded")]
+mod urlencoded {
+  use crate::data_transformation::{
+    DataTransformationError, dnsn::Urlencoded, format::VerbatimResponse,
+  };
+  use serde::{Deserialize, Serialize};
+
+  _impl_dec! {
+    VerbatimResponse<D: Deserialize<'de>>,
+    Urlencoded,
+    |_aux, dw| {
+      Ok(serde_urlencoded::from_bytes(dw.bytes)?)
+    }
+  }
+
+  _impl_dec_seq! {
+    VerbatimResponse<D: Deserialize<'de>>,
+    Urlencoded,
+    |_aux, _buffer, _dw| {
+      Err(DataTransformationError::UnsupportedOperation.into())
     }
   }
 
-  impl<D> crate::data_transformation::dnsn::Serialize<SerdeJson> for VerbatimResponse<D>
-  where
-    D: serde::Serialize,
-  {
-    #[inline]
-    fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut SerdeJson) -> crate::Result<()> {
-      if size_of::<D>() == 0 {
-        return Ok(());
-      }
-      serde_json::to_writer(bytes, &self.data)?;
-      Ok(())
+  _impl_enc! {
+    VerbatimResponse<D: Serialize>,
+    Urlencoded,
+    |this, _aux, ew| {
+      ew.vector.extend_from_copyable_slice(serde_urlencoded::to_string(&this.data)?.as_bytes())?;
     }
   }
 }
diff --git a/wtx/src/data_transformation/macros.rs b/wtx/src/data_transformation/macros.rs
index cbc8bfa1..54fdee88 100644
--- a/wtx/src/data_transformation/macros.rs
+++ b/wtx/src/data_transformation/macros.rs
@@ -32,25 +32,107 @@ macro_rules! generic_data_format_doc {
   };
 }
 
-//macro_rules! _impl_se {
-//  (
-//    ($drsr:ty, $bound:path)
-//  ) => {
-//    impl<D> crate::data_transformation::dnsn::Serialize<&mut SerdeJson> for VerbatimRequest<D>
-//    where
-//      D: serde::Serialize,
-//    {
-//      #[inline]
-//      fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut &mut SerdeJson) -> crate::Result<()> {
-//        if size_of::<D>() == 0 {
-//          return Ok(());
-//        }
-//        serde_json::to_writer(bytes, &self.data)?;
-//        Ok(())
-//      }
-//    }
-//  }
-//}
+macro_rules! _impl_dec {
+  (
+    $struct:ident<$($ty:ident $(: $bound:path)?),*>,
+    $drsr:ty,
+    |$aux:ident, $dw:ident| $impl:block
+  ) => {
+    impl<'de, $($ty: $($bound)?,)*> crate::misc::Decode<'de, crate::data_transformation::dnsn::De<$drsr>> for $struct<$($ty,)*> {
+      #[inline]
+      fn decode(
+        $aux: &mut $drsr,
+        $dw: &mut crate::data_transformation::dnsn::DecodeWrapper<'de>
+      ) -> crate::Result<Self> {
+        $impl
+      }
+    }
+
+    impl<'de, $($ty: $($bound)?,)*> crate::misc::Decode<'de, crate::data_transformation::dnsn::De<&mut $drsr>> for $struct<$($ty,)*>
+    where
+      $struct<$($ty,)*>: crate::misc::Decode<'de, crate::data_transformation::dnsn::De<$drsr>>,
+    {
+      #[inline]
+      fn decode(
+        aux: &mut &mut $drsr,
+        dw: &mut crate::data_transformation::dnsn::DecodeWrapper<'de>
+      ) -> crate::Result<Self> {
+        <$struct<$($ty,)*>>::decode(*aux, dw)
+      }
+    }
+  }
+}
+
+macro_rules! _impl_dec_seq {
+  (
+    $struct:ident<$($ty:ident $(: $bound:path)?),*>,
+    $drsr:ty,
+    |$aux:ident, $buffer:ident, $dw:ident| $impl:block
+  ) => {
+    impl<'de, $($ty: $($bound)?,)*> crate::misc::DecodeSeq<'de, crate::data_transformation::dnsn::De<$drsr>> for $struct<$($ty,)*> {
+      #[inline]
+      fn decode_seq(
+        $aux: &mut $drsr,
+        $buffer: &mut crate::misc::Vector<Self>,
+        $dw: &mut crate::data_transformation::dnsn::DecodeWrapper<'de>,
+      ) -> crate::Result<()> {
+        $impl
+      }
+    }
+
+    impl<'de, $($ty: $($bound)?,)*> crate::misc::DecodeSeq<'de, crate::data_transformation::dnsn::De<&mut $drsr>> for $struct<$($ty,)*>
+    where
+      $struct<$($ty,)*>: crate::misc::Decode<'de, crate::data_transformation::dnsn::De<$drsr>>,
+    {
+      #[inline]
+      fn decode_seq(
+        aux: &mut &mut $drsr,
+        buffer: &mut crate::misc::Vector<Self>,
+        dw: &mut crate::data_transformation::dnsn::DecodeWrapper<'de>,
+      ) -> crate::Result<()> {
+        <$struct<$($ty,)*>>::decode_seq(*aux, buffer, dw)
+      }
+    }
+  }
+}
+
+macro_rules! _impl_enc {
+  (
+    $struct:ident<$($ty:ident $(: $bound:path)?),*>,
+    $drsr:ty,
+    |$this:ident, $aux:ident, $ew:ident| $impl:block
+  ) => {
+    impl<$($ty: $($bound)?,)*> crate::misc::Encode<crate::data_transformation::dnsn::De<$drsr>> for $struct<$($ty,)*> {
+      #[inline]
+      fn encode(
+        &self,
+        $aux: &mut $drsr,
+        $ew: &mut crate::data_transformation::dnsn::EncodeWrapper<'_>
+      ) -> crate::Result<()> {
+        if size_of::<Self>() == 0 {
+          return Ok(());
+        }
+        let $this = self;
+        $impl
+        Ok(())
+      }
+    }
+
+    impl<'de, $($ty: $($bound)?,)*> crate::misc::Encode<crate::data_transformation::dnsn::De<&mut $drsr>> for $struct<$($ty,)*>
+    where
+      $struct<$($ty,)*>: crate::misc::Encode<crate::data_transformation::dnsn::De<$drsr>>,
+    {
+      #[inline]
+      fn encode(
+        &self,
+        aux: &mut &mut $drsr,
+        ew: &mut crate::data_transformation::dnsn::EncodeWrapper<'_>
+      ) -> crate::Result<()> {
+        <$struct<$($ty,)*>>::encode(self, *aux, ew)
+      }
+    }
+  }
+}
 
 macro_rules! _impl_se_collections {
   (
@@ -61,16 +143,14 @@ macro_rules! _impl_se_collections {
     vec: |$vec_self:ident, $vec_bytes:ident, $vec_drsr:ident| $vec_block:block
   ) => {
     $(
-      impl<T, const N: usize> crate::data_transformation::dnsn::Serialize<$drsr> for [T; N]
+      impl<T, const N: usize> crate::misc::Encode<crate::data_transformation::dnsn::De<$drsr>> for [T; N]
       where
         T: $bound,
       {
         #[inline]
-        fn to_bytes(&mut self, bytes: &mut crate::misc::Vector<u8>, drsr: &mut $drsr) -> crate::Result<()>
-        {
+        fn encode(&self, $array_drsr: &mut SerdeJson, ew: &mut crate::data_transformation::dnsn::EncodeWrapper<'_>) -> crate::Result<()> {
           let $array_self = self;
-          let $array_bytes = bytes;
-          let $array_drsr = drsr;
+          let $array_bytes = &mut *ew.vector;
           $array_block;
           Ok(())
         }
@@ -78,44 +158,41 @@ macro_rules! _impl_se_collections {
     )?
 
     $(
-      impl<T, const N: usize> crate::data_transformation::dnsn::Serialize<$drsr> for crate::misc::ArrayVector<T, N>
+      impl<T, const N: usize> crate::misc::Encode<crate::data_transformation::dnsn::De<$drsr>> for crate::misc::ArrayVector<T, N>
       where
         T: $bound,
       {
         #[inline]
-        fn to_bytes(&mut self, bytes: &mut crate::misc::Vector<u8>, drsr: &mut $drsr) -> crate::Result<()> {
+        fn encode(&self, $arrayvector_drsr: &mut SerdeJson, ew: &mut crate::data_transformation::dnsn::EncodeWrapper<'_>) -> crate::Result<()> {
           let $arrayvector_self = self;
-          let $arrayvector_bytes = bytes;
-          let $arrayvector_drsr = drsr;
+          let $arrayvector_bytes = &mut *ew.vector;
           $arrayvector_block;
           Ok(())
         }
       }
     )?
 
-    impl<T> crate::data_transformation::dnsn::Serialize<$drsr> for &[T]
+    impl<T> crate::misc::Encode<crate::data_transformation::dnsn::De<$drsr>> for &'_ [T]
     where
       T: $bound,
     {
       #[inline]
-      fn to_bytes(&mut self, bytes: &mut crate::misc::Vector<u8>, drsr: &mut $drsr) -> crate::Result<()> {
+      fn encode(&self, $slice_ref_drsr: &mut SerdeJson, ew: &mut crate::data_transformation::dnsn::EncodeWrapper<'_>) -> crate::Result<()> {
         let $slice_ref_self = self;
-        let $slice_ref_bytes = bytes;
-        let $slice_ref_drsr = drsr;
+        let $slice_ref_bytes = &mut *ew.vector;
         $slice_ref_block;
         Ok(())
       }
     }
 
-    impl<T> crate::data_transformation::dnsn::Serialize<$drsr> for crate::misc::Vector<T>
+    impl<T> crate::misc::Encode<crate::data_transformation::dnsn::De<$drsr>> for crate::misc::Vector<T>
     where
       T: $bound,
     {
       #[inline]
-      fn to_bytes(&mut self, bytes: &mut crate::misc::Vector<u8>, drsr: &mut $drsr) -> crate::Result<()>  {
+      fn encode(&self, $vec_drsr: &mut SerdeJson, ew: &mut crate::data_transformation::dnsn::EncodeWrapper<'_>) -> crate::Result<()> {
         let $vec_self = self;
-        let $vec_bytes = bytes;
-        let $vec_drsr = drsr;
+        let $vec_bytes = &mut *ew.vector;
         $vec_block;
         Ok(())
       }
diff --git a/wtx/src/database.rs b/wtx/src/database.rs
index e50f7782..8344a778 100644
--- a/wtx/src/database.rs
+++ b/wtx/src/database.rs
@@ -3,8 +3,6 @@
 pub mod client;
 mod database_error;
 mod database_ty;
-mod decode;
-mod encode;
 mod executor;
 mod from_record;
 mod from_records;
@@ -21,8 +19,6 @@ mod value_ident;
 
 pub use database_error::DatabaseError;
 pub use database_ty::DatabaseTy;
-pub use decode::Decode;
-pub use encode::Encode;
 pub use executor::Executor;
 pub use from_record::FromRecord;
 pub use from_records::FromRecords;
@@ -45,22 +41,10 @@ pub const DEFAULT_URI_VAR: &str = "DATABASE_URI";
 pub type Identifier = crate::misc::ArrayString<64>;
 
 /// Database
-pub trait Database {
-  /// Prefix used to bind parameterized queries.
-  const BIND_PREFIX: &'static str;
-  /// Some databases require bindings in ascending order.
-  const IS_BIND_INCREASING: bool;
+pub trait Database: crate::misc::DEController {
   /// See [`DatabaseTy`].
   const TY: DatabaseTy;
 
-  /// Contains the data used to decode types.
-  type DecodeValue<'exec>;
-  /// Contains the data used to decode types.
-  type EncodeValue<'buffer, 'tmp>: crate::misc::LeaseMut<crate::misc::FilledBufferWriter<'buffer>>
-  where
-    'buffer: 'tmp;
-  /// See [`crate::Error`].
-  type Error: From<crate::Error>;
   /// See [Record].
   type Record<'exec>: Record<'exec, Database = Self>;
   /// See [Records].
@@ -70,16 +54,8 @@ pub trait Database {
 }
 
 impl Database for () {
-  const BIND_PREFIX: &'static str = "$";
-  const IS_BIND_INCREASING: bool = true;
   const TY: DatabaseTy = DatabaseTy::Unit;
 
-  type DecodeValue<'exec> = ();
-  type EncodeValue<'buffer, 'tmp>
-    = crate::misc::FilledBufferWriter<'buffer>
-  where
-    'buffer: 'tmp;
-  type Error = crate::Error;
   type Record<'exec> = ();
   type Records<'exec> = ();
   type Ty = ();
diff --git a/wtx/src/database/client.rs b/wtx/src/database/client.rs
index bd8fabf1..0d1b8885 100644
--- a/wtx/src/database/client.rs
+++ b/wtx/src/database/client.rs
@@ -1,4 +1,8 @@
 //! Database clients
 
+#[cfg(feature = "mysql")]
+pub mod mysql;
 #[cfg(feature = "postgres")]
 pub mod postgres;
+#[cfg(any(feature = "mysql", feature = "postgres"))]
+mod rdbms;
diff --git a/wtx/src/database/client/mysql.rs b/wtx/src/database/client/mysql.rs
new file mode 100644
index 00000000..2963c55d
--- /dev/null
+++ b/wtx/src/database/client/mysql.rs
@@ -0,0 +1,83 @@
+//! MySQL is an open source relational database management system (RDBMS) that's used to store
+//! and manage data.
+
+mod auth_plugin;
+mod capability;
+pub(crate) mod charset;
+pub(crate) mod collation;
+mod column;
+mod config;
+mod decode_wrapper;
+mod encode_wrapper;
+mod executor_buffer;
+mod flags;
+mod misc;
+mod mysql_error;
+mod mysql_executor;
+mod mysql_protocol;
+mod mysql_record;
+mod mysql_records;
+mod status;
+mod ty;
+mod ty_params;
+mod tys;
+
+use crate::{
+  database::{
+    Database, DatabaseTy,
+    client::rdbms::{statement::Statement, statements::Statements},
+  },
+  misc::DEController,
+};
+pub use config::Config;
+use core::marker::PhantomData;
+pub use decode_wrapper::DecodeWrapper;
+pub use encode_wrapper::EncodeWrapper;
+pub use executor_buffer::ExecutorBuffer;
+pub use mysql_error::MysqlError;
+pub use mysql_executor::MysqlExecutor;
+pub use mysql_record::MysqlRecord;
+pub use mysql_records::MysqlRecords;
+pub use ty::Ty;
+
+pub(crate) type MysqlStatements = Statements<u32, column::Column, ty_params::TyParams>;
+pub(crate) type MysqlStatement<'stmts> =
+  Statement<'stmts, u32, column::Column, ty_params::TyParams>;
+
+/// MySQL
+#[derive(Debug)]
+pub struct Mysql<E>(PhantomData<fn() -> E>);
+
+impl<E> Database for Mysql<E>
+where
+  E: From<crate::Error>,
+{
+  const TY: DatabaseTy = DatabaseTy::Mysql;
+
+  type Record<'exec> = MysqlRecord<'exec, E>;
+  type Records<'exec> = MysqlRecords<'exec, E>;
+  type Ty = Ty;
+}
+
+impl<E> DEController for Mysql<E>
+where
+  E: From<crate::Error>,
+{
+  type Aux = ();
+  type DecodeWrapper<'inner, 'outer>
+    = DecodeWrapper<'inner>
+  where
+    'inner: 'outer;
+  type Error = E;
+  type EncodeWrapper<'inner, 'outer>
+    = EncodeWrapper<'inner>
+  where
+    'inner: 'outer;
+}
+
+impl<E> Default for Mysql<E> {
+  #[inline]
+  fn default() -> Self {
+    Self(PhantomData)
+  }
+}
diff --git a/wtx/src/database/client/mysql/auth_plugin.rs b/wtx/src/database/client/mysql/auth_plugin.rs
new file mode 100644
index 00000000..89c617a3
--- /dev/null
+++ b/wtx/src/database/client/mysql/auth_plugin.rs
@@ -0,0 +1,124 @@
+use crate::{
+  database::client::mysql::{
+    MysqlError,
+    misc::{fetch_msg, write_packet},
+  },
+  misc::{ArrayVector, Stream, Vector, partitioned_filled_buffer::PartitionedFilledBuffer},
+};
+use sha2::{Digest, Sha256};
+//use rsa::{pkcs8::DecodePublicKey, Oaep, RsaPublicKey};
+
+#[derive(Clone, Copy, Debug)]
+pub(crate) enum AuthPlugin {
+  CachingSha2,
+  MySqlClear,
+}
+
+impl AuthPlugin {
+  #[inline]
+  pub(crate) async fn manage_caching_sha2<E, S, const IS_TLS: bool>(
+    self,
+    auth_plugin_data: ([u8; 8], &[u8]),
+    bytes: [u8; 2],
+    (capabilities, sequence_id): (&mut u64, &mut u8),
+    enc_buffer: &mut Vector<u8>,
+    net_buffer: &mut PartitionedFilledBuffer,
+    password: &str,
+    stream: &mut S,
+  ) -> Result<bool, E>
+  where
+    E: From<crate::Error>,
+    S: Stream,
+  {
+    let [a, b] = bytes;
+    match self {
+      AuthPlugin::CachingSha2 if a == 1 => match b {
+        3 => Ok(true),
+        4 => {
+          let mut pw_array: ArrayVector<u8, 32> = password.as_bytes().try_into()?;
+          pw_array.push(0)?;
+          if IS_TLS {
+            //return Ok(to_asciz(password));
+          }
+
+          write_packet((capabilities, sequence_id), enc_buffer, &[2][..], stream).await?;
+
+          fetch_msg(net_buffer, sequence_id, stream).await?;
+          //let rsa_pub_key = net_buffer._current().get(1..).unwrap_or_default();
+
+          Self::xor_slice((&auth_plugin_data.0, &auth_plugin_data.1), &mut pw_array);
+
+          //let pkey = RsaPublicKey::from_public_key_pem(std::str::from_utf8(rsa_pub_key)?)?;
+          //let padding = Oaep::new::<sha1::Sha1>();
+          //pkey.encrypt(&mut thread_rng(), padding, &pass[..]).map_err(Error::protocol);
+
+          Ok(false)
+        }
+        _ => panic!(),
+      },
+      _ => panic!(),
+    }
+  }
+
+  #[inline]
+  pub(crate) fn mask_pw(
+    self,
+    auth_plugin_data: (&[u8], &[u8]),
+    pw: &[u8],
+  ) -> crate::Result<ArrayVector<u8, 32>> {
+    match self {
+      AuthPlugin::CachingSha2 => Ok(Self::sha2_mask(auth_plugin_data, pw).as_slice().try_into()?),
+      AuthPlugin::MySqlClear => {
+        let mut rslt: ArrayVector<u8, 32> = pw.try_into()?;
+        rslt.push(0)?;
+        Ok(rslt)
+      }
+    }
+  }
+
+  #[inline]
+  fn sha2_mask(data: (&[u8], &[u8]), pw: &[u8]) -> [u8; 32] {
+    let mut ctx = Sha256::new();
+    ctx.update(pw);
+    let mut hash = ctx.finalize_reset();
+    ctx.update(hash);
+    let another_hash = ctx.finalize_reset();
+    ctx.update(&data.0);
+    ctx.update(&data.1);
+    ctx.update(another_hash);
+    let with_seed_hash = ctx.finalize();
+    Self::xor_slice((&with_seed_hash, &[]), &mut hash);
+    hash.into()
+  }
+
+  #[inline]
+  fn xor_slice((from0, from1): (&[u8], &[u8]), to: &mut [u8]) {
+    let from_iter = from0.iter().chain(from1).cycle();
+    for (to, from) in to.iter_mut().zip(from_iter) {
+      *to ^= *from;
+    }
+  }
+}
+
+impl From<AuthPlugin> for &'static str {
+  #[inline]
+  fn from(from: AuthPlugin) -> Self {
+    match from {
+      AuthPlugin::CachingSha2 => "caching_sha2_password",
+      AuthPlugin::MySqlClear => "mysql_clear_password",
+    }
+  }
+}
+
+impl TryFrom<&[u8]> for AuthPlugin {
+  type Error = crate::Error;
+
+  #[inline]
+  fn try_from(from: &[u8]) -> Result<Self, Self::Error> {
+    Ok(match from {
+      b"caching_sha2_password" => AuthPlugin::CachingSha2,
+      b"mysql_clear_password" => AuthPlugin::MySqlClear,
+      _ => return Err(MysqlError::UnknownAuthPlugin.into()),
+    })
+  }
+}
diff --git a/wtx/src/database/client/mysql/capability.rs b/wtx/src/database/client/mysql/capability.rs
new file mode 100644
index 00000000..4e87b768
--- /dev/null
+++ b/wtx/src/database/client/mysql/capability.rs
@@ -0,0 +1,40 @@
+create_enum! {
+  /// Aggregation of MySQL e MariaDB capabilities
+  #[derive(Debug, Clone, Copy)]
+  pub(crate) enum Capability<u64> {
+    Mysql = (1),
+    FoundRows = (2),
+    LongFlag = (4),
+    ConnectWithDb = (8),
+    NoSchema = (16),
+    Compress = (32),
+    Odbc = (64),
+    LocalFiles = (128),
+    IgnoreSpace = (256),
+    Protocol41 = (512),
+    Interactive = (1024),
+    Ssl = (2048),
+    Transactions = (16384),
+    SecureConnection = (32768),
+    MultiStatements = (65536), // 1 << 16
+    MultiResults = (131072), // 1 << 17
+    PsMultiResults = (262144), // 1 << 18
+    PluginAuth = (524288), // 1 << 19
+    ConnectAttrs = (1048576), // 1 << 20
+    PluginAuthLenencData = (2097152), // 1 << 21
+    CanHandleExpiredPasswords = (4194304), // 1 << 22
+    SessionTrack = (8388608), // 1 << 23
+    DeprecateEof = (16777216),  // 1 << 24
+    OptionalResultsetMetadata = (33554432), // 1 << 25
+    ZstdCompressionAlgorithm = (67108864), // 1 << 26
+    QueryAttributes = (134217728), // 1 << 27
+    SslVerifyServerCert = (1073741824), // 1 << 30
+    RememberOptions = (2147483648), // 1 << 31
+    MariaDbClientProgress = (4294967296), // 1 << 32
+    MariaDbClientMulti = (8589934592),  // 1 << 33
+    MariaDbClientStmtBulkOperations = (17179869184), // 1 << 34
+    MariaDbClientExtendedTypeInfo = (34359738368), // 1 << 35
+    MariaDbClientCacheMetadata = (68719476736), // 1 << 36
+    MariaDbClientBulkUnitResults = (137438953472) // 1 << 37
+  }
+}
diff --git a/wtx/src/database/client/mysql/charset.rs b/wtx/src/database/client/mysql/charset.rs
new file mode 100644
index 00000000..3c576da3
--- /dev/null
+++ b/wtx/src/database/client/mysql/charset.rs
@@ -0,0 +1,98 @@
+use crate::database::client::mysql::collation::Collation;
+
+create_enum! {
+  #[allow(non_camel_case_types, reason = "mysql format")]
+  #[derive(Copy, Clone, Debug)]
+  pub(crate) enum Charset<u8> {
+    armscii8 = (1),
+    ascii = (2),
+    big5 = (3),
+    binary = (4),
+    cp1250 = (5),
+    cp1251 = (6),
+    cp1256 = (7),
+    cp1257 = (8),
+    cp850 = (9),
+    cp852 = (10),
+    cp866 = (11),
+    cp932 = (12),
+    dec8 = (13),
+    eucjpms = (14),
+    euckr = (15),
+    gb18030 = (16),
+    gb2312 = (17),
+    gbk = (18),
+    geostd8 = (19),
+    greek = (20),
+    hebrew = (21),
+    hp8 = (22),
+    keybcs2 = (23),
+    koi8r = (24),
+    koi8u = (25),
+    latin1 = (26),
+    latin2 = (27),
+    latin5 = (28),
+    latin7 = (29),
+    macce = (30),
+    macroman = (31),
+    sjis = (32),
+    swe7 = (33),
+    tis620 = (34),
+    ucs2 = (35),
+    ujis = (36),
+    utf16 = (37),
+    utf16le = (38),
+    utf32 = (39),
+    utf8 = (40),
+    utf8mb4 = (41),
+  }
+}
+
+impl Charset {
+  #[inline]
+  pub(crate) fn default_collation(&self) -> Collation {
+    match self {
+      Self::armscii8 => Collation::armscii8_general_ci,
+      Self::ascii => Collation::ascii_general_ci,
+      Self::big5 => Collation::big5_chinese_ci,
+      Self::binary => Collation::binary,
+      Self::cp1250 => Collation::cp1250_general_ci,
+      Self::cp1251 => Collation::cp1251_general_ci,
+      Self::cp1256 => Collation::cp1256_general_ci,
+      Self::cp1257 => Collation::cp1257_general_ci,
+      Self::cp850 => Collation::cp850_general_ci,
+      Self::cp852 => Collation::cp852_general_ci,
+      Self::cp866 => Collation::cp866_general_ci,
+      Self::cp932 => Collation::cp932_japanese_ci,
+      Self::dec8 => Collation::dec8_swedish_ci,
+      Self::eucjpms => Collation::eucjpms_japanese_ci,
+      Self::euckr => Collation::euckr_korean_ci,
+      Self::gb18030 => Collation::gb18030_chinese_ci,
+      Self::gb2312 => Collation::gb2312_chinese_ci,
+      Self::gbk => Collation::gbk_chinese_ci,
+      Self::geostd8 => Collation::geostd8_general_ci,
+      Self::greek => Collation::greek_general_ci,
+      Self::hebrew => Collation::hebrew_general_ci,
+      Self::hp8 => Collation::hp8_english_ci,
+      Self::keybcs2 => Collation::keybcs2_general_ci,
+      Self::koi8r => Collation::koi8r_general_ci,
+      Self::koi8u => Collation::koi8u_general_ci,
+      Self::latin1 => Collation::latin1_swedish_ci,
+      Self::latin2 => Collation::latin2_general_ci,
+      Self::latin5 => Collation::latin5_turkish_ci,
+      Self::latin7 => Collation::latin7_general_ci,
+      Self::macce => Collation::macce_general_ci,
+      Self::macroman => Collation::macroman_general_ci,
+      Self::sjis => Collation::sjis_japanese_ci,
+      Self::swe7 => Collation::swe7_swedish_ci,
+      Self::tis620 => Collation::tis620_thai_ci,
+      Self::ucs2 => Collation::ucs2_general_ci,
+      Self::ujis => Collation::ujis_japanese_ci,
+      Self::utf16 => Collation::utf16_general_ci,
+      Self::utf16le => Collation::utf16le_general_ci,
+      Self::utf32 => Collation::utf32_general_ci,
+      Self::utf8 => Collation::utf8_unicode_ci,
+      Self::utf8mb4 => Collation::utf8mb4_unicode_ci,
+    }
+  }
+}
diff --git a/wtx/src/database/client/mysql/collation.rs b/wtx/src/database/client/mysql/collation.rs
new file mode 100644
index 00000000..dbd2c21b
--- /dev/null
+++ b/wtx/src/database/client/mysql/collation.rs
@@ -0,0 +1,230 @@
+create_enum! {
+  #[allow(non_camel_case_types, reason = "mysql format")]
+  #[derive(Copy, Clone, Debug)]
+  pub(crate) enum Collation<u8> {
+    armscii8_bin = (64),
+    armscii8_general_ci = (32),
+    ascii_bin = (65),
+    ascii_general_ci = (11),
+    big5_bin = (84),
+    big5_chinese_ci = (1),
+    binary = (63),
+    cp1250_bin = (66),
+    cp1250_croatian_ci = (44),
+    cp1250_czech_cs = (34),
+    cp1250_general_ci = (26),
+    cp1250_polish_ci = (99),
+    cp1251_bin = (50),
+    cp1251_bulgarian_ci = (14),
+    cp1251_general_ci = (51),
+    cp1251_general_cs = (52),
+    cp1251_ukrainian_ci = (23),
+    cp1256_bin = (67),
+    cp1256_general_ci = (57),
+    cp1257_bin = (58),
+    cp1257_general_ci = (59),
+    cp1257_lithuanian_ci = (29),
+    cp850_bin = (80),
+    cp850_general_ci = (4),
+    cp852_bin = (81),
+    cp852_general_ci = (40),
+    cp866_bin = (68),
+    cp866_general_ci = (36),
+    cp932_bin = (96),
+    cp932_japanese_ci = (95),
+    dec8_bin = (69),
+    dec8_swedish_ci = (3),
+    eucjpms_bin = (98),
+    eucjpms_japanese_ci = (97),
+    euckr_bin = (85),
+    euckr_korean_ci = (19),
+    gb18030_bin = (249),
+    gb18030_chinese_ci = (248),
+    gb18030_unicode_520_ci = (250),
+    gb2312_bin = (86),
+    gb2312_chinese_ci = (24),
+    gbk_bin = (87),
+    gbk_chinese_ci = (28),
+    geostd8_bin = (93),
+    geostd8_general_ci = (92),
+    greek_bin = (70),
+    greek_general_ci = (25),
+    hebrew_bin = (71),
+    hebrew_general_ci = (16),
+    hp8_bin = (72),
+    hp8_english_ci = (6),
+    keybcs2_bin = (73),
+    keybcs2_general_ci = (37),
+    koi8r_bin = (74),
+    koi8r_general_ci = (7),
+    koi8u_bin = (75),
+    koi8u_general_ci = (22),
+    latin1_bin = (47),
+    latin1_danish_ci = (15),
+    latin1_general_ci = (48),
+    latin1_general_cs = (49),
+    latin1_german1_ci = (5),
+    latin1_german2_ci = (31),
+    latin1_spanish_ci = (94),
+    latin1_swedish_ci = (8),
+    latin2_bin = (77),
+    latin2_croatian_ci = (27),
+    latin2_czech_cs = (2),
+    latin2_general_ci = (9),
+    latin2_hungarian_ci = (21),
+    latin5_bin = (78),
+    latin5_turkish_ci = (30),
+    latin7_bin = (79),
+    latin7_estonian_cs = (20),
+    latin7_general_ci = (41),
+    latin7_general_cs = (42),
+    macce_bin = (43),
+    macce_general_ci = (38),
+    macroman_bin = (53),
+    macroman_general_ci = (39),
+    sjis_bin = (88),
+    sjis_japanese_ci = (13),
+    swe7_bin = (82),
+    swe7_swedish_ci = (10),
+    tis620_bin = (89),
+    tis620_thai_ci = (18),
+    ucs2_bin = (90),
+    ucs2_croatian_ci = (149),
+    ucs2_czech_ci = (138),
+    ucs2_danish_ci = (139),
+    ucs2_esperanto_ci = (145),
+    ucs2_estonian_ci = (134),
+    ucs2_general_ci = (35),
+    ucs2_general_mysql500_ci = (159),
+    ucs2_german2_ci = (148),
+    ucs2_hungarian_ci = (146),
+    ucs2_icelandic_ci = (129),
+    ucs2_latvian_ci = (130),
+    ucs2_lithuanian_ci = (140),
+    ucs2_persian_ci = (144),
+    ucs2_polish_ci = (133),
+    ucs2_roman_ci = (143),
+    ucs2_romanian_ci = (131),
+    ucs2_sinhala_ci = (147),
+    ucs2_slovak_ci = (141),
+    ucs2_slovenian_ci = (132),
+    ucs2_spanish_ci = (135),
+    ucs2_spanish2_ci = (142),
+    ucs2_swedish_ci = (136),
+    ucs2_turkish_ci = (137),
+    ucs2_unicode_520_ci = (150),
+    ucs2_unicode_ci = (128),
+    ucs2_vietnamese_ci = (151),
+    ujis_bin = (91),
+    ujis_japanese_ci = (12),
+    utf16_bin = (55),
+    utf16_croatian_ci = (122),
+    utf16_czech_ci = (111),
+    utf16_danish_ci = (112),
+    utf16_esperanto_ci = (118),
+    utf16_estonian_ci = (107),
+    utf16_general_ci = (54),
+    utf16_german2_ci = (121),
+    utf16_hungarian_ci = (119),
+    utf16_icelandic_ci = (102),
+    utf16_latvian_ci = (103),
+    utf16_lithuanian_ci = (113),
+    utf16_persian_ci = (117),
+    utf16_polish_ci = (106),
+    utf16_roman_ci = (116),
+    utf16_romanian_ci = (104),
+    utf16_sinhala_ci = (120),
+    utf16_slovak_ci = (114),
+    utf16_slovenian_ci = (105),
+    utf16_spanish_ci = (108),
+    utf16_spanish2_ci = (115),
+    utf16_swedish_ci = (109),
+    utf16_turkish_ci = (110),
+    utf16_unicode_520_ci = (123),
+    utf16_unicode_ci = (101),
+    utf16_vietnamese_ci = (124),
+    utf16le_bin = (62),
+    utf16le_general_ci = (56),
+    utf32_bin = (61),
+    utf32_croatian_ci = (181),
+    utf32_czech_ci = (170),
+    utf32_danish_ci = (171),
+    utf32_esperanto_ci = (177),
+    utf32_estonian_ci = (166),
+    utf32_general_ci = (60),
+    utf32_german2_ci = (180),
+    utf32_hungarian_ci = (178),
+    utf32_icelandic_ci = (161),
+    utf32_latvian_ci = (162),
+    utf32_lithuanian_ci = (172),
+    utf32_persian_ci = (176),
+    utf32_polish_ci = (165),
+    utf32_roman_ci = (175),
+    utf32_romanian_ci = (163),
+    utf32_sinhala_ci = (179),
+    utf32_slovak_ci = (173),
+    utf32_slovenian_ci = (164),
+    utf32_spanish_ci = (167),
+    utf32_spanish2_ci = (174),
+    utf32_swedish_ci = (168),
+    utf32_turkish_ci = (169),
+    utf32_unicode_520_ci = (182),
+    utf32_unicode_ci = (160),
+    utf32_vietnamese_ci = (183),
+    utf8_bin = (83),
+    utf8_croatian_ci = (213),
+    utf8_czech_ci = (202),
+    utf8_danish_ci = (203),
+    utf8_esperanto_ci = (209),
+    utf8_estonian_ci = (198),
+    utf8_general_ci = (33),
+    utf8_general_mysql500_ci = (223),
+    utf8_german2_ci = (212),
+    utf8_hungarian_ci = (210),
+    utf8_icelandic_ci = (193),
+    utf8_latvian_ci = (194),
+    utf8_lithuanian_ci = (204),
+    utf8_persian_ci = (208),
+    utf8_polish_ci = (197),
+    utf8_roman_ci = (207),
+    utf8_romanian_ci = (195),
+    utf8_sinhala_ci = (211),
+    utf8_slovak_ci = (205),
+    utf8_slovenian_ci = (196),
+    utf8_spanish_ci = (199),
+    utf8_spanish2_ci = (206),
+    utf8_swedish_ci = (200),
+    utf8_tolower_ci = (76),
+    utf8_turkish_ci = (201),
+    utf8_unicode_520_ci = (214),
+    utf8_unicode_ci = (192),
+    utf8_vietnamese_ci = (215),
+    utf8mb4_0900_ai_ci = (255),
+    utf8mb4_bin = (46),
+    utf8mb4_croatian_ci = (245),
+    utf8mb4_czech_ci = (234),
+    utf8mb4_danish_ci = (235),
+    utf8mb4_esperanto_ci = (241),
+    utf8mb4_estonian_ci = (230),
+    utf8mb4_general_ci = (45),
+    utf8mb4_german2_ci = (244),
+    utf8mb4_hungarian_ci = (242),
+    utf8mb4_icelandic_ci = (225),
+    utf8mb4_latvian_ci = (226),
+    utf8mb4_lithuanian_ci = (236),
+    utf8mb4_persian_ci = (240),
+    utf8mb4_polish_ci = (229),
+    utf8mb4_roman_ci = (239),
+    utf8mb4_romanian_ci = (227),
+    utf8mb4_sinhala_ci = (243),
+    utf8mb4_slovak_ci = (237),
+    utf8mb4_slovenian_ci = (228),
+    utf8mb4_spanish_ci = (231),
+    utf8mb4_spanish2_ci = (238),
+    utf8mb4_swedish_ci = (232),
+    utf8mb4_turkish_ci = (233),
+    utf8mb4_unicode_520_ci = (246),
+    utf8mb4_unicode_ci = (224),
+    utf8mb4_vietnamese_ci = (247),
+  }
+}
diff --git a/wtx/src/database/client/mysql/column.rs b/wtx/src/database/client/mysql/column.rs
new file mode 100644
index 00000000..2e4dfcac
--- /dev/null
+++ b/wtx/src/database/client/mysql/column.rs
@@ -0,0 +1,18 @@
+use crate::database::{
+  Identifier,
+  client::mysql::{mysql_protocol::column_res::ColumnRes, ty_params::TyParams},
+};
+
+#[derive(Clone, Debug)]
+pub(crate) struct Column {
+  pub(crate) name: Identifier,
+  pub(crate) ty_params: TyParams,
+}
+
+impl Column {
+  #[inline]
+  pub(crate) fn from_column_res(column_res: &ColumnRes) -> Self {
+    let name = if column_res.alias.is_empty() { column_res.name } else { column_res.alias };
+    Self { name, ty_params: TyParams::from_column_res(column_res) }
+  }
+}
diff --git a/wtx/src/database/client/mysql/config.rs b/wtx/src/database/client/mysql/config.rs
new file mode 100644
index 00000000..af78170f
--- /dev/null
+++ b/wtx/src/database/client/mysql/config.rs
@@ -0,0 +1,75 @@
+use crate::{
+  database::client::{
+    mysql::{MysqlError, charset::Charset, collation::Collation},
+    rdbms::query_walker,
+  },
+  misc::UriRef,
+};
+
+/// Configuration
+#[derive(Debug)]
+pub struct Config<'data> {
+  pub(crate) charset: Charset,
+  pub(crate) collation: Collation,
+  pub(crate) db: Option<&'data str>,
+  pub(crate) enable_cleartext_plugin: bool,
+  pub(crate) no_engine_substitution: bool,
+  pub(crate) password: Option<&'data str>,
+  pub(crate) pipes_as_concat: bool,
+  pub(crate) set_names: bool,
+  pub(crate) timezone: Option<&'data str>,
+  pub(crate) user: &'data str,
+}
+
+impl<'data> Config<'data> {
+  /// Unwraps the elements from an URI.
+  #[inline]
+  pub fn from_uri(uri: &'data UriRef<'_>) -> crate::Result<Config<'data>> {
+    let db = uri.path().get(1..).unwrap_or_default();
+    let password = uri.password();
+    let user = uri.user();
+    let mut this = Self {
+      charset: Charset::utf8mb4,
+      collation: Charset::utf8mb4.default_collation(),
+      db: if db.is_empty() { None } else { Some(db) },
+      enable_cleartext_plugin: false,
+      no_engine_substitution: true,
+      password: if password.is_empty() { None } else { Some(password) },
+      pipes_as_concat: true,
+      set_names: true,
+      timezone: None,
+      user,
+    };
+    query_walker(uri, |key, value| this.set_param(key, value))?;
+    Ok(this)
+  }
+
+  #[inline]
+  fn set_param(&mut self, key: &str, value: &'data str) -> crate::Result<()> {
+    match key {
+      "charset" => {
+        self.charset = Charset::try_from(value)?;
+      }
+      "collation" => {
+        self.collation = Collation::try_from(value)?;
+      }
+      "enable_cleartext_plugin" => {
+        self.enable_cleartext_plugin = true;
+      }
+      "no_engine_substitution" => {
+        self.no_engine_substitution = true;
+      }
+      "pipes_as_concat" => {
+        self.pipes_as_concat = true;
+      }
+      "set_names" => {
+        self.set_names = true;
+      }
+      "timezone" => {
+        self.timezone = Some(value);
+      }
+      _ => return Err(MysqlError::UnknownConfigurationParameter.into()),
+    }
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/decode_wrapper.rs b/wtx/src/database/client/mysql/decode_wrapper.rs
new file mode 100644
index 00000000..401748f8
--- /dev/null
+++ b/wtx/src/database/client/mysql/decode_wrapper.rs
@@ -0,0 +1,41 @@
+use crate::{database::client::mysql::Ty, misc::Lease};
+
+/// Struct used for decoding elements in MySQL.
+#[derive(Debug, PartialEq)]
+pub struct DecodeWrapper<'de> {
+  bytes: &'de [u8],
+  ty: Ty,
+}
+
+impl<'de> DecodeWrapper<'de> {
+  #[inline]
+  pub(crate) fn new(bytes: &'de [u8], ty: Ty) -> Self {
+    Self { bytes, ty }
+  }
+
+  /// Bytes of a column.
+  #[inline]
+  pub fn bytes(&self) -> &'de [u8] {
+    self.bytes
+  }
+
+  /// Type of a column.
+  #[inline]
+  pub fn ty(&self) -> &Ty {
+    &self.ty
+  }
+}
+
+impl Default for DecodeWrapper<'_> {
+  #[inline]
+  fn default() -> Self {
+    Self { bytes: &[], ty: Ty::Null }
+  }
+}
+
+impl Lease<[u8]> for DecodeWrapper<'_> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.bytes
+  }
+}
diff --git a/wtx/src/database/client/mysql/encode_wrapper.rs b/wtx/src/database/client/mysql/encode_wrapper.rs
new file mode 100644
index 00000000..e9844608
--- /dev/null
+++ b/wtx/src/database/client/mysql/encode_wrapper.rs
@@ -0,0 +1,27 @@
+use crate::misc::{Lease, Vector};
+
+/// Struct used for encoding elements in MySQL.
+#[derive(Debug)]
+pub struct EncodeWrapper<'any> {
+  sw: &'any mut Vector<u8>,
+}
+
+impl<'any> EncodeWrapper<'any> {
+  #[inline]
+  pub(crate) fn new(sw: &'any mut Vector<u8>) -> Self {
+    Self { sw }
+  }
+
+  /// See [`FilledBufferWriter`].
+  #[inline]
+  pub fn sw(&mut self) -> &mut Vector<u8> {
+    self.sw
+  }
+}
+
+impl Lease<[u8]> for EncodeWrapper<'_> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.sw
+  }
+}
diff --git a/wtx/src/database/client/mysql/executor_buffer.rs b/wtx/src/database/client/mysql/executor_buffer.rs
new file mode 100644
index 00000000..403a3a4f
--- /dev/null
+++ b/wtx/src/database/client/mysql/executor_buffer.rs
@@ -0,0 +1,78 @@
+use crate::{
+  database::client::mysql::MysqlStatements,
+  misc::{Lease, LeaseMut, Rng, Vector, partitioned_filled_buffer::PartitionedFilledBuffer},
+};
+use core::ops::Range;
+
+#[derive(Debug)]
+#[doc = _internal_buffer_doc!()]
+pub struct ExecutorBuffer {
+  pub(crate) enc_buffer: Vector<u8>,
+  pub(crate) net_buffer: PartitionedFilledBuffer,
+  pub(crate) stmts: MysqlStatements,
+  pub(crate) vb: Vector<(bool, Range<usize>)>,
+}
+
+impl ExecutorBuffer {
+  /// New instance
+  #[inline]
+  pub fn new<RNG>(max_stmts: usize, rng: RNG) -> Self
+  where
+    RNG: Rng,
+  {
+    Self {
+      enc_buffer: Vector::new(),
+      net_buffer: PartitionedFilledBuffer::new(),
+      stmts: MysqlStatements::new(max_stmts, rng),
+      vb: Vector::new(),
+    }
+  }
+
+  /// With default capacity.
+  #[inline]
+  pub fn with_capacity<RNG>(
+    (columns_cap, enc_cap, network_buffer_cap, rows_cap, stmts_cap): (
+      usize,
+      usize,
+      usize,
+      usize,
+      usize,
+    ),
+    max_stmts: usize,
+    rng: &mut RNG,
+  ) -> crate::Result<Self>
+  where
+    RNG: Rng,
+  {
+    Ok(Self {
+      enc_buffer: Vector::with_capacity(enc_cap)?,
+      net_buffer: PartitionedFilledBuffer::_with_capacity(network_buffer_cap)?,
+      stmts: MysqlStatements::with_capacity(columns_cap, max_stmts, rng, stmts_cap)?,
+      vb: Vector::with_capacity(rows_cap.saturating_mul(columns_cap))?,
+    })
+  }
+
+  /// Removes inner content
+  #[inline]
+  pub fn clear(&mut self) {
+    let Self { enc_buffer, net_buffer, stmts, vb } = self;
+    enc_buffer.clear();
+    net_buffer._clear();
+    stmts.clear();
+    vb.clear();
+  }
+}
+
+impl Lease<ExecutorBuffer> for ExecutorBuffer {
+  #[inline]
+  fn lease(&self) -> &ExecutorBuffer {
+    self
+  }
+}
+
+impl LeaseMut<ExecutorBuffer> for ExecutorBuffer {
+  #[inline]
+  fn lease_mut(&mut self) -> &mut ExecutorBuffer {
+    self
+  }
+}
diff --git a/wtx/src/database/client/mysql/flags.rs b/wtx/src/database/client/mysql/flags.rs
new file mode 100644
index 00000000..56a77915
--- /dev/null
+++ b/wtx/src/database/client/mysql/flags.rs
@@ -0,0 +1,20 @@
+create_enum! {
+  #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+  pub(crate) enum Flags<u16> {
+    NotNull = (1),
+    PrimaryKey = (2),
+    UniqueKey = (4),
+    MultipleKey = (8),
+    Blob = (16),
+    Unsigned = (32),
+    Zerofill = (64),
+    Binary = (128),
+    Enum = (256),
+    AutoIncrement = (512),
+    Timestamp = (1024),
+    Set = (2048),
+    NoDefaultValue = (4096),
+    OnUpdateNow = (8192),
+    Num = (32768),
+  }
+}
diff --git a/wtx/src/database/client/mysql/misc.rs b/wtx/src/database/client/mysql/misc.rs
new file mode 100644
index 00000000..3f060de2
--- /dev/null
+++ b/wtx/src/database/client/mysql/misc.rs
@@ -0,0 +1,126 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol,
+    encode_wrapper_protocol::EncodeWrapperProtocol, packet_req::PacketReq,
+  },
+  misc::{
+    _read_header, _read_payload, ArrayVector, Decode, Encode, Stream, Usize, Vector,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
+  },
+};
+use core::marker::PhantomData;
+
+#[inline]
+pub(crate) fn decode<'de, DO, E, T>(bytes: &mut &'de [u8], other: DO) -> Result<T, E>
+where
+  E: From<crate::Error>,
+  T: Decode<'de, MysqlProtocol<DO, E>>,
+{
+  T::decode(&mut (), &mut DecodeWrapperProtocol { bytes, other })
+}
+
+#[inline]
+pub(crate) fn encoded_len(len: usize) -> crate::Result<ArrayVector<u8, 9>> {
+  let [a, b, c, d, e, f, g, h] = len.to_le_bytes();
+  let mut rslt = ArrayVector::new();
+  match len {
+    0..=250 => rslt.push(a)?,
+    251..=65535 => {
+      rslt.push(252)?;
+      rslt.extend_from_copyable_slice(&[a, b])?;
+    }
+    65536..=16777215 => {
+      rslt.push(253)?;
+      rslt.extend_from_copyable_slice(&[a, b, c])?;
+    }
+    _ => {
+      rslt.push(254)?;
+      rslt.extend_from_copyable_slice(&[a, b, c, d, e, f, g, h])?;
+    }
+  }
+  Ok(rslt)
+}
+
+#[inline]
+pub(crate) async fn fetch_msg<S>(
+  pfb: &mut PartitionedFilledBuffer,
+  sequence_id: &mut u8,
+  stream: &mut S,
+) -> crate::Result<()>
+where
+  S: Stream,
+{
+  let (mut len, mut local_sequence_id) = fetch_one_msg(pfb, stream).await?;
+  while len == 0xFF_FF_FF {
+    let (local_len, local_local_sequence_id) = fetch_one_msg(pfb, stream).await?;
+    len = local_len;
+    local_sequence_id = local_local_sequence_id;
+  }
+  *sequence_id = local_sequence_id;
+  Ok(())
+}
+
+#[inline]
+pub(crate) async fn fetch_protocol<'de, S, T>(
+  pfb: &'de mut PartitionedFilledBuffer,
+  sequence_id: &mut u8,
+  stream: &mut S,
+) -> crate::Result<T>
+where
+  S: Stream,
+  T: for<'any> Decode<'de, MysqlProtocol<(), crate::Error>>,
+{
+  fetch_msg(pfb, sequence_id, stream).await?;
+  T::decode(&mut (), &mut DecodeWrapperProtocol { bytes: &mut pfb._current(), other: () })
+}
+
+#[inline]
+pub(crate) async fn send_packet<E, S, T>(
+  (capabilities, sequence_id): (&mut u64, &mut u8),
+  enc_buffer: &mut Vector<u8>,
+  payload: T,
+  stream: &mut S,
+) -> Result<(), E>
+where
+  E: From<crate::Error>,
+  S: Stream,
+  T: Encode<MysqlProtocol<(), E>>,
+{
+  *sequence_id = 0;
+  write_packet((capabilities, sequence_id), enc_buffer, payload, stream).await
+}
+
+#[inline]
+pub(crate) async fn write_packet<E, S, T>(
+  (capabilities, sequence_id): (&mut u64, &mut u8),
+  enc_buffer: &mut Vector<u8>,
+  payload: T,
+  stream: &mut S,
+) -> Result<(), E>
+where
+  E: From<crate::Error>,
+  S: Stream,
+  T: Encode<MysqlProtocol<(), E>>,
+{
+  let mut ew = EncodeWrapperProtocol::new(capabilities, enc_buffer);
+  PacketReq(payload, PhantomData).encode(&mut ew, sequence_id, stream).await?;
+  stream.write_all(enc_buffer).await?;
+  Ok(())
+}
+
+#[inline]
+async fn fetch_one_msg<S>(
+  pfb: &mut PartitionedFilledBuffer,
+  stream: &mut S,
+) -> crate::Result<(usize, u8)>
+where
+  S: Stream,
+{
+  pfb._reserve(4)?;
+  let mut read = pfb._following_len();
+  let buffer = pfb._following_rest_mut();
+  let [a0, b0, c0, sequence_id] = _read_header::<0, 4, S>(buffer, &mut read, stream).await?;
+  let len = Usize::from(u32::from_le_bytes([a0, b0, c0, 0])).into_usize();
+  _read_payload((4, len), pfb, &mut read, stream).await?;
+  Ok((len, sequence_id.wrapping_add(1)))
+}
diff --git a/wtx/src/database/client/mysql/mysql_error.rs b/wtx/src/database/client/mysql/mysql_error.rs
new file mode 100644
index 00000000..30689aa6
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_error.rs
@@ -0,0 +1,8 @@
+/// Error
+#[derive(Debug)]
+pub enum MysqlError {
+  /// Unknown authentication method
+  UnknownAuthPlugin,
+  /// Unknown configuration parameter
+  UnknownConfigurationParameter,
+}
diff --git a/wtx/src/database/client/mysql/mysql_executor.rs b/wtx/src/database/client/mysql/mysql_executor.rs
new file mode 100644
index 00000000..443be59b
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_executor.rs
@@ -0,0 +1,264 @@
+mod connection;
+mod fetch;
+mod prepare;
+mod simple_query;
+
+use crate::{
+  database::{
+    Database, Executor, RecordValues, Records, StmtCmd,
+    client::mysql::{
+      Config, ExecutorBuffer, Mysql, MysqlRecord, MysqlRecords, capability::Capability,
+      misc::write_packet, mysql_protocol::initial_req::InitialReq,
+    },
+  },
+  misc::{ConnectionState, DEController, LeaseMut, Stream, StreamWithTls, Usize},
+};
+use core::marker::PhantomData;
+
+pub(crate) const DFLT_PACKET_SIZE: u32 = 1024;
+pub(crate) const MAX_PAYLOAD: u32 = 16777215;
+
+/// Executor
+#[derive(Debug)]
+pub struct MysqlExecutor<E, EB, S> {
+  pub(crate) capabilities: u64,
+  pub(crate) cs: ConnectionState,
+  pub(crate) eb: EB,
+  pub(crate) phantom: PhantomData<fn() -> E>,
+  pub(crate) sequence_id: u8,
+  pub(crate) stream: S,
+}
+
+impl<E, EB, S> MysqlExecutor<E, EB, S>
+where
+  E: From<crate::Error>,
+  EB: LeaseMut<ExecutorBuffer>,
+  S: Stream,
+{
+  /// Connects with an unencrypted stream.
+  #[inline]
+  pub async fn connect(config: &Config<'_>, mut eb: EB, mut stream: S) -> Result<Self, E> {
+    eb.lease_mut().clear();
+    let mut sequence_id = 0;
+    let ExecutorBuffer { enc_buffer, net_buffer, .. } = eb.lease_mut();
+    let tuple = Self::connect0(config, net_buffer, &mut sequence_id, &mut stream).await?;
+    let (mut capabilities, handshake_res) = tuple;
+    let plugin = handshake_res.auth_plugin;
+    Self::connect1(
+      (&mut capabilities, &mut sequence_id),
+      config,
+      enc_buffer,
+      &handshake_res,
+      &mut stream,
+    )
+    .await?;
+    Self::connect2::<false>(
+      (handshake_res.auth_plugin_data.0, handshake_res.auth_plugin_data.1.try_into()?),
+      (&mut capabilities, &mut sequence_id),
+      config,
+      enc_buffer,
+      net_buffer,
+      plugin,
+      &mut stream,
+    )
+    .await?;
+    Self::connect3(enc_buffer, config)?;
+    Ok(Self {
+      capabilities,
+      cs: ConnectionState::Open,
+      eb,
+      phantom: PhantomData,
+      sequence_id,
+      stream,
+    })
+  }
+
+  /// Initially connects with an unencrypted stream that should be later upgraded to an encrypted
+  /// stream.
+  #[inline]
+  pub async fn connect_encrypted<F, IS, RNG>(
+    config: &Config<'_>,
+    mut eb: EB,
+    mut stream: IS,
+    cb: impl FnOnce(IS) -> F,
+  ) -> Result<Self, E>
+  where
+    F: Future<Output = crate::Result<S>>,
+    IS: Stream,
+    S: StreamWithTls,
+  {
+    eb.lease_mut().clear();
+    let mut sequence_id = 0;
+    let ExecutorBuffer { enc_buffer, net_buffer, .. } = eb.lease_mut();
+    let tuple = Self::connect0(config, net_buffer, &mut sequence_id, &mut stream).await?;
+    let (mut capabilities, handshake_res) = tuple;
+    {
+      capabilities |= u64::from(Capability::Ssl);
+      let req = InitialReq { collation: config.collation, max_packet_size: DFLT_PACKET_SIZE };
+      write_packet((&mut capabilities, &mut sequence_id), enc_buffer, req, &mut stream).await?;
+      enc_buffer.clear();
+    }
+    let mut enc_stream = cb(stream).await?;
+    let plugin = handshake_res.auth_plugin;
+    Self::connect1(
+      (&mut capabilities, &mut sequence_id),
+      config,
+      enc_buffer,
+      &handshake_res,
+      &mut enc_stream,
+    )
+    .await?;
+    Self::connect2::<true>(
+      (handshake_res.auth_plugin_data.0, handshake_res.auth_plugin_data.1.try_into()?),
+      (&mut capabilities, &mut sequence_id),
+      config,
+      enc_buffer,
+      net_buffer,
+      plugin,
+      &mut enc_stream,
+    )
+    .await?;
+    Self::connect3(enc_buffer, config)?;
+    Ok(Self {
+      capabilities,
+      cs: ConnectionState::Open,
+      eb,
+      phantom: PhantomData,
+      sequence_id,
+      stream: enc_stream,
+    })
+  }
+}
+
+impl<E, EB, S> Executor for MysqlExecutor<E, EB, S>
+where
+  E: From<crate::Error>,
+  EB: LeaseMut<ExecutorBuffer>,
+  S: Stream,
+{
+  type Database = Mysql<E>;
+
+  #[inline]
+  fn connection_state(&self) -> ConnectionState {
+    self.cs
+  }
+
+  #[inline]
+  async fn execute(
+    &mut self,
+    cmd: &str,
+    cb: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> Result<(), <Self::Database as DEController>::Error> {
+    let Self { capabilities, cs: _, eb, phantom: _, sequence_id, stream } = self;
+    let ExecutorBuffer { enc_buffer, net_buffer, stmts: _, vb } = eb.lease_mut();
+    Self::simple_query_execute(
+      (capabilities, sequence_id),
+      cmd,
+      enc_buffer,
+      net_buffer,
+      stream,
+      vb,
+      cb,
+    )
+    .await?;
+    Ok(())
+  }
+
+  #[inline]
+  async fn execute_with_stmt<SC, RV>(
+    &mut self,
+    sc: SC,
+    rv: RV,
+  ) -> Result<u64, <Self::Database as DEController>::Error>
+  where
+    RV: RecordValues<Self::Database>,
+    SC: StmtCmd,
+  {
+    Ok(Usize::from(self.fetch_many_with_stmt(sc, rv, |_| Ok(())).await?.len()).into_u64())
+  }
+
+  #[inline]
+  async fn fetch_with_stmt<SC, RV>(
+    &mut self,
+    sc: SC,
+    rv: RV,
+  ) -> Result<<Self::Database as Database>::Record<'_>, E>
+  where
+    RV: RecordValues<Self::Database>,
+    SC: StmtCmd,
+  {
+    let Self { capabilities, cs: _, eb, sequence_id, stream, .. } = self;
+    let ExecutorBuffer { enc_buffer, net_buffer, stmts, vb, .. } = eb.lease_mut();
+    let mut record_len_opt = None;
+    let stmt = Self::write_send_await_stmt::<_, _, true>(
+      (capabilities, sequence_id),
+      enc_buffer,
+      net_buffer,
+      rv,
+      sc,
+      stmts,
+      stream,
+      vb,
+      |local_record| {
+        record_len_opt = Some(local_record.bytes.len());
+        Ok(())
+      },
+    )
+    .await?;
+    let Some(record_len) = record_len_opt else {
+      panic!();
+    };
+    Ok(MysqlRecord {
+      bytes: enc_buffer.get(..record_len).unwrap_or_default(),
+      phantom: PhantomData,
+      stmt,
+      values_bytes_offsets: vb.get(0..record_len).unwrap_or_default(),
+    })
+  }
+
+  #[inline]
+  async fn fetch_many_with_stmt<SC, RV>(
+    &mut self,
+    sc: SC,
+    rv: RV,
+    mut cb: impl FnMut(&<Self::Database as Database>::Record<'_>) -> Result<(), E>,
+  ) -> Result<<Self::Database as Database>::Records<'_>, E>
+  where
+    RV: RecordValues<Self::Database>,
+    SC: StmtCmd,
+  {
+    let Self { capabilities, cs: _, eb, sequence_id, stream, .. } = self;
+    let ExecutorBuffer { enc_buffer, net_buffer, stmts, vb, .. } = eb.lease_mut();
+    let stmt = Self::write_send_await_stmt::<_, _, false>(
+      (capabilities, sequence_id),
+      enc_buffer,
+      net_buffer,
+      rv,
+      sc,
+      stmts,
+      stream,
+      vb,
+      |record| cb(&record),
+    )
+    .await?;
+    Ok(MysqlRecords::new(&[], &[], stmt.clone(), vb))
+  }
+
+  #[inline]
+  async fn prepare(&mut self, cmd: &str) -> Result<u64, E> {
+    let Self { capabilities, cs: _, eb, phantom: _, sequence_id, stream } = self;
+    let ExecutorBuffer { enc_buffer, net_buffer, stmts, .. } = eb.lease_mut();
+    Ok(
+      Self::write_send_await_stmt_prot(
+        (capabilities, sequence_id),
+        enc_buffer,
+        net_buffer,
+        cmd,
+        stmts,
+        stream,
+      )
+      .await?
+      .0,
+    )
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_executor/connection.rs b/wtx/src/database/client/mysql/mysql_executor/connection.rs
new file mode 100644
index 00000000..fd3b5c69
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_executor/connection.rs
@@ -0,0 +1,188 @@
+use crate::{
+  database::client::mysql::{
+    Config, ExecutorBuffer, MysqlExecutor,
+    auth_plugin::AuthPlugin,
+    capability::Capability,
+    misc::{decode, fetch_msg, write_packet},
+    mysql_executor::DFLT_PACKET_SIZE,
+    mysql_protocol::{
+      auth_switch_req::AuthSwitchReq, auth_switch_res::AuthSwitchRes, handshake_req::HandshakeReq,
+      handshake_res::HandshakeRes, ok_res::OkRes,
+    },
+  },
+  misc::{
+    ArrayVector, LeaseMut, Stream, Vector, partitioned_filled_buffer::PartitionedFilledBuffer,
+  },
+};
+
+impl<E, EB, S> MysqlExecutor<E, EB, S>
+where
+  E: From<crate::Error>,
+  EB: LeaseMut<ExecutorBuffer>,
+  S: Stream,
+{
+  #[inline]
+  pub(crate) async fn connect0<'nb, IS>(
+    config: &Config<'_>,
+    net_buffer: &'nb mut PartitionedFilledBuffer,
+    sequence_id: &mut u8,
+    stream: &mut IS,
+  ) -> Result<(u64, HandshakeRes<'nb>), E>
+  where
+    IS: Stream,
+  {
+    let mut capabilities: u64 = u64::from(Capability::DeprecateEof)
+      | u64::from(Capability::FoundRows)
+      | u64::from(Capability::IgnoreSpace)
+      | u64::from(Capability::MultiResults)
+      | u64::from(Capability::MultiStatements)
+      | u64::from(Capability::OptionalResultsetMetadata)
+      | u64::from(Capability::PluginAuth)
+      | u64::from(Capability::PluginAuthLenencData)
+      | u64::from(Capability::Protocol41)
+      | u64::from(Capability::PsMultiResults)
+      | u64::from(Capability::SecureConnection)
+      | u64::from(Capability::Transactions);
+    if config.db.is_some() {
+      capabilities |= u64::from(Capability::ConnectWithDb);
+    }
+    fetch_msg(net_buffer, sequence_id, stream).await?;
+    let mut bytes = net_buffer._current();
+    let res: HandshakeRes<'_> = decode(&mut bytes, ())?;
+    Ok((capabilities, res))
+  }
+
+  #[inline]
+  pub(crate) async fn connect1(
+    (capabilities, sequence_id): (&mut u64, &mut u8),
+    config: &Config<'_>,
+    enc_buffer: &mut Vector<u8>,
+    handshake_res: &HandshakeRes<'_>,
+    stream: &mut S,
+  ) -> Result<(), E> {
+    *capabilities &= handshake_res.capabilities;
+    let tuple = (handshake_res.auth_plugin, config.password);
+    let auth_response = if let (Some(plugin), Some(pw)) = tuple {
+      Some(plugin.mask_pw(
+        (&handshake_res.auth_plugin_data.0, handshake_res.auth_plugin_data.1),
+        pw.as_bytes(),
+      )?)
+    } else {
+      None
+    };
+    let handshake_req = HandshakeReq {
+      auth_plugin: handshake_res.auth_plugin,
+      auth_response,
+      collation: config.collation,
+      database: config.db,
+      max_packet_size: DFLT_PACKET_SIZE,
+      username: config.user,
+    };
+    write_packet((capabilities, sequence_id), enc_buffer, handshake_req, stream).await?;
+    enc_buffer.clear();
+    Ok(())
+  }
+
+  #[inline]
+  pub(crate) async fn connect2<const IS_TLS: bool>(
+    auth_plugin_data: ([u8; 8], ArrayVector<u8, 24>),
+    (capabilities, sequence_id): (&mut u64, &mut u8),
+    config: &Config<'_>,
+    enc_buffer: &mut Vector<u8>,
+    net_buffer: &mut PartitionedFilledBuffer,
+    mut plugin: Option<AuthPlugin>,
+    stream: &mut S,
+  ) -> Result<(), E> {
+    loop {
+      fetch_msg(net_buffer, sequence_id, stream).await?;
+      match net_buffer._current() {
+        [] => {
+          break;
+        }
+        [0, rest @ ..] => {
+          let mut local_rest = rest;
+          let _: OkRes = decode(&mut local_rest, ())?;
+          break;
+        }
+        [254, rest @ ..] => {
+          let mut local_rest = rest;
+          let other = config.enable_cleartext_plugin;
+          let res_rslt: Result<AuthSwitchRes, _> = decode(&mut local_rest, other);
+          let res = res_rslt?;
+          plugin = Some(res.auth_plugin);
+          let bytes = res.auth_plugin.mask_pw(
+            if let Some((lhs, rhs)) = &res.data {
+              (lhs.as_slice(), rhs.as_slice())
+            } else {
+              (&[][..], &[][..])
+            },
+            config.password.as_deref().unwrap_or_default().as_bytes(),
+          )?;
+          let payload = AuthSwitchReq(&bytes);
+          write_packet((capabilities, sequence_id), enc_buffer, payload, stream).await?;
+        }
+        [_, rest @ ..] => {
+          if let (Some(plugin), Some(password)) = (plugin, &config.password) {
+            let [a, b, ..] = rest else {
+              panic!();
+            };
+            if plugin
+              .manage_caching_sha2::<_, _, IS_TLS>(
+                (auth_plugin_data.0, &auth_plugin_data.1),
+                [*a, *b],
+                (capabilities, sequence_id),
+                enc_buffer,
+                net_buffer,
+                password,
+                stream,
+              )
+              .await?
+            {
+              break;
+            }
+          } else {
+            panic!();
+          }
+        }
+      }
+    }
+    Ok(())
+  }
+
+  #[inline]
+  pub(crate) fn connect3(buffer: &mut Vector<u8>, config: &Config<'_>) -> crate::Result<()> {
+    buffer.extend_from_copyable_slice("SET ".as_bytes())?;
+    let sql_mode_opt = match (config.no_engine_substitution, config.pipes_as_concat) {
+      (false, false) => None,
+      (false, true) => Some(&b"sql_mode=(SELECT CONCAT(@@sql_mode, ',PIPES_AS_CONCAT')),"[..]),
+      (true, false) => {
+        Some(&b"sql_mode=(SELECT CONCAT(@@sql_mode, ',NO_ENGINE_SUBSTITUTION')),"[..])
+      }
+      (true, true) => Some(
+        &b"sql_mode=(SELECT CONCAT(@@sql_mode, ',NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT')),"[..],
+      ),
+    };
+    if let Some(sql_mode) = sql_mode_opt {
+      buffer.extend_from_copyable_slice(sql_mode)?;
+    }
+    if let Some(timezone) = &config.timezone {
+      let _ = buffer.extend_from_copyable_slices([b"time_zone=", timezone.as_bytes(), b"',"])?;
+    }
+    if config.set_names {
+      let _ = buffer.extend_from_copyable_slices([
+        "NAMES ".as_bytes(),
+        b"config.charset",
+        b" COLLATE ",
+        b"config.collation",
+        b",",
+      ])?;
+    }
+
+    if buffer.len() > 4 {
+      let _ = buffer.pop();
+      //config.execute(&options).await?;
+    }
+    buffer.clear();
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_executor/fetch.rs b/wtx/src/database/client/mysql/mysql_executor/fetch.rs
new file mode 100644
index 00000000..abf2f1a7
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_executor/fetch.rs
@@ -0,0 +1,132 @@
+use core::{marker::PhantomData, ops::Range};
+
+use crate::{
+  database::{
+    RecordValues, StmtCmd,
+    client::mysql::{
+      ExecutorBuffer, Mysql, MysqlExecutor, MysqlRecord, MysqlStatement, MysqlStatements,
+      column::Column,
+      misc::{decode, fetch_msg, fetch_protocol, send_packet},
+      mysql_protocol::{
+        binary_row_res::BinaryRowRes, column_res::ColumnRes, eof_res::EofRes, lenenc::Lenenc,
+        ok_res::OkRes, stmt_execute_req::StmtExecuteReq, text_row_res::TextRowRes,
+      },
+      status::Status,
+    },
+  },
+  misc::{LeaseMut, Stream, Usize, Vector, partitioned_filled_buffer::PartitionedFilledBuffer},
+};
+
+impl<E, EB, S> MysqlExecutor<E, EB, S>
+where
+  E: From<crate::Error>,
+  EB: LeaseMut<ExecutorBuffer>,
+  S: Stream,
+{
+  #[inline]
+  pub(crate) async fn fetch_cmd<const IS_SINGLE: bool>(
+    net_buffer: &mut PartitionedFilledBuffer,
+    sequence_id: &mut u8,
+    stmt: Option<&MysqlStatement<'_>>,
+    stream: &mut S,
+    vb: &mut Vector<(bool, Range<usize>)>,
+    mut cb_end: impl FnMut(u64) -> Result<(), E>,
+    mut cb_rslt: impl FnMut(MysqlRecord<'_, E>) -> Result<(), E>,
+  ) -> Result<(), E> {
+    let smre = u16::from(Status::ServerMoreResultsExists);
+    let mut has_at_least_one_record = false;
+    loop {
+      fetch_msg(net_buffer, sequence_id, stream).await?;
+      let [first0, rest0 @ ..] = net_buffer._current() else {
+        panic!();
+      };
+      let mut local_rest = rest0;
+      if *first0 == 0 || *first0 == 255 {
+        let res: OkRes = decode(&mut local_rest, ())?;
+        if u16::from(res.status) & smre == smre {
+          continue;
+        }
+        cb_end(res.affected_rows)?;
+        return Ok(());
+      }
+
+      let columns_lenenc: Lenenc = decode(&mut local_rest, ())?;
+      let columns = Usize::try_from(columns_lenenc.0)?.into_usize();
+
+      for _ in 0..columns {
+        let res: ColumnRes = fetch_protocol(net_buffer, sequence_id, stream).await?;
+        let _column = Column::from_column_res(&res);
+      }
+
+      loop {
+        fetch_msg(net_buffer, sequence_id, stream).await?;
+        let mut current = net_buffer._current();
+        if current.first() == Some(&254) && current.len() < 9 {
+          let res: EofRes = decode(&mut current, ())?;
+          cb_end(0)?;
+          if u16::from(res.status) & smre == smre {
+            break;
+          }
+          return Ok(());
+        }
+        if IS_SINGLE {
+          if has_at_least_one_record {
+            panic!();
+          } else {
+            has_at_least_one_record = true;
+          }
+        }
+        if let Some(elem) = stmt {
+          let begin = vb.len();
+          let res: BinaryRowRes<'_> = decode(&mut current, (elem, &mut *vb))?;
+          let rec = MysqlRecord {
+            bytes: res.0,
+            phantom: PhantomData,
+            stmt: elem.clone(),
+            values_bytes_offsets: vb.get(begin..).unwrap_or_default(),
+          };
+          cb_rslt(rec)?;
+        } else {
+          let _row: TextRowRes = decode(&mut current, (columns, &mut *vb))?;
+        };
+      }
+    }
+  }
+
+  #[inline]
+  pub(crate) async fn write_send_await_stmt<'stmts, RV, SC, const IS_SINGLE: bool>(
+    (capabilities, sequence_id): (&mut u64, &mut u8),
+    enc_buffer: &mut Vector<u8>,
+    net_buffer: &mut PartitionedFilledBuffer,
+    rv: RV,
+    sc: SC,
+    stmts: &'stmts mut MysqlStatements,
+    stream: &mut S,
+    vb: &mut Vector<(bool, Range<usize>)>,
+    cb: impl FnMut(MysqlRecord<'_, E>) -> Result<(), E>,
+  ) -> Result<MysqlStatement<'stmts>, E>
+  where
+    RV: RecordValues<Mysql<E>>,
+    SC: StmtCmd,
+  {
+    let (_, _, stmt) = Self::write_send_await_stmt_prot(
+      (capabilities, sequence_id),
+      enc_buffer,
+      net_buffer,
+      sc,
+      stmts,
+      stream,
+    )
+    .await?;
+    send_packet(
+      (capabilities, sequence_id),
+      enc_buffer,
+      StmtExecuteReq { rv, stmt: &stmt },
+      stream,
+    )
+    .await?;
+    Self::fetch_cmd::<IS_SINGLE>(net_buffer, sequence_id, Some(&stmt), stream, vb, |_| Ok(()), cb)
+      .await?;
+    Ok(stmt)
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_executor/prepare.rs b/wtx/src/database/client/mysql/mysql_executor/prepare.rs
new file mode 100644
index 00000000..0dac0c20
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_executor/prepare.rs
@@ -0,0 +1,102 @@
+use crate::{
+  database::{
+    DatabaseError, StmtCmd,
+    client::{
+      mysql::{
+        ExecutorBuffer, MysqlExecutor, MysqlStatement, MysqlStatements, Ty,
+        column::Column,
+        misc::{fetch_protocol, send_packet},
+        mysql_protocol::{
+          column_res::ColumnRes, prepare_req::PrepareReq, prepare_res::PrepareRes,
+          stmt_close_req::StmtCloseReq,
+        },
+        ty_params::TyParams,
+      },
+      rdbms::{U64Array, statements_misc::StatementsMisc, u64_array},
+    },
+  },
+  misc::{
+    ArrayString, LeaseMut, Stream, Vector, partitioned_filled_buffer::PartitionedFilledBuffer,
+  },
+};
+
+impl<E, EB, S> MysqlExecutor<E, EB, S>
+where
+  E: From<crate::Error>,
+  EB: LeaseMut<ExecutorBuffer>,
+  S: Stream,
+{
+  #[inline]
+  pub(crate) async fn write_send_await_stmt_prot<'stmts, SC>(
+    (capabilities, sequence_id): (&mut u64, &mut u8),
+    enc_buffer: &mut Vector<u8>,
+    net_buffer: &mut PartitionedFilledBuffer,
+    sc: SC,
+    stmts: &'stmts mut MysqlStatements,
+    stream: &mut S,
+  ) -> Result<(u64, U64Array, MysqlStatement<'stmts>), E>
+  where
+    SC: StmtCmd,
+  {
+    let stmt_cmd_id = sc.hash(stmts.hasher_mut());
+    let stmt_cmd_id_array = u64_array(stmt_cmd_id);
+    if stmts.get_by_stmt_cmd_id(stmt_cmd_id).is_some() {
+      // FIXME(stable): Use `if let Some ...` with polonius
+      return Ok((stmt_cmd_id, stmt_cmd_id_array, stmts.get_by_stmt_cmd_id(stmt_cmd_id).unwrap()));
+    }
+
+    let stmt_cmd = sc.cmd().ok_or_else(|| E::from(DatabaseError::UnknownStatementId.into()))?;
+
+    send_packet(
+      (capabilities, sequence_id),
+      enc_buffer,
+      PrepareReq { query: stmt_cmd.as_bytes() },
+      stream,
+    )
+    .await?;
+    let prepare_res: PrepareRes = fetch_protocol(net_buffer, sequence_id, stream).await?;
+    let mut builder = stmts.builder();
+    let _ = builder.expand(prepare_res.params.max(prepare_res.columns).into(), dummy())?;
+    let elements = builder.inserted_elements();
+    for idx in 0..prepare_res.params {
+      let res: ColumnRes = fetch_protocol(net_buffer, sequence_id, stream).await?;
+      let Some(elem0) = elements.get_mut(usize::from(idx)) else {
+        break;
+      };
+      elem0.1 = Column::from_column_res(&res).ty_params;
+    }
+    for idx in 0..prepare_res.columns {
+      let res: ColumnRes = fetch_protocol(net_buffer, sequence_id, stream).await?;
+      let Some(elem) = elements.get_mut(usize::from(idx)) else {
+        break;
+      };
+      elem.0 = Column::from_column_res(&res);
+    }
+    let sm = StatementsMisc::new(
+      prepare_res.statement_id,
+      prepare_res.columns.into(),
+      prepare_res.params.into(),
+    );
+    let idx = builder.build(stmt_cmd_id, sm)?;
+    enc_buffer.clear();
+    send_packet(
+      (capabilities, sequence_id),
+      enc_buffer,
+      StmtCloseReq { statement: prepare_res.statement_id },
+      stream,
+    )
+    .await?;
+    let Some(stmt) = stmts.get_by_idx(idx) else {
+      return Err(crate::Error::ProgrammingError.into());
+    };
+    Ok((stmt_cmd_id, stmt_cmd_id_array, stmt))
+  }
+}
+
+#[inline]
+fn dummy() -> (Column, TyParams) {
+  (
+    Column { name: ArrayString::new(), ty_params: TyParams { flags: 0, ty: Ty::Bit } },
+    TyParams { flags: 0, ty: Ty::Bit },
+  )
+}
diff --git a/wtx/src/database/client/mysql/mysql_executor/simple_query.rs b/wtx/src/database/client/mysql/mysql_executor/simple_query.rs
new file mode 100644
index 00000000..d3fe43ab
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_executor/simple_query.rs
@@ -0,0 +1,48 @@
+use core::ops::Range;
+
+use crate::{
+  database::client::mysql::{
+    ExecutorBuffer, MysqlExecutor, misc::send_packet, mysql_protocol::query_req::QueryReq,
+  },
+  misc::{LeaseMut, Stream, Vector, partitioned_filled_buffer::PartitionedFilledBuffer},
+};
+
+impl<E, EB, S> MysqlExecutor<E, EB, S>
+where
+  E: From<crate::Error>,
+  EB: LeaseMut<ExecutorBuffer>,
+  S: Stream,
+{
+  #[inline]
+  pub(crate) async fn simple_query_execute(
+    (capabilities, sequence_id): (&mut u64, &mut u8),
+    cmd: &str,
+    enc_buffer: &mut Vector<u8>,
+    net_buffer: &mut PartitionedFilledBuffer,
+    stream: &mut S,
+    vb: &mut Vector<(bool, Range<usize>)>,
+    mut cb: impl FnMut(u64) -> Result<(), E>,
+  ) -> Result<(), E> {
+    send_packet(
+      (capabilities, sequence_id),
+      enc_buffer,
+      QueryReq { query: cmd.as_bytes() },
+      stream,
+    )
+    .await?;
+    Self::fetch_cmd::<false>(
+      net_buffer,
+      sequence_id,
+      None,
+      stream,
+      vb,
+      |num| {
+        cb(num)?;
+        Ok(())
+      },
+      |_| Ok(()),
+    )
+    .await?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol.rs b/wtx/src/database/client/mysql/mysql_protocol.rs
new file mode 100644
index 00000000..71630b3f
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol.rs
@@ -0,0 +1,57 @@
+pub(crate) mod auth_switch_req;
+pub(crate) mod auth_switch_res;
+pub(crate) mod binary_row_res;
+pub(crate) mod column_res;
+pub(crate) mod decode_wrapper_protocol;
+pub(crate) mod encode_wrapper_protocol;
+pub(crate) mod eof_res;
+pub(crate) mod handshake_req;
+pub(crate) mod handshake_res;
+pub(crate) mod initial_req;
+pub(crate) mod lenenc;
+pub(crate) mod lenenc_bytes;
+pub(crate) mod ok_res;
+pub(crate) mod packet_req;
+pub(crate) mod prepare_req;
+pub(crate) mod prepare_res;
+pub(crate) mod query_req;
+pub(crate) mod stmt_close_req;
+pub(crate) mod stmt_execute_req;
+pub(crate) mod text_row_res;
+
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    decode_wrapper_protocol::DecodeWrapperProtocol, encode_wrapper_protocol::EncodeWrapperProtocol,
+  },
+  misc::{DEController, Encode},
+};
+use core::marker::PhantomData;
+
+pub(crate) struct MysqlProtocol<DO, E>(PhantomData<(DO, E)>);
+
+impl<DO, E> DEController for MysqlProtocol<DO, E>
+where
+  E: From<crate::Error>,
+{
+  type Aux = ();
+  type DecodeWrapper<'inner, 'outer>
+    = DecodeWrapperProtocol<'inner, 'outer, DO>
+  where
+    'inner: 'outer;
+  type Error = E;
+  type EncodeWrapper<'inner, 'outer>
+    = EncodeWrapperProtocol<'inner>
+  where
+    'inner: 'outer;
+}
+
+impl<DO, E> Encode<MysqlProtocol<DO, E>> for &[u8]
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    ew.enc_buffer.extend_from_copyable_slice(self)?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/auth_switch_req.rs b/wtx/src/database/client/mysql/mysql_protocol/auth_switch_req.rs
new file mode 100644
index 00000000..290643d3
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/auth_switch_req.rs
@@ -0,0 +1,19 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol,
+  },
+  misc::Encode,
+};
+
+pub(crate) struct AuthSwitchReq<'bytes>(pub(crate) &'bytes [u8]);
+
+impl<E> Encode<MysqlProtocol<(), E>> for AuthSwitchReq<'_>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    ew.enc_buffer.extend_from_copyable_slice(self.0)?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/auth_switch_res.rs b/wtx/src/database/client/mysql/mysql_protocol/auth_switch_res.rs
new file mode 100644
index 00000000..5c3940ee
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/auth_switch_res.rs
@@ -0,0 +1,47 @@
+use crate::{
+  database::client::mysql::{
+    auth_plugin::AuthPlugin,
+    mysql_protocol::{MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol},
+  },
+  misc::{Decode, bytes_split_once1},
+};
+
+pub(crate) struct AuthSwitchRes {
+  pub(crate) auth_plugin: AuthPlugin,
+  pub(crate) data: Option<([u8; 8], [u8; 12])>,
+}
+
+impl<E> Decode<'_, MysqlProtocol<bool, E>> for AuthSwitchRes
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(_: &mut (), dw: &mut DecodeWrapperProtocol<'_, '_, bool>) -> Result<Self, E> {
+    let [a, rest0 @ ..] = dw.bytes else {
+      panic!();
+    };
+    if *a != 254 {
+      panic!();
+    }
+    let Some((auth_plugin_bytes, rest1)) = bytes_split_once1(rest0, b'\0') else {
+      panic!();
+    };
+    let auth_plugin = AuthPlugin::try_from(auth_plugin_bytes)?;
+    if matches!(auth_plugin, AuthPlugin::MySqlClear) && dw.other {
+      panic!();
+    }
+    if matches!(auth_plugin, AuthPlugin::MySqlClear) && rest1.is_empty() {
+      return Ok(Self { auth_plugin, data: None });
+    }
+    let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, _u] = rest1 else {
+      panic!();
+    };
+    Ok(Self {
+      auth_plugin,
+      data: Some((
+        [*a, *b, *c, *d, *e, *f, *g, *h],
+        [*i, *j, *k, *l, *m, *n, *o, *p, *q, *r, *s, *t],
+      )),
+    })
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/binary_row_res.rs b/wtx/src/database/client/mysql/mysql_protocol/binary_row_res.rs
new file mode 100644
index 00000000..996ba418
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/binary_row_res.rs
@@ -0,0 +1,88 @@
+use core::ops::Range;
+
+use crate::{
+  database::client::mysql::{
+    MysqlStatement, Ty,
+    mysql_protocol::{
+      MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol, lenenc::Lenenc,
+    },
+  },
+  misc::{Decode, Usize, Vector},
+};
+
+type Params<'any> = (&'any MysqlStatement<'any>, &'any mut Vector<(bool, Range<usize>)>);
+
+#[derive(Debug)]
+pub(crate) struct BinaryRowRes<'de>(pub(crate) &'de [u8]);
+
+impl<'de, E> Decode<'de, MysqlProtocol<Params<'_>, E>> for BinaryRowRes<'de>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapperProtocol<'de, '_, Params<'_>>) -> Result<Self, E> {
+    let [a, rest0 @ ..] = dw.bytes else {
+      panic!();
+    };
+    *dw.bytes = rest0;
+    if *a != 0 {
+      panic!();
+    }
+    let bitmap_len = dw.other.0._columns_len().wrapping_add(9) / 8;
+    let Some((bitmap, rest1)) = dw.bytes.split_at_checked(bitmap_len) else {
+      panic!();
+    };
+    *dw.bytes = rest1;
+    dw.other.1.reserve(dw.other.0._columns_len())?;
+    let mut idx: usize = 0;
+    for (column_idx, column) in dw.other.0._columns().enumerate() {
+      let column_null_idx = column_idx.wrapping_add(2);
+      let byte_idx = column_null_idx / 8;
+      let bit_idx = column_null_idx % 8;
+      let is_null = bitmap.get(byte_idx).copied().unwrap_or_default() & (1u8 << bit_idx) != 0;
+      if is_null {
+        dw.other.1.push((true, idx..idx))?;
+        continue;
+      }
+      let len = match column.ty_params.ty {
+        Ty::Double => 8,
+        Ty::Float => 4,
+        Ty::Long | Ty::Int24 => 4,
+        Ty::LongLong => 8,
+        Ty::Short | Ty::Year => 2,
+        Ty::Tiny => 1,
+
+        Ty::Bit
+        | Ty::Blob
+        | Ty::Decimal
+        | Ty::Enum
+        | Ty::Geometry
+        | Ty::Json
+        | Ty::LongBlob
+        | Ty::MediumBlob
+        | Ty::NewDecimal
+        | Ty::Set
+        | Ty::String
+        | Ty::TinyBlob
+        | Ty::VarChar
+        | Ty::VarString => {
+          let before = dw.bytes.len();
+          let rslt = Usize::try_from(Lenenc::decode(aux, dw)?.0)?.into_usize();
+          idx = idx.wrapping_add(dw.bytes.len().wrapping_sub(before));
+          rslt
+        }
+
+        Ty::Date | Ty::Datetime | Ty::Time | Ty::Timestamp => {
+          usize::from(*dw.bytes.first().unwrap())
+        }
+
+        Ty::Null => panic!(),
+      };
+      let begin = idx;
+      idx = idx.wrapping_add(len);
+      *dw.bytes = dw.bytes.get(len..).unwrap_or_default();
+      dw.other.1.push((false, begin..idx))?;
+    }
+    Ok(Self(rest1))
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/column_res.rs b/wtx/src/database/client/mysql/mysql_protocol/column_res.rs
new file mode 100644
index 00000000..d4cb2fb2
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/column_res.rs
@@ -0,0 +1,46 @@
+use crate::{
+  database::{
+    Identifier,
+    client::mysql::{
+      mysql_protocol::{
+        MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol, lenenc::Lenenc,
+        lenenc_bytes::LenencBytes,
+      },
+      ty::Ty,
+    },
+  },
+  misc::Decode,
+};
+
+#[derive(Debug)]
+pub(crate) struct ColumnRes {
+  pub(crate) alias: Identifier,
+  pub(crate) flags: u16,
+  pub(crate) name: Identifier,
+  pub(crate) ty: Ty,
+}
+
+impl<DO, E> Decode<'_, MysqlProtocol<DO, E>> for ColumnRes
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapperProtocol<'_, '_, DO>) -> Result<Self, E> {
+    let _catalog = LenencBytes::decode(aux, dw)?.0;
+    let _schema = LenencBytes::decode(aux, dw)?.0;
+    let _table_alias = LenencBytes::decode(aux, dw)?.0;
+    let _table = LenencBytes::decode(aux, dw)?.0;
+    let alias = LenencBytes::decode(aux, dw)?.0;
+    let name = LenencBytes::decode(aux, dw)?.0;
+    let _next_len = Lenenc::decode(aux, dw)?;
+    let [a, b, c, d, e, f, g, h, i, j] = dw.bytes else {
+      panic!();
+    };
+    let _collation = u16::from_le_bytes([*a, *b]);
+    let _max_size = u32::from_le_bytes([*c, *d, *e, *f]);
+    let type_id = *g;
+    let flags = u16::from_le_bytes([*h, *i]);
+    let _decimals = *j;
+    Ok(Self { alias: alias.try_into()?, flags, name: name.try_into()?, ty: Ty::try_from(type_id)? })
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/decode_wrapper_protocol.rs b/wtx/src/database/client/mysql/mysql_protocol/decode_wrapper_protocol.rs
new file mode 100644
index 00000000..ed68acf9
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/decode_wrapper_protocol.rs
@@ -0,0 +1,14 @@
+use crate::misc::Lease;
+
+#[derive(Debug)]
+pub(crate) struct DecodeWrapperProtocol<'inner, 'outer, O> {
+  pub(crate) bytes: &'outer mut &'inner [u8],
+  pub(crate) other: O,
+}
+
+impl<O> Lease<[u8]> for DecodeWrapperProtocol<'_, '_, O> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.bytes
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/encode_wrapper_protocol.rs b/wtx/src/database/client/mysql/mysql_protocol/encode_wrapper_protocol.rs
new file mode 100644
index 00000000..e0be59fe
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/encode_wrapper_protocol.rs
@@ -0,0 +1,20 @@
+use crate::misc::{Lease, Vector};
+
+pub(crate) struct EncodeWrapperProtocol<'any> {
+  pub(crate) capabilities: &'any mut u64,
+  pub(crate) enc_buffer: &'any mut Vector<u8>,
+}
+
+impl<'any> EncodeWrapperProtocol<'any> {
+  #[inline]
+  pub(crate) fn new(capabilities: &'any mut u64, enc_buffer: &'any mut Vector<u8>) -> Self {
+    Self { capabilities, enc_buffer }
+  }
+}
+
+impl Lease<[u8]> for EncodeWrapperProtocol<'_> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.enc_buffer
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/eof_res.rs b/wtx/src/database/client/mysql/mysql_protocol/eof_res.rs
new file mode 100644
index 00000000..f1610bca
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/eof_res.rs
@@ -0,0 +1,29 @@
+use crate::{
+  database::client::mysql::{
+    mysql_protocol::{MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol},
+    status::Status,
+  },
+  misc::Decode,
+};
+
+pub(crate) struct EofRes {
+  pub(crate) status: Status,
+}
+
+impl<DO, E> Decode<'_, MysqlProtocol<DO, E>> for EofRes
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(_: &mut (), dw: &mut DecodeWrapperProtocol<'_, '_, DO>) -> Result<Self, E> {
+    let [a, b, c, d, e] = dw.bytes else {
+      panic!();
+    };
+    if *a != 254 {
+      panic!();
+    }
+    let _warnings = u16::from_le_bytes([*b, *c]);
+    let status = Status::try_from(u16::from_le_bytes([*d, *e]))?;
+    Ok(Self { status })
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/handshake_req.rs b/wtx/src/database/client/mysql/mysql_protocol/handshake_req.rs
new file mode 100644
index 00000000..1761bece
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/handshake_req.rs
@@ -0,0 +1,73 @@
+use crate::{
+  database::client::mysql::{
+    auth_plugin::AuthPlugin,
+    capability::Capability,
+    collation::Collation,
+    misc::encoded_len,
+    mysql_protocol::{
+      MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol, initial_req::InitialReq,
+    },
+  },
+  misc::{ArrayVector, Encode},
+};
+
+pub(crate) struct HandshakeReq<'bytes> {
+  pub(crate) auth_plugin: Option<AuthPlugin>,
+  pub(crate) auth_response: Option<ArrayVector<u8, 32>>,
+  pub(crate) collation: Collation,
+  pub(crate) database: Option<&'bytes str>,
+  pub(crate) max_packet_size: u32,
+  pub(crate) username: &'bytes str,
+}
+
+impl<E> Encode<MysqlProtocol<(), E>> for HandshakeReq<'_>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, aux: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    if self.auth_plugin.is_none() {
+      *ew.capabilities &= !u64::from(Capability::PluginAuth);
+    }
+
+    let req = InitialReq { collation: self.collation, max_packet_size: self.max_packet_size };
+    req.encode(aux, ew)?;
+    let _ = ew.enc_buffer.extend_from_copyable_slices([self.username.as_bytes(), b"\0"])?;
+
+    let connect_n = u64::from(Capability::ConnectWithDb);
+    let plugin_auth = u64::from(Capability::PluginAuth);
+    let plugin_auth_lenenc_n = u64::from(Capability::PluginAuthLenencData);
+    let secure_n = u64::from(Capability::SecureConnection);
+
+    if *ew.capabilities & plugin_auth_lenenc_n == plugin_auth_lenenc_n {
+      let auth_response = self.auth_response.as_deref().unwrap_or_default();
+      let array = [&encoded_len(auth_response.len())?, auth_response];
+      let _ = ew.enc_buffer.extend_from_copyable_slices(array)?;
+    } else if *ew.capabilities & secure_n == secure_n {
+      let auth_response = self.auth_response.as_deref().unwrap_or_default();
+      let len = u8::try_from(auth_response.len()).map_err(crate::Error::from)?;
+      let _ = ew.enc_buffer.extend_from_copyable_slices([&[len][..], auth_response])?;
+    } else {
+      ew.enc_buffer.extend_from_copyable_slice("\0".as_bytes())?;
+    }
+
+    if *ew.capabilities & connect_n == connect_n {
+      if let Some(database) = self.database {
+        let _ = ew.enc_buffer.extend_from_copyable_slices([database.as_bytes(), b"\0"])?;
+      } else {
+        ew.enc_buffer.extend_from_copyable_slice("\0".as_bytes())?;
+      }
+    }
+
+    if *ew.capabilities & plugin_auth == plugin_auth {
+      if let Some(auth_plugin) = self.auth_plugin {
+        let array = [<&str>::from(auth_plugin).as_bytes(), b"\0"];
+        let _ = ew.enc_buffer.extend_from_copyable_slices(array)?;
+      } else {
+        ew.enc_buffer.extend_from_copyable_slice("\0".as_bytes())?;
+      }
+    }
+
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/handshake_res.rs b/wtx/src/database/client/mysql/mysql_protocol/handshake_res.rs
new file mode 100644
index 00000000..a3e5d273
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/handshake_res.rs
@@ -0,0 +1,83 @@
+use crate::{
+  database::client::mysql::{
+    auth_plugin::AuthPlugin,
+    capability::Capability,
+    mysql_protocol::{MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol},
+    status::Status,
+  },
+  misc::{Decode, FromRadix10, bytes_split_once1, bytes_split1},
+};
+
+#[derive(Debug)]
+pub(crate) struct HandshakeRes<'bytes> {
+  pub(crate) auth_plugin: Option<AuthPlugin>,
+  pub(crate) auth_plugin_data: ([u8; 8], &'bytes [u8]),
+  pub(crate) capabilities: u64,
+}
+
+impl<'de, DO, E> Decode<'de, MysqlProtocol<DO, E>> for HandshakeRes<'de>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(_: &mut (), dw: &mut DecodeWrapperProtocol<'de, '_, DO>) -> Result<Self, E> {
+    let [_protocol_version, rest0 @ ..] = dw.bytes else {
+      panic!();
+    };
+    let Some((server_version, rest1)) = bytes_split_once1(rest0, b'\0') else {
+      panic!();
+    };
+    let [a, b, c, d, e, f, g, h, i, j, k, l, _, rest2 @ ..] = rest1 else {
+      panic!();
+    };
+    let _connection_id = u32::from_le_bytes([*a, *b, *c, *d]);
+    let auth_plugin_data0 = [*e, *f, *g, *h, *i, *j, *k, *l];
+
+    let [a, b, _default_collation, d, e, f, g, h, _, _, _, _, _, _, i, j, k, l, rest3 @ ..] = rest2
+    else {
+      panic!();
+    };
+
+    let mut capabilities: u64 = u64::from(u16::from_le_bytes([*a, *b])) << 32;
+    let _status = Status::try_from(u16::from_le_bytes([*d, *e]))?;
+    capabilities |= u64::from(u16::from_le_bytes([*f, *g])) << 32;
+
+    let plugin_auth_n = u64::from(Capability::PluginAuth);
+    let auth_plugin_data_len = if capabilities & plugin_auth_n == plugin_auth_n { *h } else { 0 };
+
+    let mysql_n = u64::from(Capability::Mysql);
+    if capabilities & mysql_n == mysql_n {
+      capabilities |= u64::from(u32::from_le_bytes([*i, *j, *k, *l])) << 32;
+    }
+
+    let secure_connection_n = u64::from(Capability::SecureConnection);
+    let (auth_plugin_data1, rest4) = if capabilities & secure_connection_n == secure_connection_n {
+      let len = auth_plugin_data_len.saturating_sub(9).max(12);
+      let Some((auth_plugin_data1, rest4)) = rest3.split_at_checked(len.into()) else {
+        panic!();
+      };
+      (auth_plugin_data1, rest4)
+    } else {
+      (&[][..], rest3)
+    };
+
+    let auth_plugin = if capabilities & plugin_auth_n == plugin_auth_n {
+      Some(AuthPlugin::try_from(rest4)?)
+    } else {
+      None
+    };
+
+    let _server_version = server_version_array(server_version);
+
+    Ok(Self { auth_plugin, auth_plugin_data: (auth_plugin_data0, auth_plugin_data1), capabilities })
+  }
+}
+
+#[inline]
+fn server_version_array(bytes: &[u8]) -> [u16; 3] {
+  let mut iter = bytes_split1(bytes, b'.');
+  let major = iter.next().and_then(|el| FromRadix10::from_radix_10(el).ok()).unwrap_or_default();
+  let minor = iter.next().and_then(|el| FromRadix10::from_radix_10(el).ok()).unwrap_or_default();
+  let patch = iter.next().and_then(|el| FromRadix10::from_radix_10(el).ok()).unwrap_or_default();
+  [major, minor, patch]
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/initial_req.rs b/wtx/src/database/client/mysql/mysql_protocol/initial_req.rs
new file mode 100644
index 00000000..af3b9aaa
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/initial_req.rs
@@ -0,0 +1,38 @@
+use crate::{
+  database::client::mysql::{
+    capability::Capability,
+    collation::Collation,
+    mysql_protocol::{MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol},
+  },
+  misc::Encode,
+};
+
+#[derive(Debug)]
+pub(crate) struct InitialReq {
+  pub(crate) collation: Collation,
+  pub(crate) max_packet_size: u32,
+}
+
+impl<E> Encode<MysqlProtocol<(), E>> for InitialReq
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    let capability_lhs = (*ew.capabilities >> 32) as u32;
+    let capability_rhs = *ew.capabilities as u32;
+    let _ = ew.enc_buffer.extend_from_copyable_slices([
+      capability_rhs.to_le_bytes().as_slice(),
+      self.max_packet_size.to_le_bytes().as_slice(),
+      &[self.collation.into()],
+      &[0; 19],
+    ])?;
+    let mysql_n = u64::from(Capability::Mysql);
+    ew.enc_buffer.extend_from_copyable_slice(&if *ew.capabilities & mysql_n == mysql_n {
+      [0; 4]
+    } else {
+      capability_lhs.to_le_bytes()
+    })?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/lenenc.rs b/wtx/src/database/client/mysql/mysql_protocol/lenenc.rs
new file mode 100644
index 00000000..d508364f
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/lenenc.rs
@@ -0,0 +1,45 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol,
+  },
+  misc::Decode,
+};
+
+pub(crate) struct Lenenc(pub(crate) u64);
+
+impl<DO, E> Decode<'_, MysqlProtocol<DO, E>> for Lenenc
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(_: &mut (), dw: &mut DecodeWrapperProtocol<'_, '_, DO>) -> Result<Self, E> {
+    let [len, rest @ ..] = dw.bytes else {
+      panic!();
+    };
+    let value = match *len {
+      252 => {
+        let [a, b, local_rest @ ..] = rest else {
+          panic!();
+        };
+        *dw.bytes = local_rest;
+        u16::from_le_bytes([*a, *b]).into()
+      }
+      253 => {
+        let [a, b, c, local_rest @ ..] = rest else {
+          panic!();
+        };
+        *dw.bytes = local_rest;
+        u32::from_le_bytes([*a, *b, *c, 0]).into()
+      }
+      254 => {
+        let [a, b, c, d, e, f, g, h, local_rest @ ..] = rest else {
+          panic!();
+        };
+        *dw.bytes = local_rest;
+        u64::from_le_bytes([*a, *b, *c, *d, *e, *f, *g, *h])
+      }
+      n => u64::from(n),
+    };
+    Ok(Self(value))
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/lenenc_bytes.rs b/wtx/src/database/client/mysql/mysql_protocol/lenenc_bytes.rs
new file mode 100644
index 00000000..0c0a118c
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/lenenc_bytes.rs
@@ -0,0 +1,23 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol, lenenc::Lenenc,
+  },
+  misc::{Decode, Usize},
+};
+
+pub(crate) struct LenencBytes<'bytes>(pub(crate) &'bytes [u8]);
+
+impl<'de, DO, E> Decode<'de, MysqlProtocol<DO, E>> for LenencBytes<'de>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapperProtocol<'de, '_, DO>) -> Result<Self, E> {
+    let len = Lenenc::decode(aux, dw)?;
+    let Some((lhs, rhs)) = dw.bytes.split_at_checked(*Usize::try_from(len.0)?) else {
+      panic!();
+    };
+    *dw.bytes = rhs;
+    Ok(Self(lhs))
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/ok_res.rs b/wtx/src/database/client/mysql/mysql_protocol/ok_res.rs
new file mode 100644
index 00000000..86a7041b
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/ok_res.rs
@@ -0,0 +1,38 @@
+use crate::{
+  database::client::mysql::{
+    mysql_protocol::{
+      MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol, lenenc::Lenenc,
+    },
+    status::Status,
+  },
+  misc::Decode,
+};
+
+#[derive(Debug)]
+pub(crate) struct OkRes {
+  pub(crate) affected_rows: u64,
+  pub(crate) status: Status,
+}
+
+impl<DO, E> Decode<'_, MysqlProtocol<DO, E>> for OkRes
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(_: &mut (), dw: &mut DecodeWrapperProtocol<'_, '_, DO>) -> Result<Self, E> {
+    let [header, rest @ ..] = dw.bytes else { panic!() };
+    if *header != 0 && *header != 254 {
+      panic!();
+    }
+    *dw.bytes = rest;
+    let affected_rows = Lenenc::decode(&mut (), dw)?.0;
+    let _last_insert_id = Lenenc::decode(&mut (), dw)?.0;
+    let [a, b, c, d, rest @ ..] = dw.bytes else {
+      panic!();
+    };
+    let status = Status::try_from(u16::from_le_bytes([*a, *b]))?;
+    let _warnings = u16::from_le_bytes([*c, *d]);
+    *dw.bytes = rest;
+    Ok(Self { affected_rows, status })
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/packet_req.rs b/wtx/src/database/client/mysql/mysql_protocol/packet_req.rs
new file mode 100644
index 00000000..90f0a901
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/packet_req.rs
@@ -0,0 +1,45 @@
+use core::marker::PhantomData;
+
+use crate::{
+  database::client::mysql::{
+    mysql_executor::MAX_PAYLOAD,
+    mysql_protocol::{MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol},
+  },
+  misc::{Encode, Stream, Usize},
+};
+
+pub(crate) struct PacketReq<E, T>(pub(crate) T, pub(crate) PhantomData<E>);
+
+impl<E, T> PacketReq<E, T>
+where
+  E: From<crate::Error>,
+  T: Encode<MysqlProtocol<(), E>>,
+{
+  #[inline]
+  pub(crate) async fn encode<S>(
+    &self,
+    ew: &mut EncodeWrapperProtocol<'_>,
+    sequence_id: &mut u8,
+    stream: &mut S,
+  ) -> Result<(), E>
+  where
+    S: Stream,
+  {
+    self.0.encode(&mut (), ew)?;
+    let copy_into_header = |len: usize, local_sequence_id: &mut u8| {
+      let mut len_u32 = u32::try_from(len).unwrap_or_default().to_le_bytes();
+      len_u32[3] = *local_sequence_id;
+      *local_sequence_id = local_sequence_id.wrapping_add(1);
+      len_u32
+    };
+    let mut chunks = ew.enc_buffer.chunks_exact(*Usize::from(MAX_PAYLOAD));
+    for chunk in chunks.by_ref() {
+      let len = copy_into_header(chunk.len(), sequence_id);
+      stream.write_all_vectored(&[len.as_slice(), chunk]).await?;
+    }
+    let remainder = chunks.remainder();
+    let len = copy_into_header(remainder.len(), sequence_id);
+    stream.write_all_vectored(&[len.as_slice(), remainder]).await?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/prepare_req.rs b/wtx/src/database/client/mysql/mysql_protocol/prepare_req.rs
new file mode 100644
index 00000000..791e2e19
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/prepare_req.rs
@@ -0,0 +1,21 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol,
+  },
+  misc::Encode,
+};
+
+pub(crate) struct PrepareReq<'any> {
+  pub(crate) query: &'any [u8],
+}
+
+impl<E> Encode<MysqlProtocol<(), E>> for PrepareReq<'_>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    let _ = ew.enc_buffer.extend_from_copyable_slices([&[22], self.query])?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/prepare_res.rs b/wtx/src/database/client/mysql/mysql_protocol/prepare_res.rs
new file mode 100644
index 00000000..b299bbaf
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/prepare_res.rs
@@ -0,0 +1,33 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol,
+  },
+  misc::Decode,
+};
+
+#[derive(Debug)]
+pub(crate) struct PrepareRes {
+  pub(crate) columns: u16,
+  pub(crate) params: u16,
+  pub(crate) statement_id: u32,
+}
+
+impl<'de, DO, E> Decode<'de, MysqlProtocol<DO, E>> for PrepareRes
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(_: &mut (), dw: &mut DecodeWrapperProtocol<'de, '_, DO>) -> Result<Self, E> {
+    let [a, b, c, d, e, f, g, h, i, _, k, l] = dw.bytes else {
+      panic!();
+    };
+    if *a != 0x00 {
+      panic!();
+    }
+    let statement_id = u32::from_le_bytes([*b, *c, *d, *e]);
+    let columns = u16::from_le_bytes([*f, *g]);
+    let params = u16::from_le_bytes([*h, *i]);
+    let _warnings = u16::from_le_bytes([*k, *l]);
+    Ok(Self { columns, params, statement_id })
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/query_req.rs b/wtx/src/database/client/mysql/mysql_protocol/query_req.rs
new file mode 100644
index 00000000..264277ab
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/query_req.rs
@@ -0,0 +1,21 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol,
+  },
+  misc::Encode,
+};
+
+pub(crate) struct QueryReq<'any> {
+  pub(crate) query: &'any [u8],
+}
+
+impl<E> Encode<MysqlProtocol<(), E>> for QueryReq<'_>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    let _ = ew.enc_buffer.extend_from_copyable_slices([&[3], self.query])?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/stmt_close_req.rs b/wtx/src/database/client/mysql/mysql_protocol/stmt_close_req.rs
new file mode 100644
index 00000000..961ecae9
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/stmt_close_req.rs
@@ -0,0 +1,23 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol,
+  },
+  misc::Encode,
+};
+
+#[derive(Debug)]
+pub(crate) struct StmtCloseReq {
+  pub(crate) statement: u32,
+}
+
+impl<E> Encode<MysqlProtocol<(), E>> for StmtCloseReq
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    let array = [&[25][..], &self.statement.to_le_bytes()];
+    let _ = ew.enc_buffer.extend_from_copyable_slices(array)?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/stmt_execute_req.rs b/wtx/src/database/client/mysql/mysql_protocol/stmt_execute_req.rs
new file mode 100644
index 00000000..94e9e5ad
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/stmt_execute_req.rs
@@ -0,0 +1,61 @@
+use crate::{
+  database::{
+    RecordValues,
+    client::mysql::{
+      EncodeWrapper, Mysql, MysqlStatement,
+      flags::Flags,
+      mysql_protocol::{MysqlProtocol, encode_wrapper_protocol::EncodeWrapperProtocol},
+    },
+  },
+  misc::Encode,
+};
+
+#[derive(Debug)]
+pub(crate) struct StmtExecuteReq<'any, 'stmts, RV> {
+  pub(crate) rv: RV,
+  pub(crate) stmt: &'any MysqlStatement<'stmts>,
+}
+
+impl<'any, 'stmts, DO, E, RV> Encode<MysqlProtocol<DO, E>> for StmtExecuteReq<'any, 'stmts, RV>
+where
+  E: From<crate::Error>,
+  RV: RecordValues<Mysql<E>>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapperProtocol<'_>) -> Result<(), E> {
+    let _ = ew.enc_buffer.extend_from_copyable_slices([
+      &[23][..],
+      &self.stmt._aux().to_le_bytes(),
+      &[0],
+      &1_u32.to_le_bytes(),
+    ])?;
+    if self.stmt._tys_len() > 0 {
+      let prev_len = ew.enc_buffer.len();
+      let mut idx: usize = 0;
+      self.rv.is_null(|is_null| {
+        let bit_offset = idx % 8;
+        let byte_index = prev_len.wrapping_add(idx / 8);
+        if bit_offset == 0 {
+          ew.enc_buffer.push(0)?;
+        }
+        idx = idx.wrapping_add(1);
+        if let Some(elem) = ew.enc_buffer.get_mut(byte_index) {
+          *elem |= u8::from(is_null) << bit_offset;
+        }
+        Ok(())
+      })?;
+      for ty in self.stmt._tys() {
+        let unsigned = u16::from(Flags::Unsigned);
+        let value = if ty.flags & unsigned == unsigned { 128 } else { 0 };
+        ew.enc_buffer.extend_from_copyable_slice(&[u8::from(ty.ty), value])?;
+      }
+      let _ = self.rv.encode_values(
+        &mut (),
+        &mut EncodeWrapper::new(ew.enc_buffer),
+        |_, _| 0,
+        |_, _, _, _| 0,
+      )?;
+    }
+    Ok(())
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_protocol/text_row_res.rs b/wtx/src/database/client/mysql/mysql_protocol/text_row_res.rs
new file mode 100644
index 00000000..e6427811
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_protocol/text_row_res.rs
@@ -0,0 +1,45 @@
+use crate::{
+  database::client::mysql::mysql_protocol::{
+    MysqlProtocol, decode_wrapper_protocol::DecodeWrapperProtocol, lenenc::Lenenc,
+  },
+  misc::{Decode, Usize, Vector},
+};
+use core::ops::Range;
+
+type Params<'any> = (usize, &'any mut Vector<(bool, Range<usize>)>);
+
+#[derive(Debug)]
+pub(crate) struct TextRowRes;
+
+impl<'de, E> Decode<'de, MysqlProtocol<Params<'_>, E>> for TextRowRes
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapperProtocol<'de, '_, Params<'_>>) -> Result<Self, E> {
+    dw.other.1.reserve(dw.other.0)?;
+    let mut idx = 0;
+    for _ in 0..dw.other.0 {
+      let [first, rest @ ..] = dw.bytes else {
+        panic!();
+      };
+      if *first == 251 {
+        dw.other.1.push((true, idx..idx))?;
+        *dw.bytes = rest;
+        idx = idx.wrapping_add(1);
+      } else {
+        let len = {
+          let begin = dw.bytes.len();
+          let len = Usize::try_from(Lenenc::decode(aux, dw)?.0)?.into_usize();
+          idx = idx.wrapping_add(dw.bytes.len().wrapping_sub(begin));
+          len
+        };
+        let begin = idx;
+        idx = idx.wrapping_add(len);
+        *dw.bytes = dw.bytes.get(len..).unwrap_or_default();
+        dw.other.1.push((false, begin..idx))?;
+      }
+    }
+    Ok(Self)
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_record.rs b/wtx/src/database/client/mysql/mysql_record.rs
new file mode 100644
index 00000000..73242548
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_record.rs
@@ -0,0 +1,89 @@
+use crate::{
+  database::{
+    Record, ValueIdent,
+    client::mysql::{DecodeWrapper, Mysql, MysqlStatement},
+  },
+  misc::{_unlikely_elem, DEController},
+};
+use core::{marker::PhantomData, ops::Range};
+
+/// Record
+#[derive(Debug)]
+pub struct MysqlRecord<'any, E> {
+  pub(crate) bytes: &'any [u8],
+  pub(crate) phantom: PhantomData<fn() -> E>,
+  pub(crate) stmt: MysqlStatement<'any>,
+  pub(crate) values_bytes_offsets: &'any [(bool, Range<usize>)],
+}
+
+impl<'any, E> MysqlRecord<'any, E> {
+  #[inline]
+  pub(crate) fn new(
+    bytes: &'any [u8],
+    stmt: MysqlStatement<'any>,
+    values_bytes_offsets: &'any [(bool, Range<usize>)],
+  ) -> Self {
+    Self { bytes, phantom: PhantomData, stmt, values_bytes_offsets }
+  }
+}
+
+impl<'exec, E> Record<'exec> for MysqlRecord<'exec, E>
+where
+  E: From<crate::Error>,
+{
+  type Database = Mysql<E>;
+
+  #[inline]
+  fn len(&self) -> usize {
+    0
+  }
+
+  #[inline]
+  fn value<CI>(&self, ci: CI) -> Option<<Self::Database as DEController>::DecodeWrapper<'exec, '_>>
+  where
+    CI: ValueIdent<Self>,
+  {
+    let idx = ci.idx(self)?;
+    let (is_null, range) = match self.values_bytes_offsets.get(idx) {
+      None => return _unlikely_elem(None),
+      Some(elem) => elem,
+    };
+    if *is_null {
+      None
+    } else {
+      let column = match self.stmt._column(idx) {
+        None => return _unlikely_elem(None),
+        Some(elem) => elem,
+      };
+      let bytes = match self.bytes.get(range.clone()) {
+        None => return _unlikely_elem(None),
+        Some(elem) => elem,
+      };
+      Some(DecodeWrapper::new(bytes, column.ty_params.ty))
+    }
+  }
+}
+
+impl<'exec, E> ValueIdent<MysqlRecord<'exec, E>> for str {
+  #[inline]
+  fn idx(&self, input: &MysqlRecord<'exec, E>) -> Option<usize> {
+    input.stmt._columns().position(|column| column.name.as_str() == self)
+  }
+}
+
+mod array {
+  use crate::{
+    database::{FromRecord, Record, client::mysql::Mysql},
+    misc::{ArrayString, from_utf8_basic, into_rslt},
+  };
+
+  impl<E, const N: usize> FromRecord<Mysql<E>> for ArrayString<N>
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn from_record(record: &crate::database::client::mysql::MysqlRecord<'_, E>) -> Result<Self, E> {
+      Ok(from_utf8_basic(into_rslt(record.value(0))?.bytes()).map_err(From::from)?.try_into()?)
+    }
+  }
+}
diff --git a/wtx/src/database/client/mysql/mysql_records.rs b/wtx/src/database/client/mysql/mysql_records.rs
new file mode 100644
index 00000000..33585d56
--- /dev/null
+++ b/wtx/src/database/client/mysql/mysql_records.rs
@@ -0,0 +1,85 @@
+use crate::database::{
+  Records,
+  client::mysql::{Mysql, MysqlRecord, MysqlStatement},
+};
+use core::{marker::PhantomData, ops::Range};
+
+/// Records
+#[derive(Debug)]
+pub struct MysqlRecords<'exec, E> {
+  pub(crate) bytes: &'exec [u8],
+  pub(crate) phantom: PhantomData<fn() -> E>,
+  /// Each element represents a record and an offset of `values_bytes_offsets`.
+  pub(crate) records_values_offsets: &'exec [usize],
+  pub(crate) stmt: MysqlStatement<'exec>,
+  /// Each element represents a value and an offset of `bytes`.
+  pub(crate) values_bytes_offsets: &'exec [(bool, Range<usize>)],
+}
+
+impl<'exec, E> MysqlRecords<'exec, E> {
+  #[inline]
+  pub(crate) fn new(
+    bytes: &'exec [u8],
+    records_values_offsets: &'exec [usize],
+    stmt: MysqlStatement<'exec>,
+    values_bytes_offsets: &'exec [(bool, Range<usize>)],
+  ) -> Self {
+    Self { bytes, phantom: PhantomData, records_values_offsets, stmt, values_bytes_offsets }
+  }
+}
+
+impl<'exec, E> Records<'exec> for MysqlRecords<'exec, E>
+where
+  E: From<crate::Error>,
+{
+  type Database = Mysql<E>;
+
+  #[inline]
+  fn get(&self, record_idx: usize) -> Option<MysqlRecord<'exec, E>> {
+    let slice = self.records_values_offsets.get(..record_idx.wrapping_add(1))?;
+    let (record_bytes_range, record_values_bytes_offsets) = match slice {
+      [] => return None,
+      &[to] => {
+        let record_values_bytes_offsets = self.values_bytes_offsets.get(..to)?;
+        (0..record_values_bytes_offsets.last()?.1.end, record_values_bytes_offsets)
+      }
+      &[.., from, to] => {
+        let record_values_bytes_offsets = self.values_bytes_offsets.get(from..to)?;
+        let [start, end] = match record_values_bytes_offsets {
+          [(_, first)] => [first.start, first.end],
+          [(_, first), .., last] => [first.start, last.1.end],
+          _ => return None,
+        };
+        (start..end, record_values_bytes_offsets)
+      }
+    };
+    Some(MysqlRecord::new(
+      self.bytes.get(record_bytes_range)?,
+      self.stmt.clone(),
+      record_values_bytes_offsets,
+    ))
+  }
+
+  #[inline]
+  fn iter(&self) -> impl Iterator<Item = MysqlRecord<'exec, E>> {
+    (0..self.len()).filter_map(|idx| self.get(idx))
+  }
+
+  #[inline]
+  fn len(&self) -> usize {
+    self.records_values_offsets.len()
+  }
+}
+
+impl<E> Default for MysqlRecords<'_, E> {
+  #[inline]
+  fn default() -> Self {
+    Self {
+      bytes: &[],
+      phantom: PhantomData,
+      records_values_offsets: &[],
+      stmt: MysqlStatement::default(),
+      values_bytes_offsets: &[],
+    }
+  }
+}
diff --git a/wtx/src/database/client/mysql/status.rs b/wtx/src/database/client/mysql/status.rs
new file mode 100644
index 00000000..3d79ed42
--- /dev/null
+++ b/wtx/src/database/client/mysql/status.rs
@@ -0,0 +1,38 @@
+create_enum! {
+  /// Status
+  #[derive(Clone, Copy, Debug)]
+  pub(crate) enum Status<u16> {
+    // A transaction is currently active
+    ServerStatusInTrans = (1),
+    // Autocommit mode is set
+    ServerStatusAutocommit = (2),
+    // Multi query - next query exists.
+    ServerMoreResultsExists = (8),
+    /// Indicates that an index was used but it was not optimal or effective for the
+    /// query, leading to suboptimal performance.
+    ServerQueryNoGoodIndexUsed = (16),
+    /// Indicates that no index was used and a full table scan was performed.
+    ServerQueryNoIndexUsed = (32),
+    // when using COM_STMT_FETCH, indicate that current cursor still has result
+    ServerStatusCursorExists = (64),
+    // When using COM_STMT_FETCH, indicate that current cursor has finished to send results
+    ServerStatusLastRowSent = (128),
+    // Database has been dropped
+    ServerStatusDbDropped = (256),
+    // Current escape mode is "no backslash escape"
+    ServerStatusNoBackslashEscapes = (512),
+    // A DDL change did have an impact on an existing PREPARE (an automatic
+    // re-prepare has been executed)
+    ServerStatusMetadataChanged = (1024),
+    // Last statement took more than the time value specified
+    // in server variable long_query_time.
+    ServerQueryWasSlow = (2048),
+    // This result-set contain stored procedure output parameter.
+    ServerPsOutParams = (4096),
+    // Current transaction is a read-only transaction.
+    ServerStatusInTransReadonly = (8192),
+    // This status flag, when on, implies that one of the state information has changed
+    // on the server because of the execution of the last statement.
+    ServerSessionStateChanged = (16384),
+  }
+}
diff --git a/wtx/src/database/client/mysql/ty.rs b/wtx/src/database/client/mysql/ty.rs
new file mode 100644
index 00000000..e51e7fd0
--- /dev/null
+++ b/wtx/src/database/client/mysql/ty.rs
@@ -0,0 +1,60 @@
+create_enum! {
+  /// MySQL type
+  #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+  pub enum Ty<u8> {
+    /// Decimal
+    Decimal = (0),
+    /// Tiny
+    Tiny = (1),
+    /// Short
+    Short = (2),
+    /// Long
+    Long = (3),
+    /// Float
+    Float = (4),
+    /// Double
+    Double = (5),
+    /// Null
+    Null = (6),
+    /// Timestamp
+    Timestamp = (7),
+    /// LongLong
+    LongLong = (8),
+    /// Int24
+    Int24 = (9),
+    /// Date
+    Date = (10),
+    /// Time
+    Time = (11),
+    /// Datetime
+    Datetime = (12),
+    /// Year
+    Year = (13),
+    /// VarChar
+    VarChar = (15),
+    /// Bit
+    Bit = (16),
+    /// Json
+    Json = (245),
+    /// NewDecimal
+    NewDecimal = (246),
+    /// Enum
+    Enum = (247),
+    /// Set
+    Set = (248),
+    /// TinyBlob
+    TinyBlob = (249),
+    /// MediumBlob
+    MediumBlob = (250),
+    /// LongBlog
+    LongBlob = (251),
+    /// Blob
+    Blob = (252),
+    /// VarString
+    VarString = (253),
+    /// String
+    String = (254),
+    /// Geometry
+    Geometry = (255),
+  }
+}
diff --git a/wtx/src/database/client/mysql/ty_params.rs b/wtx/src/database/client/mysql/ty_params.rs
new file mode 100644
index 00000000..26d95697
--- /dev/null
+++ b/wtx/src/database/client/mysql/ty_params.rs
@@ -0,0 +1,14 @@
+use crate::database::client::mysql::{Ty, mysql_protocol::column_res::ColumnRes};
+
+#[derive(Clone, Debug)]
+pub(crate) struct TyParams {
+  pub(crate) flags: u16,
+  pub(crate) ty: Ty,
+}
+
+impl TyParams {
+  #[inline]
+  pub(crate) fn from_column_res(column_res: &ColumnRes) -> Self {
+    Self { flags: column_res.flags, ty: column_res.ty }
+  }
+}
diff --git a/wtx/src/database/client/mysql/tys.rs b/wtx/src/database/client/mysql/tys.rs
new file mode 100644
index 00000000..dc4a946a
--- /dev/null
+++ b/wtx/src/database/client/mysql/tys.rs
@@ -0,0 +1,501 @@
+macro_rules! kani {
+  ($name:ident, $ty:ty) => {
+    #[cfg(kani)]
+    #[kani::proof]
+    fn $name(instance: $ty) {
+      let mut vec = &mut crate::misc::FilledBuffer::_new();
+      {
+        let mut sw = crate::misc::FilledBufferWriter::new(0, &mut vec);
+        let mut ew = EncodeValue::new(&mut sw);
+        Encode::<Mysql<crate::Error>>::encode(&instance, &mut ew).unwrap();
+        let decoded: $ty = Decode::<Mysql<crate::Error>>::decode(&DecodeValue::new(
+          ew.sw()._curr_bytes(),
+          crate::database::client::mysql::Ty::Null,
+        ))
+        .unwrap();
+        assert_eq!(instance, decoded);
+      }
+      vec._clear();
+    }
+  };
+}
+
+macro_rules! test {
+  ($name:ident, $ty:ty, $instance:expr) => {
+    #[cfg(test)]
+    #[test]
+    fn $name() {
+      let mut vec = crate::misc::Vector::new();
+      let mut ew = EncodeWrapper::new(&mut vec);
+      let instance: $ty = $instance;
+      Encode::<Mysql<crate::Error>>::encode(&instance, &mut (), &mut ew).unwrap();
+      let decoded: $ty = Decode::<Mysql<crate::Error>>::decode(
+        &mut (),
+        &mut DecodeWrapper::new(ew.sw(), crate::database::client::mysql::Ty::Tiny),
+      )
+      .unwrap();
+      assert_eq!(instance, decoded);
+    }
+  };
+}
+
+#[cfg(feature = "chrono")]
+mod chrono {
+  use crate::{
+    database::{
+      DatabaseError, Typed,
+      client::mysql::{DecodeWrapper, EncodeWrapper, Mysql, Ty},
+    },
+    misc::{Decode, Encode, Usize},
+  };
+  use chrono::{DateTime, Datelike, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Timelike, Utc};
+  use core::any::type_name;
+
+  impl<E> Decode<'_, Mysql<E>> for DateTime<Utc>
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(aux: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      let naive = <NaiveDateTime as Decode<Mysql<E>>>::decode(aux, dv)?;
+      Ok(Utc.from_utc_datetime(&naive))
+    }
+  }
+  impl<E> Encode<Mysql<E>> for DateTime<Utc>
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, aux: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      Encode::<Mysql<E>>::encode(&self.naive_utc(), aux, ew)
+    }
+  }
+  impl<E> Typed<Mysql<E>> for DateTime<Utc>
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::Timestamp;
+  }
+
+  impl<E> Decode<'_, Mysql<E>> for NaiveDate
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      date_decode(dv).map(|el| el.1).map_err(E::from)
+    }
+  }
+  impl<E> Encode<Mysql<E>> for NaiveDate
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      date_encode(self, ew, 4).map_err(E::from)
+    }
+  }
+  impl<E> Typed<Mysql<E>> for NaiveDate
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::Date;
+  }
+
+  impl<E> Decode<'_, Mysql<E>> for NaiveDateTime
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      let (len, date) = date_decode(dv).map_err(E::from)?;
+      Ok(if len > 4 {
+        let bytes = if let [_, _, _, _, _, bytes @ ..] = dv.bytes() { bytes } else { &[] };
+        date.and_time(time_decode(len - 4, bytes)?)
+      } else {
+        date.and_time(NaiveTime::default())
+      })
+    }
+  }
+  impl<E> Encode<Mysql<E>> for NaiveDateTime
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      let len = date_len(self);
+      date_encode(&self.date(), ew, len)?;
+      if len > 4 {
+        time_encode(&self.time(), len > 7, ew)?;
+      }
+      Ok(())
+    }
+  }
+  impl<E> Typed<Mysql<E>> for NaiveDateTime
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::Datetime;
+  }
+
+  #[inline]
+  fn date_decode(dv: &mut DecodeWrapper<'_>) -> crate::Result<(u8, NaiveDate)> {
+    let [len, year_a, year_b, month, day] = dv.bytes() else {
+      return Err(
+        DatabaseError::UnexpectedBufferSize {
+          expected: 5,
+          received: Usize::from(dv.bytes().len()).into_u32().unwrap_or(u32::MAX),
+        }
+        .into(),
+      );
+    };
+    let year = i16::from_be_bytes([*year_a, *year_b]);
+    let date = NaiveDate::from_ymd_opt(year.into(), (*month).into(), (*day).into())
+      .ok_or(DatabaseError::UnexpectedValueFromBytes { expected: type_name::<NaiveDate>() })?;
+    Ok((*len, date))
+  }
+
+  #[inline]
+  fn date_encode(date: &NaiveDate, ew: &mut EncodeWrapper<'_>, len: u8) -> crate::Result<()> {
+    let year = u16::try_from(date.year()).map_err(|_err| {
+      DatabaseError::UnexpectedValueFromBytes { expected: type_name::<NaiveDate>() }
+    })?;
+    let [year_a, year_b] = year.to_le_bytes();
+    ew.sw().extend_from_copyable_slice(&[
+      len,
+      year_a,
+      year_b,
+      date.month().try_into().unwrap_or_default(),
+      date.day().try_into().unwrap_or_default(),
+    ])?;
+    Ok(())
+  }
+
+  #[inline]
+  fn date_len(time: &NaiveDateTime) -> u8 {
+    // to save space the packet can be compressed:
+    match (
+      time.hour(),
+      time.minute(),
+      time.second(),
+      #[allow(deprecated)]
+      time.timestamp_subsec_nanos(),
+    ) {
+      (0, 0, 0, 0) => 4,
+      (_, _, _, 0) => 7,
+      (_, _, _, _) => 11,
+    }
+  }
+
+  #[inline]
+  fn time_decode(len: u8, bytes: &[u8]) -> crate::Result<NaiveTime> {
+    let (hours, minutes, seconds, micros) = if len > 3 {
+      let [hours, minutes, seconds, a, b, c, d] = bytes else {
+        return Err(
+          DatabaseError::UnexpectedBufferSize {
+            expected: 7,
+            received: Usize::from(bytes.len()).into_u32().unwrap_or(u32::MAX),
+          }
+          .into(),
+        );
+      };
+      (*hours, *minutes, *seconds, u32::from_be_bytes([*a, *b, *c, *d]))
+    } else {
+      let [hours, minutes, seconds] = bytes else {
+        return Err(
+          DatabaseError::UnexpectedBufferSize {
+            expected: 3,
+            received: Usize::from(bytes.len()).into_u32().unwrap_or(u32::MAX),
+          }
+          .into(),
+        );
+      };
+      (*hours, *minutes, *seconds, 0)
+    };
+    NaiveTime::from_hms_micro_opt(hours.into(), minutes.into(), seconds.into(), micros).ok_or_else(
+      || DatabaseError::UnexpectedValueFromBytes { expected: type_name::<NaiveTime>() }.into(),
+    )
+  }
+
+  fn time_encode(
+    time: &NaiveTime,
+    include_micros: bool,
+    ew: &mut EncodeWrapper<'_>,
+  ) -> crate::Result<()> {
+    let hour = time.hour().try_into().unwrap_or_default();
+    let minute = time.minute().try_into().unwrap_or_default();
+    let second = time.second().try_into().unwrap_or_default();
+    if include_micros {
+      let [a, b, c, d] = (time.nanosecond() / 1000).to_le_bytes();
+      ew.sw().extend_from_copyable_slice(&[hour, minute, second, a, b, c, d])?;
+    } else {
+      ew.sw().extend_from_copyable_slice(&[hour, minute, second])?;
+    }
+    Ok(())
+  }
+
+  test!(datetime_utc, DateTime<Utc>, Utc::now());
+}
+
+mod collections {
+  use crate::{
+    database::{
+      Typed,
+      client::mysql::{DecodeWrapper, EncodeWrapper, Mysql, Ty},
+    },
+    misc::{ArrayString, Decode, Encode, from_utf8_basic},
+  };
+  use alloc::string::String;
+
+  // &[u8]
+
+  impl<'exec, E> Decode<'exec, Mysql<E>> for &'exec [u8]
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(_: &mut (), dv: &mut DecodeWrapper<'exec>) -> Result<Self, E> {
+      Ok(dv.bytes())
+    }
+  }
+  impl<E> Encode<Mysql<E>> for &[u8]
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      ew.sw().extend_from_copyable_slice(self)?;
+      Ok(())
+    }
+  }
+  impl<E> Typed<Mysql<E>> for &[u8]
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::Blob;
+  }
+  test!(bytes, &[u8], &[1, 2, 3, 4]);
+
+  // String
+
+  impl<E, const N: usize> Decode<'_, Mysql<E>> for ArrayString<N>
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      Ok(from_utf8_basic(dv.bytes()).map_err(Into::into)?.try_into()?)
+    }
+  }
+  impl<E, const N: usize> Encode<Mysql<E>> for ArrayString<N>
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      ew.sw().extend_from_copyable_slice(self.as_str().as_bytes())?;
+      Ok(())
+    }
+  }
+  impl<E, const N: usize> Typed<Mysql<E>> for ArrayString<N>
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::VarString;
+  }
+  test!(array_string, ArrayString<4>, ArrayString::try_from("123").unwrap());
+
+  impl<'exec, E> Decode<'exec, Mysql<E>> for &'exec str
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(_: &mut (), dv: &mut DecodeWrapper<'exec>) -> Result<Self, E> {
+      Ok(from_utf8_basic(dv.bytes()).map_err(crate::Error::from)?)
+    }
+  }
+  impl<E> Encode<Mysql<E>> for &str
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      ew.sw().extend_from_copyable_slice(self.as_bytes())?;
+      Ok(())
+    }
+  }
+  impl<E> Typed<Mysql<E>> for &str
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::VarString;
+  }
+  test!(str, &str, "1234");
+
+  // String
+
+  impl<E> Decode<'_, Mysql<E>> for String
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      match from_utf8_basic(dv.bytes()).map_err(crate::Error::from) {
+        Ok(elem) => Ok(elem.into()),
+        Err(err) => Err(err.into()),
+      }
+    }
+  }
+  impl<E> Encode<Mysql<E>> for String
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      ew.sw().extend_from_copyable_slice(self.as_bytes())?;
+      Ok(())
+    }
+  }
+  impl<E> Typed<Mysql<E>> for String
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::VarString;
+  }
+  kani!(string, String);
+}
+
+mod primitives {
+  use crate::{
+    database::{
+      DatabaseError, Typed,
+      client::mysql::{DecodeWrapper, EncodeWrapper, Mysql, Ty},
+    },
+    misc::{Decode, Encode, Usize},
+  };
+
+  // bool
+
+  impl<E> Decode<'_, Mysql<E>> for bool
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      let &[byte] = dv.bytes() else {
+        return Err(E::from(
+          DatabaseError::UnexpectedBufferSize {
+            expected: 1,
+            received: Usize::from(dv.bytes().len()).into_u32().unwrap_or(u32::MAX),
+          }
+          .into(),
+        ));
+      };
+      Ok(byte != 0)
+    }
+  }
+  impl<E> Encode<Mysql<E>> for bool
+  where
+    E: From<crate::Error>,
+  {
+    #[inline]
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+      ew.sw().push((*self).into())?;
+      Ok(())
+    }
+  }
+  impl<E> Typed<Mysql<E>> for bool
+  where
+    E: From<crate::Error>,
+  {
+    const TY: Ty = Ty::Tiny;
+  }
+
+  macro_rules! impl_integer_from_array {
+      ($instance:expr, [$($elem:ident),+], ($signed:ident, $signed_pg_ty:expr), ($unsigned:ident, $unsigned_pg_ty:expr)) => {
+        impl_primitive_from_array!($instance, [$($elem),+], $signed, $signed_pg_ty);
+
+        impl<E> Decode<'_, Mysql<E>> for $unsigned
+        where
+          E: From<crate::Error>,
+        {
+          #[inline]
+          fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+            if let &[$($elem,)+] = dv.bytes() {
+                return Ok(<Self>::from_be_bytes([$($elem),+]));
+              }
+              Err(E::from(DatabaseError::UnexpectedBufferSize {
+                expected: Usize::from(size_of::<Self>()).into_u32().unwrap_or(u32::MAX),
+                received: Usize::from(dv.bytes().len()).into_u32().unwrap_or(u32::MAX)
+              }.into()))
+          }
+        }
+        impl<E> Encode<Mysql<E>> for $unsigned
+        where
+          E: From<crate::Error>,
+        {
+          #[inline]
+          fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+            ew.sw().extend_from_copyable_slice(&self.to_be_bytes()).map_err(Into::into)?;
+            Ok(())
+          }
+        }
+        impl<E> Typed<Mysql<E>> for $unsigned
+        where
+          E: From<crate::Error>
+        {
+          const TY: Ty = $unsigned_pg_ty;
+        }
+
+        test!($unsigned, $unsigned, $instance);
+      };
+    }
+
+  macro_rules! impl_primitive_from_array {
+      ($instance:expr, [$($elem:ident),+], $ty:ident, $pg_ty:expr) => {
+        impl<E> Decode<'_, Mysql<E>> for $ty
+        where
+          E: From<crate::Error>,
+        {
+          #[inline]
+          fn decode(_: &mut (), dv: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+            if let &[$($elem,)+] = dv.bytes() {
+              return Ok(<Self>::from_be_bytes([$($elem),+]));
+            }
+            Err(E::from(DatabaseError::UnexpectedBufferSize {
+              expected: Usize::from(size_of::<Self>()).into_u32().unwrap_or(u32::MAX),
+              received: Usize::from(dv.bytes().len()).into_u32().unwrap_or(u32::MAX)
+            }.into()))
+          }
+        }
+
+        impl<E> Encode<Mysql<E>> for $ty
+        where
+          E: From<crate::Error>,
+        {
+          #[inline]
+          fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_>) -> Result<(), E> {
+            ew.sw().extend_from_copyable_slice(&self.to_be_bytes()).map_err(Into::into)?;
+            Ok(())
+          }
+        }
+
+        impl<E> Typed<Mysql<E>> for $ty
+        where
+          E: From<crate::Error>
+        {
+          const TY: Ty = $pg_ty;
+        }
+
+        test!($ty, $ty, $instance);
+      }
+    }
+
+  impl_integer_from_array!(37, [a], (i8, Ty::Tiny), (u8, Ty::Tiny));
+  impl_integer_from_array!(37, [a, b], (i16, Ty::Short), (u16, Ty::Short));
+  impl_integer_from_array!(37, [a, b, c, d], (i32, Ty::Long), (u32, Ty::Long));
+  impl_integer_from_array!(37, [a, b, c, d, e, f, g, h], (i64, Ty::LongLong), (u64, Ty::LongLong));
+
+  impl_primitive_from_array!(37.0, [a, b, c, d], f32, Ty::Float);
+  impl_primitive_from_array!(37.0, [a, b, c, d, e, f, g, h], f64, Ty::Double);
+}
diff --git a/wtx/src/database/client/postgres.rs b/wtx/src/database/client/postgres.rs
index 459dfb42..a22f8ec9 100644
--- a/wtx/src/database/client/postgres.rs
+++ b/wtx/src/database/client/postgres.rs
@@ -2,46 +2,52 @@
 //! extensibility and SQL compliance.
 
 mod authentication;
+mod column;
 mod config;
 mod db_error;
-mod decode_value;
-mod encode_value;
-mod executor;
+mod decode_wrapper;
+mod encode_wrapper;
 mod executor_buffer;
 #[cfg(all(feature = "_async-tests", feature = "_integration-tests", test))]
 mod integration_tests;
 mod message;
 mod msg_field;
 mod postgres_error;
+mod postgres_executor;
+mod postgres_record;
+mod postgres_records;
 mod protocol;
-mod record;
-mod records;
 mod sql_state;
-mod statements;
 mod struct_decoder;
 mod struct_encoder;
 mod ty;
 mod tys;
 
-use crate::database::{Database, DatabaseTy};
+use crate::{
+  database::{
+    Database, DatabaseTy,
+    client::rdbms::{statement::Statement, statements::Statements},
+  },
+  misc::DEController,
+};
 pub use config::Config;
 use core::marker::PhantomData;
 pub use db_error::{DbError, ErrorPosition, Severity};
-pub use decode_value::DecodeValue;
-pub use encode_value::EncodeValue;
-pub use executor::Executor;
+pub use decode_wrapper::DecodeWrapper;
+pub use encode_wrapper::EncodeWrapper;
 pub use executor_buffer::ExecutorBuffer;
 pub use postgres_error::PostgresError;
-pub use record::Record;
-pub use records::Records;
+pub use postgres_executor::PostgresExecutor;
+pub use postgres_record::PostgresRecord;
+pub use postgres_records::PostgresRecords;
 pub use sql_state::SqlState;
-pub use statements::Statements;
 pub use struct_decoder::StructDecoder;
 pub use struct_encoder::StructEncoder;
 pub use ty::Ty;
 
 pub(crate) type Oid = u32;
-
+pub(crate) type PostgresStatements = Statements<(), column::Column, Ty>;
+pub(crate) type PostgresStatement<'stmts> = Statement<'stmts, (), column::Column, Ty>;
 /// Postgres
 #[derive(Debug)]
 pub struct Postgres<E>(PhantomData<fn() -> E>);
@@ -50,19 +56,27 @@ impl<E> Database for Postgres<E>
 where
   E: From<crate::Error>,
 {
-  const BIND_PREFIX: &'static str = "$";
-  const IS_BIND_INCREASING: bool = true;
   const TY: DatabaseTy = DatabaseTy::Postgres;
 
-  type DecodeValue<'exec> = DecodeValue<'exec>;
-  type EncodeValue<'buffer, 'tmp>
-    = EncodeValue<'buffer, 'tmp>
+  type Record<'exec> = PostgresRecord<'exec, E>;
+  type Records<'exec> = PostgresRecords<'exec, E>;
+  type Ty = Ty;
+}
+
+impl<E> DEController for Postgres<E>
+where
+  E: From<crate::Error>,
+{
+  type Aux = ();
+  type DecodeWrapper<'inner, 'outer>
+    = DecodeWrapper<'inner>
   where
-    'buffer: 'tmp;
+    'inner: 'outer;
   type Error = E;
-  type Record<'exec> = Record<'exec, E>;
-  type Records<'exec> = Records<'exec, E>;
-  type Ty = Ty;
+  type EncodeWrapper<'inner, 'outer>
+    = EncodeWrapper<'inner, 'outer>
+  where
+    'inner: 'outer;
 }
 
 impl<E> Default for Postgres<E> {
@@ -74,7 +88,7 @@ impl<E> Default for Postgres<E> {
 
 #[cfg(test)]
 mod tests {
-  use crate::database::client::postgres::{statements::column::Column, Ty};
+  use crate::database::client::postgres::{Ty, column::Column};
 
   pub(crate) fn column0() -> Column {
     Column::new("a".try_into().unwrap(), Ty::VarcharArray)
@@ -87,8 +101,4 @@ mod tests {
   pub(crate) fn column2() -> Column {
     Column::new("c".try_into().unwrap(), Ty::Char)
   }
-
-  pub(crate) fn column3() -> Column {
-    Column::new("d".try_into().unwrap(), Ty::Date)
-  }
 }
diff --git a/wtx/src/database/client/postgres/authentication.rs b/wtx/src/database/client/postgres/authentication.rs
index 2d34e677..ae41b870 100644
--- a/wtx/src/database/client/postgres/authentication.rs
+++ b/wtx/src/database/client/postgres/authentication.rs
@@ -1,6 +1,6 @@
 use crate::{
-  database::client::postgres::PostgresError,
-  misc::{bytes_split1, into_rslt, FromRadix10},
+  database::DatabaseError,
+  misc::{FromRadix10, bytes_split1, into_rslt},
 };
 use core::any::type_name;
 
@@ -20,7 +20,7 @@ impl<'bytes> TryFrom<&'bytes [u8]> for Authentication<'bytes> {
     let (n, rest) = if let [a, b, c, d, rest @ ..] = bytes {
       (u32::from_be_bytes([*a, *b, *c, *d]), rest)
     } else {
-      return Err(PostgresError::UnexpectedValueFromBytes { expected: type_name::<Self>() }.into());
+      return Err(DatabaseError::UnexpectedValueFromBytes { expected: type_name::<Self>() }.into());
     };
     Ok(match n {
       0 => Self::Ok,
@@ -61,7 +61,7 @@ impl<'bytes> TryFrom<&'bytes [u8]> for Authentication<'bytes> {
       }
       _ => {
         return Err(
-          PostgresError::UnexpectedValueFromBytes { expected: type_name::<Self>() }.into(),
+          DatabaseError::UnexpectedValueFromBytes { expected: type_name::<Self>() }.into(),
         );
       }
     })
diff --git a/wtx/src/database/client/postgres/statements/column.rs b/wtx/src/database/client/postgres/column.rs
similarity index 80%
rename from wtx/src/database/client/postgres/statements/column.rs
rename to wtx/src/database/client/postgres/column.rs
index be66e15a..7afde013 100644
--- a/wtx/src/database/client/postgres/statements/column.rs
+++ b/wtx/src/database/client/postgres/column.rs
@@ -1,4 +1,4 @@
-use crate::database::{client::postgres::Ty, Identifier};
+use crate::database::{Identifier, client::postgres::Ty};
 
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub(crate) struct Column {
diff --git a/wtx/src/database/client/postgres/config.rs b/wtx/src/database/client/postgres/config.rs
index 61685cf2..edf7b2f9 100644
--- a/wtx/src/database/client/postgres/config.rs
+++ b/wtx/src/database/client/postgres/config.rs
@@ -1,56 +1,28 @@
 use crate::{
-  database::client::postgres::PostgresError,
-  misc::{into_rslt, str_split1, str_split_once1, FromRadix10, UriRef},
+  database::client::{postgres::PostgresError, rdbms::query_walker},
+  misc::UriRef,
 };
-use core::time::Duration;
 
 /// Configuration
 #[derive(Debug, PartialEq, Eq)]
 pub struct Config<'data> {
-  pub(crate) app_name: &'data str,
+  pub(crate) application_name: &'data str,
   pub(crate) channel_binding: ChannelBinding,
-  pub(crate) connect_timeout: Duration,
   pub(crate) db: &'data str,
-  pub(crate) host: &'data str,
-  pub(crate) keepalives: bool,
-  pub(crate) load_balance_hosts: LoadBalanceHosts,
   pub(crate) password: &'data str,
-  pub(crate) port: u16,
-  pub(crate) target_session_attrs: TargetSessionAttrs,
-  pub(crate) tcp_user_timeout: Duration,
   pub(crate) user: &'data str,
 }
 
 impl<'data> Config<'data> {
-  /// Unwraps the elements of an URI.
+  /// Unwraps the elements from an URI.
   #[inline]
   pub fn from_uri(uri: &'data UriRef<'_>) -> crate::Result<Config<'data>> {
-    let mut this = Self {
-      app_name: "",
-      channel_binding: ChannelBinding::Prefer,
-      connect_timeout: Duration::ZERO,
-      db: uri.path().get(1..).unwrap_or_default(),
-      host: uri.hostname(),
-      keepalives: true,
-      load_balance_hosts: LoadBalanceHosts::Disable,
-      password: uri.password(),
-      port: into_rslt(uri.port())?,
-      target_session_attrs: TargetSessionAttrs::Any,
-      tcp_user_timeout: Duration::ZERO,
-      user: uri.user(),
-    };
-    let mut pair_iter = str_split1(uri.query_and_fragment(), b'&');
-    if let Some(mut key_value) = pair_iter.next() {
-      key_value = key_value.get(1..).unwrap_or_default();
-      if let Some((key, value)) = str_split_once1(key_value, b'=') {
-        this.set_param(key, value)?;
-      }
-    }
-    for key_value in pair_iter {
-      if let Some((key, value)) = str_split_once1(key_value, b'=') {
-        this.set_param(key, value)?;
-      }
-    }
+    let db = uri.path().get(1..).unwrap_or_default();
+    let password = uri.password();
+    let user = uri.user();
+    let mut this =
+      Self { application_name: "", channel_binding: ChannelBinding::Prefer, db, password, user };
+    query_walker(uri, |key, value| this.set_param(key, value))?;
     Ok(this)
   }
 
@@ -58,7 +30,7 @@ impl<'data> Config<'data> {
   fn set_param(&mut self, key: &str, value: &'data str) -> crate::Result<()> {
     match key {
       "application_name" => {
-        self.app_name = value;
+        self.application_name = value;
       }
       "channel_binding" => {
         let channel_binding = match value {
@@ -69,30 +41,6 @@ impl<'data> Config<'data> {
         };
         self.channel_binding = channel_binding;
       }
-      "connect_timeout" => {
-        if let Ok(timeout) = u64::from_radix_10(value.as_bytes()) {
-          self.connect_timeout = Duration::from_secs(timeout);
-        }
-      }
-      "load_balance_hosts" => {
-        self.load_balance_hosts = match value {
-          "disable" => LoadBalanceHosts::Disable,
-          "random" => LoadBalanceHosts::Random,
-          _ => return Err(PostgresError::UnknownConfigurationParameter.into()),
-        };
-      }
-      "target_session_attrs" => {
-        self.target_session_attrs = match value {
-          "any" => TargetSessionAttrs::Any,
-          "read-write" => TargetSessionAttrs::ReadWrite,
-          _ => return Err(PostgresError::UnknownConfigurationParameter.into()),
-        };
-      }
-      "tcp_user_timeout" => {
-        if let Ok(timeout) = u64::from_radix_10(value.as_bytes()) {
-          self.tcp_user_timeout = Duration::from_secs(timeout);
-        }
-      }
       _ => return Err(PostgresError::UnknownConfigurationParameter.into()),
     }
     Ok(())
@@ -106,22 +54,10 @@ pub(crate) enum ChannelBinding {
   Require,
 }
 
-#[derive(Debug, PartialEq, Eq)]
-pub(crate) enum LoadBalanceHosts {
-  Disable,
-  Random,
-}
-
-#[derive(Debug, PartialEq, Eq)]
-pub(crate) enum TargetSessionAttrs {
-  Any,
-  ReadWrite,
-}
-
 #[cfg(test)]
 mod tests {
   use crate::{
-    database::client::postgres::{config::ChannelBinding, Config},
+    database::client::postgres::{Config, config::ChannelBinding},
     misc::Uri,
   };
 
@@ -129,10 +65,9 @@ mod tests {
   fn from_uri() {
     let uri = Uri::new("postgres://ab:cd@ef:5432/gh?application_name=ij&channel_binding=disable");
     let config = Config::from_uri(&uri).unwrap();
-    assert_eq!(config.app_name, "ij");
+    assert_eq!(config.application_name, "ij");
     assert_eq!(config.channel_binding, ChannelBinding::Disable);
     assert_eq!(config.db, "gh");
-    assert_eq!(config.host, "ef");
     assert_eq!(config.password, "cd");
     assert_eq!(config.user, "ab");
   }
diff --git a/wtx/src/database/client/postgres/db_error.rs b/wtx/src/database/client/postgres/db_error.rs
index 47c5a326..fa887718 100644
--- a/wtx/src/database/client/postgres/db_error.rs
+++ b/wtx/src/database/client/postgres/db_error.rs
@@ -1,6 +1,6 @@
 use crate::{
   database::client::postgres::{PostgresError, SqlState},
-  misc::{FromRadix10, Usize, _usize_range_from_u32_range, into_rslt, str_split1},
+  misc::{_usize_range_from_u32_range, FromRadix10, Usize, into_rslt, str_split1},
 };
 use alloc::boxed::Box;
 use core::{
@@ -294,7 +294,7 @@ impl TryFrom<&str> for DbError {
         "t" => table = Some(range),
         _ => {
           return Err(crate::Error::UnexpectedUint {
-            received: u32::from_radix_10(ty.as_bytes())?,
+            received: u64::from_radix_10(ty.as_bytes())?,
           });
         }
       }
diff --git a/wtx/src/database/client/postgres/decode_value.rs b/wtx/src/database/client/postgres/decode_value.rs
deleted file mode 100644
index e9a4cd52..00000000
--- a/wtx/src/database/client/postgres/decode_value.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-use crate::database::client::postgres::ty::Ty;
-
-/// Struct used for decoding elements in PostgreSQL.
-#[derive(Debug, PartialEq)]
-pub struct DecodeValue<'any> {
-  bytes: &'any [u8],
-  ty: Ty,
-}
-
-impl<'any> DecodeValue<'any> {
-  pub(crate) fn new(bytes: &'any [u8], ty: Ty) -> Self {
-    Self { bytes, ty }
-  }
-
-  /// Bytes of a column.
-  #[inline]
-  pub fn bytes(&self) -> &'any [u8] {
-    self.bytes
-  }
-
-  /// Type of a column.
-  #[inline]
-  pub fn ty(&self) -> &Ty {
-    &self.ty
-  }
-}
-
-impl Default for DecodeValue<'_> {
-  #[inline]
-  fn default() -> Self {
-    Self { bytes: &[], ty: Ty::Any }
-  }
-}
diff --git a/wtx/src/database/client/postgres/decode_wrapper.rs b/wtx/src/database/client/postgres/decode_wrapper.rs
new file mode 100644
index 00000000..807a1845
--- /dev/null
+++ b/wtx/src/database/client/postgres/decode_wrapper.rs
@@ -0,0 +1,40 @@
+use crate::{database::client::postgres::ty::Ty, misc::Lease};
+
+/// Struct used for decoding elements in PostgreSQL.
+#[derive(Debug, PartialEq)]
+pub struct DecodeWrapper<'de> {
+  bytes: &'de [u8],
+  ty: Ty,
+}
+
+impl<'de> DecodeWrapper<'de> {
+  pub(crate) fn new(bytes: &'de [u8], ty: Ty) -> Self {
+    Self { bytes, ty }
+  }
+
+  /// Bytes
+  #[inline]
+  pub fn bytes(&self) -> &'de [u8] {
+    self.bytes
+  }
+
+  /// Type of a column.
+  #[inline]
+  pub fn ty(&self) -> &Ty {
+    &self.ty
+  }
+}
+
+impl Default for DecodeWrapper<'_> {
+  #[inline]
+  fn default() -> Self {
+    Self { bytes: &[], ty: Ty::Any }
+  }
+}
+
+impl Lease<[u8]> for DecodeWrapper<'_> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.bytes
+  }
+}
diff --git a/wtx/src/database/client/postgres/encode_value.rs b/wtx/src/database/client/postgres/encode_value.rs
deleted file mode 100644
index 5dd59202..00000000
--- a/wtx/src/database/client/postgres/encode_value.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-use crate::misc::{FilledBufferWriter, Lease, LeaseMut};
-
-/// Struct used for encoding elements in PostgreSQL.
-#[derive(Debug)]
-pub struct EncodeValue<'buffer, 'tmp> {
-  fbw: &'tmp mut FilledBufferWriter<'buffer>,
-}
-
-impl<'buffer, 'tmp> EncodeValue<'buffer, 'tmp> {
-  #[inline]
-  pub(crate) fn new(fbw: &'tmp mut FilledBufferWriter<'buffer>) -> Self {
-    Self { fbw }
-  }
-
-  /// See [`FilledBufferWriter`].
-  #[inline]
-  pub fn fbw(&mut self) -> &mut FilledBufferWriter<'buffer> {
-    self.fbw
-  }
-}
-
-impl<'buffer> Lease<FilledBufferWriter<'buffer>> for EncodeValue<'buffer, '_> {
-  #[inline]
-  fn lease(&self) -> &FilledBufferWriter<'buffer> {
-    self.fbw
-  }
-}
-
-impl<'buffer> LeaseMut<FilledBufferWriter<'buffer>> for EncodeValue<'buffer, '_> {
-  #[inline]
-  fn lease_mut(&mut self) -> &mut FilledBufferWriter<'buffer> {
-    self.fbw
-  }
-}
diff --git a/wtx/src/database/client/postgres/encode_wrapper.rs b/wtx/src/database/client/postgres/encode_wrapper.rs
new file mode 100644
index 00000000..6f55404e
--- /dev/null
+++ b/wtx/src/database/client/postgres/encode_wrapper.rs
@@ -0,0 +1,27 @@
+use crate::misc::{Lease, SuffixWriterFbvm};
+
+/// Struct used for encoding elements in PostgreSQL.
+#[derive(Debug)]
+pub struct EncodeWrapper<'buffer, 'tmp> {
+  sw: &'tmp mut SuffixWriterFbvm<'buffer>,
+}
+
+impl<'buffer, 'tmp> EncodeWrapper<'buffer, 'tmp> {
+  #[inline]
+  pub(crate) fn new(sw: &'tmp mut SuffixWriterFbvm<'buffer>) -> Self {
+    Self { sw }
+  }
+
+  /// See [`FilledBufferWriter`].
+  #[inline]
+  pub fn sw(&mut self) -> &mut SuffixWriterFbvm<'buffer> {
+    self.sw
+  }
+}
+
+impl Lease<[u8]> for EncodeWrapper<'_, '_> {
+  #[inline]
+  fn lease(&self) -> &[u8] {
+    self.sw._curr_bytes()
+  }
+}
diff --git a/wtx/src/database/client/postgres/executor/simple_query.rs b/wtx/src/database/client/postgres/executor/simple_query.rs
deleted file mode 100644
index e3da6691..00000000
--- a/wtx/src/database/client/postgres/executor/simple_query.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use crate::{
-  database::client::postgres::{
-    executor_buffer::ExecutorBufferPartsMut, message::MessageTy, protocol::query, Executor,
-    ExecutorBuffer, PostgresError,
-  },
-  misc::{FilledBufferWriter, LeaseMut, Stream},
-};
-
-impl<E, EB, S> Executor<E, EB, S>
-where
-  EB: LeaseMut<ExecutorBuffer>,
-  S: Stream,
-{
-  #[inline]
-  pub(crate) async fn simple_query_execute(
-    &mut self,
-    cmd: &str,
-    mut cb: impl FnMut(u64),
-  ) -> crate::Result<()> {
-    {
-      let ExecutorBufferPartsMut { nb, rb, vb, .. } = self.eb.lease_mut().parts_mut();
-      ExecutorBuffer::clear_cmd_buffers(nb, rb, vb);
-      let mut fbw = FilledBufferWriter::from(&mut self.eb.lease_mut().nb);
-      query(cmd.as_bytes(), &mut fbw)?;
-      self.stream.write_all(fbw._curr_bytes()).await?;
-    }
-    loop {
-      let nb = &mut self.eb.lease_mut().nb;
-      let msg = Self::fetch_msg_from_stream(&mut self.cs, nb, &mut self.stream).await?;
-      match msg.ty {
-        MessageTy::CommandComplete(n) => cb(n),
-        MessageTy::EmptyQueryResponse => {
-          cb(0);
-        }
-        MessageTy::ReadyForQuery => return Ok(()),
-        _ => return Err(PostgresError::UnexpectedDatabaseMessage { received: msg.tag }.into()),
-      }
-    }
-  }
-}
diff --git a/wtx/src/database/client/postgres/executor_buffer.rs b/wtx/src/database/client/postgres/executor_buffer.rs
index c24aca93..f4747d31 100644
--- a/wtx/src/database/client/postgres/executor_buffer.rs
+++ b/wtx/src/database/client/postgres/executor_buffer.rs
@@ -1,6 +1,6 @@
 use crate::{
-  database::{client::postgres::Statements, Identifier},
-  misc::{partitioned_filled_buffer::PartitionedFilledBuffer, Lease, LeaseMut, Rng, Vector},
+  database::{Identifier, client::postgres::PostgresStatements},
+  misc::{Lease, LeaseMut, Rng, Vector, partitioned_filled_buffer::PartitionedFilledBuffer},
 };
 use core::ops::Range;
 use hashbrown::HashMap;
@@ -15,7 +15,7 @@ pub struct ExecutorBuffer {
   /// Records Buffer.
   pub(crate) rb: Vector<usize>,
   /// Statements
-  pub(crate) stmts: Statements,
+  pub(crate) stmts: PostgresStatements,
   /// Values Buffer.
   pub(crate) vb: Vector<(bool, Range<usize>)>,
 }
@@ -31,7 +31,7 @@ impl ExecutorBuffer {
       cp: HashMap::new(),
       nb: PartitionedFilledBuffer::new(),
       rb: Vector::new(),
-      stmts: Statements::new(max_stmts, rng),
+      stmts: PostgresStatements::new(max_stmts, rng),
       vb: Vector::new(),
     }
   }
@@ -50,7 +50,7 @@ impl ExecutorBuffer {
       cp: HashMap::with_capacity(4),
       nb: PartitionedFilledBuffer::_with_capacity(network_buffer_cap)?,
       rb: Vector::with_capacity(rows_cap)?,
-      stmts: Statements::with_capacity(columns_cap, max_stmts, rng, stmts_cap)?,
+      stmts: PostgresStatements::with_capacity(columns_cap, max_stmts, rng, stmts_cap)?,
       vb: Vector::with_capacity(rows_cap.saturating_mul(columns_cap))?,
     })
   }
@@ -108,6 +108,6 @@ pub(crate) struct ExecutorBufferPartsMut<'eb> {
   pub(crate) cp: &'eb mut HashMap<Identifier, Identifier>,
   pub(crate) nb: &'eb mut PartitionedFilledBuffer,
   pub(crate) rb: &'eb mut Vector<usize>,
-  pub(crate) stmts: &'eb mut Statements,
+  pub(crate) stmts: &'eb mut PostgresStatements,
   pub(crate) vb: &'eb mut Vector<(bool, Range<usize>)>,
 }
diff --git a/wtx/src/database/client/postgres/message.rs b/wtx/src/database/client/postgres/message.rs
index 2ff1d7a7..a2edb942 100644
--- a/wtx/src/database/client/postgres/message.rs
+++ b/wtx/src/database/client/postgres/message.rs
@@ -1,6 +1,9 @@
 use crate::{
-  database::client::postgres::{authentication::Authentication, DbError, PostgresError},
-  misc::{bytes_rsplit1, bytes_split1, from_utf8_basic, ConnectionState, FromRadix10},
+  database::{
+    DatabaseError,
+    client::postgres::{DbError, PostgresError, authentication::Authentication},
+  },
+  misc::{ConnectionState, FromRadix10, bytes_rsplit1, bytes_split1, from_utf8_basic},
 };
 use core::any::type_name;
 
@@ -113,7 +116,7 @@ impl<'bytes> TryFrom<(&mut ConnectionState, &'bytes [u8])> for MessageTy<'bytes>
       }
       _ => {
         return Err(
-          PostgresError::UnexpectedValueFromBytes { expected: type_name::<Self>() }.into(),
+          DatabaseError::UnexpectedValueFromBytes { expected: type_name::<Self>() }.into(),
         );
       }
     };
diff --git a/wtx/src/database/client/postgres/postgres_error.rs b/wtx/src/database/client/postgres/postgres_error.rs
index 4ac1392c..9fb8c301 100644
--- a/wtx/src/database/client/postgres/postgres_error.rs
+++ b/wtx/src/database/client/postgres/postgres_error.rs
@@ -30,13 +30,6 @@ pub enum PostgresError {
   ServerDoesNotSupportEncryption,
   /// A query
   StatementHashCollision,
-  /// Received size differs from expected size.
-  UnexpectedBufferSize {
-    /// Expected
-    expected: u32,
-    /// Received
-    received: u32,
-  },
   /// Received an unexpected message type.
   UnexpectedDatabaseMessage {
     /// Received
@@ -44,17 +37,10 @@ pub enum PostgresError {
   },
   /// Received an expected message type but the related bytes are in an unexpected state.
   UnexpectedDatabaseMessageBytes,
-  /// Bytes don't represent expected type
-  UnexpectedValueFromBytes {
-    /// Expected
-    expected: &'static str,
-  },
   /// The system does not support a requested authentication method.
   UnknownAuthenticationMethod,
   /// The system does not support a provided parameter.
   UnknownConfigurationParameter,
-  /// Received a statement ID that is not present in the local cache.
-  UnknownStatementId,
   /// The system only supports decimals with 64 digits.
   VeryLargeDecimal,
 }
diff --git a/wtx/src/database/client/postgres/executor.rs b/wtx/src/database/client/postgres/postgres_executor.rs
similarity index 76%
rename from wtx/src/database/client/postgres/executor.rs
rename to wtx/src/database/client/postgres/postgres_executor.rs
index 5ee30be6..0198f143 100644
--- a/wtx/src/database/client/postgres/executor.rs
+++ b/wtx/src/database/client/postgres/postgres_executor.rs
@@ -6,29 +6,29 @@ mod simple_query;
 
 use crate::{
   database::{
+    Database, Executor, RecordValues, StmtCmd,
     client::postgres::{
-      executor::commons::FetchWithStmtCommons,
+      Config, Postgres, PostgresError, PostgresRecord, PostgresRecords,
       executor_buffer::{ExecutorBuffer, ExecutorBufferPartsMut},
       message::MessageTy,
+      postgres_executor::commons::FetchWithStmtCommons,
       protocol::{encrypted_conn, initial_conn_msg},
-      Config, Postgres, PostgresError, Record, Records,
     },
-    Database, RecordValues, StmtCmd,
   },
-  misc::{ConnectionState, FilledBufferWriter, Lease, LeaseMut, Rng, Stream, StreamWithTls},
+  misc::{ConnectionState, DEController, Lease, LeaseMut, Rng, Stream, StreamWithTls},
 };
 use core::{future::Future, marker::PhantomData};
 
 /// Executor
 #[derive(Debug)]
-pub struct Executor<E, EB, S> {
+pub struct PostgresExecutor<E, EB, S> {
   pub(crate) cs: ConnectionState,
   pub(crate) eb: EB,
   pub(crate) phantom: PhantomData<fn() -> E>,
   pub(crate) stream: S,
 }
 
-impl<E, EB, S> Executor<E, EB, S>
+impl<E, EB, S> PostgresExecutor<E, EB, S>
 where
   EB: LeaseMut<ExecutorBuffer>,
   S: Stream,
@@ -66,18 +66,19 @@ where
   {
     eb.lease_mut().clear();
     {
-      let mut fbw = FilledBufferWriter::from(&mut eb.lease_mut().nb);
-      encrypted_conn(&mut fbw)?;
-      stream.write_all(fbw._curr_bytes()).await?;
+      let mut sw = eb.lease_mut().nb._suffix_writer();
+      encrypted_conn(&mut sw)?;
+      stream.write_all(sw._curr_bytes()).await?;
     }
     let mut buf = [0];
     let _ = stream.read(&mut buf).await?;
     if buf[0] != b'S' {
       return Err(PostgresError::ServerDoesNotSupportEncryption.into());
     }
-    let stream = cb(stream).await?;
-    let tls_server_end_point = stream.tls_server_end_point()?;
-    Self::do_connect(config, eb, rng, stream, tls_server_end_point.as_ref().map(Lease::lease)).await
+    let enc_stream = cb(stream).await?;
+    let tls_server_end_point = enc_stream.tls_server_end_point()?;
+    Self::do_connect(config, eb, rng, enc_stream, tls_server_end_point.as_ref().map(Lease::lease))
+      .await
   }
 
   /// Mutable buffer reference
@@ -105,14 +106,14 @@ where
   }
 
   async fn send_initial_conn_msg(&mut self, config: &Config<'_>) -> crate::Result<()> {
-    let mut fbw = FilledBufferWriter::from(&mut self.eb.lease_mut().nb);
-    initial_conn_msg(config, &mut fbw)?;
-    self.stream.write_all(fbw._curr_bytes()).await?;
+    let mut sw = self.eb.lease_mut().nb._suffix_writer();
+    initial_conn_msg(config, &mut sw)?;
+    self.stream.write_all(sw._curr_bytes()).await?;
     Ok(())
   }
 }
 
-impl<E, EB, S> crate::database::Executor for Executor<E, EB, S>
+impl<E, EB, S> Executor for PostgresExecutor<E, EB, S>
 where
   E: From<crate::Error>,
   EB: LeaseMut<ExecutorBuffer>,
@@ -126,7 +127,11 @@ where
   }
 
   #[inline]
-  async fn execute(&mut self, cmd: &str, cb: impl FnMut(u64)) -> crate::Result<()> {
+  async fn execute(
+    &mut self,
+    cmd: &str,
+    cb: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> Result<(), <Self::Database as DEController>::Error> {
     self.simple_query_execute(cmd, cb).await
   }
 
@@ -135,7 +140,7 @@ where
     &mut self,
     sc: SC,
     rv: RV,
-  ) -> Result<u64, <Self::Database as Database>::Error>
+  ) -> Result<u64, <Self::Database as DEController>::Error>
   where
     RV: RecordValues<Self::Database>,
     SC: StmtCmd,
@@ -145,8 +150,8 @@ where
     ExecutorBuffer::clear_cmd_buffers(nb, rb, vb);
     let mut rows = 0;
     let mut fwsc = FetchWithStmtCommons { cs, stream, tys: &[] };
-    let (_, stmt_id, stmt) = Self::write_send_await_stmt_prot(&mut fwsc, nb, sc, stmts).await?;
-    Self::write_send_await_stmt_initial(&mut fwsc, nb, rv, &stmt, &stmt_id).await?;
+    let (_, stmt_cmd_id, stmt) = Self::write_send_await_stmt_prot(&mut fwsc, nb, sc, stmts).await?;
+    Self::write_send_await_stmt_initial(&mut fwsc, nb, rv, &stmt, &stmt_cmd_id).await?;
     loop {
       let msg = Self::fetch_msg_from_stream(cs, nb, stream).await?;
       match msg.ty {
@@ -165,23 +170,6 @@ where
     Ok(rows)
   }
 
-  #[inline]
-  async fn fetch_with_stmt<SC, RV>(
-    &mut self,
-    sc: SC,
-    rv: RV,
-  ) -> Result<<Self::Database as Database>::Record<'_>, E>
-  where
-    RV: RecordValues<Self::Database>,
-    SC: StmtCmd,
-  {
-    let Self { cs, eb, phantom: _, stream } = self;
-    let ExecutorBufferPartsMut { nb, stmts, vb, .. } = eb.lease_mut().parts_mut();
-    let mut fwsc = FetchWithStmtCommons { cs, stream, tys: &[] };
-    let (_, stmt_id, stmt) = Self::write_send_await_stmt_prot(&mut fwsc, nb, sc, stmts).await?;
-    Self::write_send_await_fetch_with_stmt_wo_prot(&mut fwsc, nb, rv, stmt, &stmt_id, vb).await
-  }
-
   #[inline]
   async fn fetch_many_with_stmt<SC, RV>(
     &mut self,
@@ -197,8 +185,8 @@ where
     let ExecutorBufferPartsMut { nb, rb, stmts, vb, .. } = eb.lease_mut().parts_mut();
     ExecutorBuffer::clear_cmd_buffers(nb, rb, vb);
     let mut fwsc = FetchWithStmtCommons { cs, stream, tys: &[] };
-    let (_, stmt_id, stmt) = Self::write_send_await_stmt_prot(&mut fwsc, nb, sc, stmts).await?;
-    Self::write_send_await_stmt_initial(&mut fwsc, nb, rv, &stmt, &stmt_id).await?;
+    let (_, stmt_cmd_id, stmt) = Self::write_send_await_stmt_prot(&mut fwsc, nb, sc, stmts).await?;
+    Self::write_send_await_stmt_initial(&mut fwsc, nb, rv, &stmt, &stmt_cmd_id).await?;
     let begin = nb._current_end_idx();
     let begin_data = nb._current_end_idx().wrapping_add(7);
     loop {
@@ -209,7 +197,7 @@ where
           let bytes = nb._buffer().get(begin_data..nb._current_end_idx()).unwrap_or_default();
           let range_begin = nb._antecedent_end_idx().wrapping_sub(begin);
           let range_end = nb._current_end_idx().wrapping_sub(begin_data);
-          cb(&Record::parse(bytes, range_begin..range_end, stmt.clone(), vb, len)?)?;
+          cb(&PostgresRecord::parse(bytes, range_begin..range_end, stmt.clone(), vb, len)?)?;
           rb.push(vb.len())?;
         }
         MessageTy::ReadyForQuery => {
@@ -222,16 +210,29 @@ where
         }
       }
     }
-    Ok(Records {
-      bytes: nb
-        ._buffer()
-        .get(begin_data.wrapping_add(4)..nb._current_end_idx())
-        .unwrap_or_default(),
-      phantom: PhantomData,
-      records_values_offsets: rb,
+    Ok(PostgresRecords::new(
+      nb._buffer().get(begin_data.wrapping_add(4)..nb._current_end_idx()).unwrap_or_default(),
+      rb,
       stmt,
-      values_bytes_offsets: vb,
-    })
+      vb,
+    ))
+  }
+
+  #[inline]
+  async fn fetch_with_stmt<SC, RV>(
+    &mut self,
+    sc: SC,
+    rv: RV,
+  ) -> Result<<Self::Database as Database>::Record<'_>, E>
+  where
+    RV: RecordValues<Self::Database>,
+    SC: StmtCmd,
+  {
+    let Self { cs, eb, phantom: _, stream } = self;
+    let ExecutorBufferPartsMut { nb, stmts, vb, .. } = eb.lease_mut().parts_mut();
+    let mut fwsc = FetchWithStmtCommons { cs, stream, tys: &[] };
+    let (_, stmt_cmd_id, stmt) = Self::write_send_await_stmt_prot(&mut fwsc, nb, sc, stmts).await?;
+    Self::write_send_await_fetch_with_stmt_wo_prot(&mut fwsc, nb, rv, stmt, &stmt_cmd_id, vb).await
   }
 
   #[inline]
diff --git a/wtx/src/database/client/postgres/executor/authentication.rs b/wtx/src/database/client/postgres/postgres_executor/authentication.rs
similarity index 91%
rename from wtx/src/database/client/postgres/executor/authentication.rs
rename to wtx/src/database/client/postgres/postgres_executor/authentication.rs
index 47538d98..3c638b95 100644
--- a/wtx/src/database/client/postgres/executor/authentication.rs
+++ b/wtx/src/database/client/postgres/postgres_executor/authentication.rs
@@ -1,25 +1,25 @@
 use crate::{
   database::{
+    Identifier,
     client::postgres::{
+      Config, PostgresError, PostgresExecutor,
       authentication::Authentication,
       config::ChannelBinding,
       executor_buffer::{ExecutorBuffer, ExecutorBufferPartsMut},
       message::MessageTy,
       protocol::{sasl_first, sasl_second},
-      Config, Executor, PostgresError,
     },
-    Identifier,
   },
   misc::{
-    bytes_split1, from_utf8_basic, partitioned_filled_buffer::PartitionedFilledBuffer, ArrayVector,
-    ConnectionState, FilledBufferWriter, LeaseMut, Rng, Stream, Vector,
+    ArrayVector, ConnectionState, LeaseMut, Rng, Stream, SuffixWriterFbvm, Vector, bytes_split1,
+    from_utf8_basic, partitioned_filled_buffer::PartitionedFilledBuffer,
   },
 };
-use base64::prelude::{Engine as _, BASE64_STANDARD};
+use base64::prelude::{BASE64_STANDARD, Engine as _};
 use hmac::{Hmac, Mac};
 use sha2::Sha256;
 
-impl<E, EB, S> Executor<E, EB, S>
+impl<E, EB, S> PostgresExecutor<E, EB, S>
 where
   EB: LeaseMut<ExecutorBuffer>,
   S: Stream,
@@ -114,7 +114,6 @@ where
 
   #[inline]
   pub(crate) async fn read_after_authentication_data(&mut self) -> crate::Result<()> {
-    self.eb.lease_mut().nb._reserve(2048)?;
     loop {
       let ExecutorBufferPartsMut { cp, nb, .. } = self.eb.lease_mut().parts_mut();
       let msg = Self::fetch_msg_from_stream(&mut self.cs, nb, &mut self.stream).await?;
@@ -150,11 +149,10 @@ where
   {
     let tsep_data = tls_server_end_point.unwrap_or_default();
     let local_nonce = nonce(rng);
-    nb._reserve(2048)?;
     {
-      let mut fbw = FilledBufferWriter::from(&mut *nb);
-      sasl_first(&mut fbw, (method_bytes, method_header), &local_nonce)?;
-      stream.write_all(fbw._curr_bytes()).await?;
+      let mut sw = SuffixWriterFbvm::from(nb._suffix_writer());
+      sasl_first(&mut sw, (method_bytes, method_header), &local_nonce)?;
+      stream.write_all(sw._curr_bytes()).await?;
     }
 
     let (mut auth_data, response_nonce, salted_password) = {
@@ -183,16 +181,16 @@ where
     };
 
     {
-      let mut fbw = FilledBufferWriter::from(&mut *nb);
+      let mut sw = SuffixWriterFbvm::from(nb._suffix_writer());
       sasl_second(
         &mut auth_data,
-        &mut fbw,
+        &mut sw,
         method_header,
         &response_nonce,
         &salted_password,
         tsep_data,
       )?;
-      stream.write_all(fbw._curr_bytes()).await?;
+      stream.write_all(sw._curr_bytes()).await?;
     }
 
     {
diff --git a/wtx/src/database/client/postgres/executor/commons.rs b/wtx/src/database/client/postgres/postgres_executor/commons.rs
similarity index 100%
rename from wtx/src/database/client/postgres/executor/commons.rs
rename to wtx/src/database/client/postgres/postgres_executor/commons.rs
diff --git a/wtx/src/database/client/postgres/executor/fetch.rs b/wtx/src/database/client/postgres/postgres_executor/fetch.rs
similarity index 84%
rename from wtx/src/database/client/postgres/executor/fetch.rs
rename to wtx/src/database/client/postgres/postgres_executor/fetch.rs
index 2e6034fd..d450b631 100644
--- a/wtx/src/database/client/postgres/executor/fetch.rs
+++ b/wtx/src/database/client/postgres/postgres_executor/fetch.rs
@@ -1,21 +1,20 @@
 use crate::{
   database::{
+    RecordValues,
     client::postgres::{
-      executor::commons::FetchWithStmtCommons,
+      ExecutorBuffer, Postgres, PostgresError, PostgresExecutor, PostgresRecord, PostgresStatement,
       message::{Message, MessageTy},
-      statements::statement::Statement,
-      Executor, ExecutorBuffer, Postgres, PostgresError, Record,
+      postgres_executor::commons::FetchWithStmtCommons,
     },
-    RecordValues,
   },
   misc::{
-    ConnectionState, LeaseMut, Stream, Usize, Vector, _read_header, _read_payload,
+    _read_header, _read_payload, ConnectionState, LeaseMut, Stream, Usize, Vector,
     partitioned_filled_buffer::PartitionedFilledBuffer,
   },
 };
 use core::ops::Range;
 
-impl<E, EB, S> Executor<E, EB, S>
+impl<E, EB, S> PostgresExecutor<E, EB, S>
 where
   EB: LeaseMut<ExecutorBuffer>,
   S: Stream,
@@ -25,15 +24,15 @@ where
     fwsc: &mut FetchWithStmtCommons<'_, S>,
     nb: &'any mut PartitionedFilledBuffer,
     rv: RV,
-    stmt: Statement<'any>,
-    stmt_id_str: &str,
+    stmt: PostgresStatement<'any>,
+    stmt_cmd_id_array: &[u8],
     vb: &'any mut Vector<(bool, Range<usize>)>,
-  ) -> Result<Record<'any, E>, E>
+  ) -> Result<PostgresRecord<'any, E>, E>
   where
     E: From<crate::Error>,
     RV: RecordValues<Postgres<E>>,
   {
-    Self::write_send_await_stmt_initial(fwsc, nb, rv, &stmt, stmt_id_str).await?;
+    Self::write_send_await_stmt_initial(fwsc, nb, rv, &stmt, stmt_cmd_id_array).await?;
     let mut data_row_msg_range = None;
     loop {
       let msg = Self::fetch_msg_from_stream(fwsc.cs, nb, fwsc.stream).await?;
@@ -54,7 +53,7 @@ where
       let record_range = range.start.wrapping_add(7)..range.end;
       Some((nb._buffer().get(record_range)?, len))
     }) {
-      Ok(Record::parse(record_bytes, 0..record_bytes.len(), stmt, vb, len)?)
+      Ok(PostgresRecord::parse(record_bytes, 0..record_bytes.len(), stmt, vb, len)?)
     } else {
       Err(E::from(PostgresError::NoRecord.into()))
     }
diff --git a/wtx/src/database/client/postgres/executor/prepare.rs b/wtx/src/database/client/postgres/postgres_executor/prepare.rs
similarity index 60%
rename from wtx/src/database/client/postgres/executor/prepare.rs
rename to wtx/src/database/client/postgres/postgres_executor/prepare.rs
index a7d99520..0e3c1695 100644
--- a/wtx/src/database/client/postgres/executor/prepare.rs
+++ b/wtx/src/database/client/postgres/postgres_executor/prepare.rs
@@ -1,24 +1,27 @@
 use crate::{
   database::{
-    client::postgres::{
-      executor::commons::FetchWithStmtCommons,
-      executor_buffer::ExecutorBuffer,
-      message::MessageTy,
-      msg_field::MsgField,
-      protocol::{bind, describe, execute, parse, sync},
-      statements::{column::Column, statement::Statement, statements_misc::StatementsMisc},
-      ty::Ty,
-      Executor, Postgres, PostgresError, Statements,
+    DatabaseError, RecordValues, StmtCmd,
+    client::{
+      postgres::{
+        Postgres, PostgresError, PostgresExecutor, PostgresStatement, PostgresStatements,
+        column::Column,
+        executor_buffer::ExecutorBuffer,
+        message::MessageTy,
+        msg_field::MsgField,
+        postgres_executor::commons::FetchWithStmtCommons,
+        protocol::{bind, describe, execute, parse, sync},
+        ty::Ty,
+      },
+      rdbms::{U64Array, statements_misc::StatementsMisc, u64_array},
     },
-    RecordValues, StmtCmd,
   },
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, ArrayString, FilledBufferWriter, LeaseMut,
-    Stream,
+    ArrayString, LeaseMut, Stream, SuffixWriterFbvm,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
   },
 };
 
-impl<E, EB, S> Executor<E, EB, S>
+impl<E, EB, S> PostgresExecutor<E, EB, S>
 where
   E: From<crate::Error>,
   EB: LeaseMut<ExecutorBuffer>,
@@ -29,18 +32,18 @@ where
     fwsc: &mut FetchWithStmtCommons<'_, S>,
     nb: &mut PartitionedFilledBuffer,
     rv: RV,
-    stmt: &Statement<'_>,
-    stmt_id_str: &str,
+    stmt: &PostgresStatement<'_>,
+    stmt_cmd_id_array: &[u8],
   ) -> Result<(), E>
   where
     RV: RecordValues<Postgres<E>>,
   {
     {
-      let mut fbw = FilledBufferWriter::from(&mut *nb);
-      bind(&mut fbw, "", rv, stmt, stmt_id_str)?;
-      execute(&mut fbw, 0, "")?;
-      sync(&mut fbw)?;
-      fwsc.stream.write_all(fbw._curr_bytes()).await?;
+      let mut sw = SuffixWriterFbvm::from(nb._suffix_writer());
+      bind(&mut sw, "", rv, stmt, stmt_cmd_id_array)?;
+      execute(&mut sw, 0, "")?;
+      sync(&mut sw)?;
+      fwsc.stream.write_all(sw._curr_bytes()).await?;
     }
     let msg = Self::fetch_msg_from_stream(fwsc.cs, nb, fwsc.stream).await?;
     let MessageTy::BindComplete = msg.ty else {
@@ -54,26 +57,26 @@ where
     fwsc: &mut FetchWithStmtCommons<'_, S>,
     nb: &mut PartitionedFilledBuffer,
     sc: SC,
-    stmts: &'stmts mut Statements,
-  ) -> Result<(u64, ArrayString<22>, Statement<'stmts>), E>
+    stmts: &'stmts mut PostgresStatements,
+  ) -> Result<(u64, U64Array, PostgresStatement<'stmts>), E>
   where
     SC: StmtCmd,
   {
-    let stmt_hash = sc.hash(stmts.hasher_mut());
-    let stmt_id_str = Self::stmt_id_str(stmt_hash)?;
-    if stmts.get_by_stmt_hash(stmt_hash).is_some() {
+    let stmt_cmd_id = sc.hash(stmts.hasher_mut());
+    let stmt_cmd_id_array = u64_array(stmt_cmd_id);
+    if stmts.get_by_stmt_cmd_id(stmt_cmd_id).is_some() {
       // FIXME(stable): Use `if let Some ...` with polonius
-      return Ok((stmt_hash, stmt_id_str, stmts.get_by_stmt_hash(stmt_hash).unwrap()));
+      return Ok((stmt_cmd_id, stmt_cmd_id_array, stmts.get_by_stmt_cmd_id(stmt_cmd_id).unwrap()));
     }
 
-    let stmt_cmd = sc.cmd().ok_or_else(|| E::from(PostgresError::UnknownStatementId.into()))?;
+    let stmt_cmd = sc.cmd().ok_or_else(|| E::from(DatabaseError::UnknownStatementId.into()))?;
 
     {
-      let mut fbw = FilledBufferWriter::from(&mut *nb);
-      parse(stmt_cmd, &mut fbw, fwsc.tys.iter().copied().map(Into::into), &stmt_id_str)?;
-      describe(&stmt_id_str, &mut fbw, b'S')?;
-      sync(&mut fbw)?;
-      fwsc.stream.write_all(fbw._curr_bytes()).await?;
+      let mut sw = SuffixWriterFbvm::from(nb._suffix_writer());
+      parse(stmt_cmd, &mut sw, fwsc.tys.iter().copied().map(Into::into), &stmt_cmd_id_array)?;
+      describe(&stmt_cmd_id_array, &mut sw, b'S')?;
+      sync(&mut sw)?;
+      fwsc.stream.write_all(sw._curr_bytes()).await?;
     }
 
     let msg0 = Self::fetch_msg_from_stream(fwsc.cs, nb, fwsc.stream).await?;
@@ -87,7 +90,7 @@ where
     };
 
     let mut builder = stmts.builder();
-    let _ = builder.expand(types_len.into())?;
+    let _ = builder.expand(types_len.into(), dummy())?;
 
     {
       let elements = builder.inserted_elements();
@@ -104,7 +107,7 @@ where
       MessageTy::NoData => 0,
       MessageTy::RowDescription(columns_len, mut rd) => {
         if let Some(diff @ 1..=u16::MAX) = columns_len.checked_sub(types_len) {
-          let _ = builder.expand(diff.into())?;
+          let _ = builder.expand(diff.into(), dummy())?;
         }
         let elements = builder.inserted_elements();
         for idx in 0..columns_len {
@@ -134,16 +137,16 @@ where
       return Err(E::from(PostgresError::UnexpectedDatabaseMessage { received: msg3.tag }.into()));
     };
 
-    let sm = StatementsMisc::new(columns_len.into(), types_len.into());
-    let idx = builder.build(stmt_hash, sm)?;
+    let sm = StatementsMisc::new((), columns_len.into(), types_len.into());
+    let idx = builder.build(stmt_cmd_id, sm)?;
     let Some(stmt) = stmts.get_by_idx(idx) else {
       return Err(crate::Error::ProgrammingError.into());
     };
-    Ok((stmt_hash, stmt_id_str, stmt))
+    Ok((stmt_cmd_id, stmt_cmd_id_array, stmt))
   }
+}
 
-  #[inline]
-  fn stmt_id_str(stmt_hash: u64) -> crate::Result<ArrayString<22>> {
-    ArrayString::try_from(format_args!("s{stmt_hash}"))
-  }
+#[inline]
+fn dummy() -> (Column, Ty) {
+  (Column::new(ArrayString::new(), Ty::Any), Ty::Any)
 }
diff --git a/wtx/src/database/client/postgres/postgres_executor/simple_query.rs b/wtx/src/database/client/postgres/postgres_executor/simple_query.rs
new file mode 100644
index 00000000..8e6a7c7b
--- /dev/null
+++ b/wtx/src/database/client/postgres/postgres_executor/simple_query.rs
@@ -0,0 +1,46 @@
+use crate::{
+  database::client::postgres::{
+    ExecutorBuffer, PostgresError, PostgresExecutor, executor_buffer::ExecutorBufferPartsMut,
+    message::MessageTy, protocol::query,
+  },
+  misc::{LeaseMut, Stream, SuffixWriterFbvm},
+};
+
+impl<E, EB, S> PostgresExecutor<E, EB, S>
+where
+  E: From<crate::Error>,
+  EB: LeaseMut<ExecutorBuffer>,
+  S: Stream,
+{
+  #[inline]
+  pub(crate) async fn simple_query_execute(
+    &mut self,
+    cmd: &str,
+    mut cb: impl FnMut(u64) -> Result<(), E>,
+  ) -> Result<(), E> {
+    {
+      let ExecutorBufferPartsMut { nb, rb, vb, .. } = self.eb.lease_mut().parts_mut();
+      ExecutorBuffer::clear_cmd_buffers(nb, rb, vb);
+      let mut sw = SuffixWriterFbvm::from(self.eb.lease_mut().nb._suffix_writer());
+      query(cmd.as_bytes(), &mut sw)?;
+      self.stream.write_all(sw._curr_bytes()).await?;
+    }
+    loop {
+      let nb = &mut self.eb.lease_mut().nb;
+      let msg = Self::fetch_msg_from_stream(&mut self.cs, nb, &mut self.stream).await?;
+      match msg.ty {
+        MessageTy::CommandComplete(n) => cb(n)?,
+        MessageTy::EmptyQueryResponse => {
+          cb(0)?;
+        }
+        MessageTy::ReadyForQuery => return Ok(()),
+        _ => {
+          return Err(
+            crate::Error::from(PostgresError::UnexpectedDatabaseMessage { received: msg.tag })
+              .into(),
+          );
+        }
+      }
+    }
+  }
+}
diff --git a/wtx/src/database/client/postgres/record.rs b/wtx/src/database/client/postgres/postgres_record.rs
similarity index 67%
rename from wtx/src/database/client/postgres/record.rs
rename to wtx/src/database/client/postgres/postgres_record.rs
index 9fa69dc0..adf771f1 100644
--- a/wtx/src/database/client/postgres/record.rs
+++ b/wtx/src/database/client/postgres/postgres_record.rs
@@ -1,28 +1,28 @@
 use crate::{
   database::{
-    client::postgres::{statements::statement::Statement, DecodeValue, Postgres, PostgresError},
-    Database, ValueIdent,
+    Record, ValueIdent,
+    client::postgres::{DecodeWrapper, Postgres, PostgresError, PostgresStatement},
   },
-  misc::{Vector, _unlikely_dflt, _unlikely_elem},
+  misc::{_unlikely_dflt, _unlikely_elem, DEController, Vector},
 };
 use core::{marker::PhantomData, ops::Range};
 
 /// Record
 #[derive(Debug)]
-pub struct Record<'exec, E> {
+pub struct PostgresRecord<'exec, E> {
   pub(crate) bytes: &'exec [u8],
   pub(crate) initial_value_offset: usize,
   pub(crate) phantom: PhantomData<fn() -> E>,
-  pub(crate) stmt: Statement<'exec>,
+  pub(crate) stmt: PostgresStatement<'exec>,
   pub(crate) values_bytes_offsets: &'exec [(bool, Range<usize>)],
 }
 
-impl<'exec, E> Record<'exec, E> {
+impl<'exec, E> PostgresRecord<'exec, E> {
   #[inline]
-  pub(crate) fn _new(
+  pub(crate) fn new(
     bytes: &'exec [u8],
     initial_value_offset: usize,
-    stmt: Statement<'exec>,
+    stmt: PostgresStatement<'exec>,
     values_bytes_offsets: &'exec [(bool, Range<usize>)],
   ) -> Self {
     Self { bytes, initial_value_offset, phantom: PhantomData, stmt, values_bytes_offsets }
@@ -31,13 +31,16 @@ impl<'exec, E> Record<'exec, E> {
   pub(crate) fn parse(
     mut bytes: &'exec [u8],
     bytes_range: Range<usize>,
-    stmt: Statement<'exec>,
+    stmt: PostgresStatement<'exec>,
     values_bytes_offsets: &'exec mut Vector<(bool, Range<usize>)>,
     values_len: u16,
   ) -> crate::Result<Self> {
-    let values_bytes_offsets_start = values_bytes_offsets.len();
-
-    let mut fun = |curr_value_offset: &mut usize, [a, b, c, d]: [u8; 4]| {
+    #[inline]
+    fn fun(
+      [a, b, c, d]: [u8; 4],
+      curr_value_offset: &mut usize,
+      values_bytes_offsets: &mut Vector<(bool, Range<usize>)>,
+    ) -> crate::Result<()> {
       let begin = *curr_value_offset;
       let n = i32::from_be_bytes([a, b, c, d]);
       let (is_null, end) = match n {
@@ -47,8 +50,9 @@ impl<'exec, E> Record<'exec, E> {
       values_bytes_offsets.push((is_null, begin..end))?;
       *curr_value_offset = end;
       crate::Result::Ok(())
-    };
+    }
 
+    let values_bytes_offsets_start = values_bytes_offsets.len();
     let initial_value_offset = bytes_range.start;
     let mut curr_value_offset = bytes_range.start;
 
@@ -56,7 +60,7 @@ impl<'exec, E> Record<'exec, E> {
     match (local_bytes, values_len) {
       (Some([a, b, c, d, rest @ ..]), 1..=u16::MAX) => {
         bytes = rest;
-        fun(&mut curr_value_offset, [*a, *b, *c, *d])?;
+        fun([*a, *b, *c, *d], &mut curr_value_offset, values_bytes_offsets)?;
       }
       _ => {
         return Ok(Self {
@@ -75,7 +79,7 @@ impl<'exec, E> Record<'exec, E> {
         return Err(PostgresError::InvalidPostgresRecord.into());
       };
       curr_value_offset = curr_value_offset.wrapping_add(4);
-      fun(&mut curr_value_offset, [a, b, c, d])?;
+      fun([a, b, c, d], &mut curr_value_offset, values_bytes_offsets)?;
     }
 
     Ok(Self {
@@ -90,7 +94,7 @@ impl<'exec, E> Record<'exec, E> {
   }
 }
 
-impl<'exec, E> crate::database::Record<'exec> for Record<'exec, E>
+impl<'exec, E> Record<'exec> for PostgresRecord<'exec, E>
 where
   E: From<crate::Error>,
 {
@@ -102,7 +106,7 @@ where
   }
 
   #[inline]
-  fn value<CI>(&self, ci: CI) -> Option<<Self::Database as Database>::DecodeValue<'exec>>
+  fn value<CI>(&self, ci: CI) -> Option<<Self::Database as DEController>::DecodeWrapper<'exec, '_>>
   where
     CI: ValueIdent<Self>,
   {
@@ -115,7 +119,7 @@ where
       None
     } else {
       let begin = range.start.wrapping_sub(self.initial_value_offset);
-      let column = match self.stmt.column(idx) {
+      let column = match self.stmt._column(idx) {
         None => return _unlikely_elem(None),
         Some(elem) => elem,
       };
@@ -124,19 +128,19 @@ where
         None => return _unlikely_elem(None),
         Some(elem) => elem,
       };
-      Some(DecodeValue::new(bytes, column.ty))
+      Some(DecodeWrapper::new(bytes, column.ty))
     }
   }
 }
 
-impl<'exec, E> ValueIdent<Record<'exec, E>> for str {
+impl<'exec, E> ValueIdent<PostgresRecord<'exec, E>> for str {
   #[inline]
-  fn idx(&self, input: &Record<'exec, E>) -> Option<usize> {
-    input.stmt.columns().position(|column| column.name.as_str() == self)
+  fn idx(&self, input: &PostgresRecord<'exec, E>) -> Option<usize> {
+    input.stmt._columns().position(|column| column.name.as_str() == self)
   }
 }
 
-impl<E> PartialEq for Record<'_, E> {
+impl<E> PartialEq for PostgresRecord<'_, E> {
   #[inline]
   fn eq(&self, other: &Self) -> bool {
     self.bytes == other.bytes
@@ -149,8 +153,8 @@ impl<E> PartialEq for Record<'_, E> {
 
 mod array {
   use crate::{
-    database::{client::postgres::Postgres, FromRecord, Record},
-    misc::{from_utf8_basic, into_rslt, ArrayString},
+    database::{FromRecord, Record, client::postgres::Postgres},
+    misc::{ArrayString, from_utf8_basic, into_rslt},
   };
 
   impl<E, const N: usize> FromRecord<Postgres<E>> for ArrayString<N>
@@ -159,7 +163,7 @@ mod array {
   {
     #[inline]
     fn from_record(
-      record: &crate::database::client::postgres::record::Record<'_, E>,
+      record: &crate::database::client::postgres::postgres_record::PostgresRecord<'_, E>,
     ) -> Result<Self, E> {
       Ok(from_utf8_basic(into_rslt(record.value(0))?.bytes()).map_err(From::from)?.try_into()?)
     }
@@ -170,24 +174,22 @@ mod array {
 mod tests {
   use crate::{
     database::{
+      Record as _,
       client::postgres::{
-        statements::statement::Statement,
+        DecodeWrapper, PostgresRecord, PostgresStatement, Ty,
         tests::{column0, column1, column2},
-        DecodeValue, Record, Ty,
       },
-      Record as _,
     },
     misc::Vector,
   };
-  use core::marker::PhantomData;
 
   #[test]
   fn returns_correct_values() {
     let bytes = &[0, 0, 0, 1, 1, 0, 0, 0, 2, 2, 3, 0, 0, 0, 1, 4];
     let values = &[(column0(), Ty::Any), (column1(), Ty::Any), (column2(), Ty::Any)];
     let mut values_bytes_offsets = Vector::new();
-    let stmt = Statement::new(3, 0, values);
-    let record = Record::<crate::Error>::parse(
+    let stmt = PostgresStatement::new((), 3, 0, values);
+    let record = PostgresRecord::<crate::Error>::parse(
       bytes,
       0..bytes.len(),
       stmt.clone(),
@@ -197,18 +199,17 @@ mod tests {
     .unwrap();
     assert_eq!(
       record,
-      Record {
-        bytes: &[1, 0, 0, 0, 2, 2, 3, 0, 0, 0, 1, 4],
-        initial_value_offset: 0,
+      PostgresRecord::new(
+        &[1, 0, 0, 0, 2, 2, 3, 0, 0, 0, 1, 4],
+        0,
         stmt,
-        values_bytes_offsets: &[(false, 0usize..1usize), (false, 5..7), (false, 11..12)],
-        phantom: PhantomData
-      }
+        &[(false, 0usize..1usize), (false, 5..7), (false, 11..12)],
+      )
     );
     assert_eq!(record.len(), 3);
-    assert_eq!(record.value(0), Some(DecodeValue::new(&[1][..], column0().ty)));
-    assert_eq!(record.value(1), Some(DecodeValue::new(&[2, 3][..], column1().ty)));
-    assert_eq!(record.value(2), Some(DecodeValue::new(&[4][..], column2().ty)));
+    assert_eq!(record.value(0), Some(DecodeWrapper::new(&[1][..], column0().ty)));
+    assert_eq!(record.value(1), Some(DecodeWrapper::new(&[2, 3][..], column1().ty)));
+    assert_eq!(record.value(2), Some(DecodeWrapper::new(&[4][..], column2().ty)));
     assert_eq!(record.value(3), None);
   }
 }
diff --git a/wtx/src/database/client/postgres/records.rs b/wtx/src/database/client/postgres/postgres_records.rs
similarity index 68%
rename from wtx/src/database/client/postgres/records.rs
rename to wtx/src/database/client/postgres/postgres_records.rs
index 9e54250e..c4ca6e5b 100644
--- a/wtx/src/database/client/postgres/records.rs
+++ b/wtx/src/database/client/postgres/postgres_records.rs
@@ -1,38 +1,41 @@
-use crate::database::client::postgres::{statements::statement::Statement, Postgres, Record};
+use crate::database::{
+  Records,
+  client::postgres::{Postgres, PostgresRecord, PostgresStatement},
+};
 use core::{marker::PhantomData, ops::Range};
 
 /// Records
 #[derive(Debug)]
-pub struct Records<'exec, E> {
+pub struct PostgresRecords<'exec, E> {
   pub(crate) bytes: &'exec [u8],
   pub(crate) phantom: PhantomData<fn() -> E>,
   /// Each element represents a record and an offset of `values_bytes_offsets`.
   pub(crate) records_values_offsets: &'exec [usize],
-  pub(crate) stmt: Statement<'exec>,
+  pub(crate) stmt: PostgresStatement<'exec>,
   /// Each element represents a value and an offset of `bytes`.
   pub(crate) values_bytes_offsets: &'exec [(bool, Range<usize>)],
 }
 
-impl<'exec, E> Records<'exec, E> {
+impl<'exec, E> PostgresRecords<'exec, E> {
   #[inline]
-  pub(crate) fn _new(
+  pub(crate) fn new(
     bytes: &'exec [u8],
     records_values_offsets: &'exec [usize],
-    stmt: Statement<'exec>,
+    stmt: PostgresStatement<'exec>,
     values_bytes_offsets: &'exec [(bool, Range<usize>)],
   ) -> Self {
     Self { bytes, phantom: PhantomData, records_values_offsets, stmt, values_bytes_offsets }
   }
 }
 
-impl<'exec, E> crate::database::Records<'exec> for Records<'exec, E>
+impl<'exec, E> Records<'exec> for PostgresRecords<'exec, E>
 where
   E: From<crate::Error>,
 {
   type Database = Postgres<E>;
 
   #[inline]
-  fn get(&self, record_idx: usize) -> Option<Record<'exec, E>> {
+  fn get(&self, record_idx: usize) -> Option<PostgresRecord<'exec, E>> {
     let slice = self.records_values_offsets.get(..record_idx.wrapping_add(1))?;
     let (record_bytes_range, record_values_bytes_offsets) = match slice {
       [] => return None,
@@ -51,17 +54,16 @@ where
       }
     };
     let initial_value_offset = record_bytes_range.start;
-    Some(Record {
-      bytes: self.bytes.get(record_bytes_range)?,
+    Some(PostgresRecord::new(
+      self.bytes.get(record_bytes_range)?,
       initial_value_offset,
-      stmt: self.stmt.clone(),
-      values_bytes_offsets: record_values_bytes_offsets,
-      phantom: PhantomData,
-    })
+      self.stmt.clone(),
+      record_values_bytes_offsets,
+    ))
   }
 
   #[inline]
-  fn iter(&self) -> impl Iterator<Item = Record<'exec, E>> {
+  fn iter(&self) -> impl Iterator<Item = PostgresRecord<'exec, E>> {
     (0..self.len()).filter_map(|idx| self.get(idx))
   }
 
@@ -71,14 +73,14 @@ where
   }
 }
 
-impl<E> Default for Records<'_, E> {
+impl<E> Default for PostgresRecords<'_, E> {
   #[inline]
   fn default() -> Self {
     Self {
       bytes: &[],
       phantom: PhantomData,
       records_values_offsets: &[],
-      stmt: Statement::default(),
+      stmt: PostgresStatement::default(),
       values_bytes_offsets: &[],
     }
   }
@@ -88,12 +90,11 @@ impl<E> Default for Records<'_, E> {
 mod tests {
   use crate::{
     database::{
+      Record as _, Records as _,
       client::postgres::{
-        statements::statement::Statement,
+        DecodeWrapper, PostgresRecord, PostgresRecords, PostgresStatement, Ty,
         tests::{column0, column1, column2},
-        DecodeValue, Record, Records, Ty,
       },
-      Record as _, Records as _,
     },
     misc::Vector,
   };
@@ -102,12 +103,12 @@ mod tests {
   fn returns_correct_values() {
     let bytes = &[0, 0, 0, 2, 1, 2, 0, 0, 0, 2, 3, 4, 9, 9, 9, 0, 1, 0, 0, 0, 4, 5, 6, 7, 8];
     let values = &[(column0(), Ty::Any), (column1(), Ty::Any), (column2(), Ty::Any)];
-    let stmt = Statement::new(3, 0, values);
+    let stmt = PostgresStatement::new((), 3, 0, values);
     let mut records_values_offsets = Vector::new();
     let mut values_bytes_offsets = Vector::new();
     assert_eq!(
-      Record::parse(bytes, 0..12, stmt.clone(), &mut values_bytes_offsets, 2).unwrap(),
-      Record::<crate::Error>::_new(
+      PostgresRecord::parse(bytes, 0..12, stmt.clone(), &mut values_bytes_offsets, 2).unwrap(),
+      PostgresRecord::<crate::Error>::new(
         &[1, 2, 0, 0, 0, 2, 3, 4],
         0,
         stmt.clone(),
@@ -116,12 +117,12 @@ mod tests {
     );
     records_values_offsets.push(values_bytes_offsets.len()).unwrap();
     assert_eq!(
-      Record::parse(bytes, 17..25, stmt.clone(), &mut values_bytes_offsets, 1).unwrap(),
-      Record::<crate::Error>::_new(&[5, 6, 7, 8], 17, stmt.clone(), &[(false, 17..21)])
+      PostgresRecord::parse(bytes, 17..25, stmt.clone(), &mut values_bytes_offsets, 1).unwrap(),
+      PostgresRecord::<crate::Error>::new(&[5, 6, 7, 8], 17, stmt.clone(), &[(false, 17..21)])
     );
     records_values_offsets.push(values_bytes_offsets.len()).unwrap();
 
-    let records = Records::<crate::Error>::_new(
+    let records = PostgresRecords::<crate::Error>::new(
       &bytes[4..],
       &records_values_offsets,
       stmt.clone(),
@@ -135,18 +136,21 @@ mod tests {
     let first_record = records.get(0).unwrap();
     assert_eq!(
       &first_record,
-      &Record::<crate::Error>::_new(
+      &PostgresRecord::<crate::Error>::new(
         &[1, 2, 0, 0, 0, 2, 3, 4],
         0,
         stmt.clone(),
         &[(false, 0..2), (false, 6..8)]
       )
     );
-    assert_eq!(first_record.value(0).unwrap(), DecodeValue::new(&[1, 2], column0().ty));
-    assert_eq!(first_record.value(1).unwrap(), DecodeValue::new(&[3, 4], column1().ty));
+    assert_eq!(first_record.value(0).unwrap(), DecodeWrapper::new(&[1, 2], column0().ty));
+    assert_eq!(first_record.value(1).unwrap(), DecodeWrapper::new(&[3, 4], column1().ty));
 
     let second_record = records.get(1).unwrap();
-    assert_eq!(&second_record, &Record::_new(&[5, 6, 7, 8], 17, stmt.clone(), &[(false, 17..21)]));
+    assert_eq!(
+      &second_record,
+      &PostgresRecord::new(&[5, 6, 7, 8], 17, stmt.clone(), &[(false, 17..21)])
+    );
 
     assert_eq!(records.iter().count(), 2);
   }
diff --git a/wtx/src/database/client/postgres/protocol.rs b/wtx/src/database/client/postgres/protocol.rs
index 6cfc6848..00332ca5 100644
--- a/wtx/src/database/client/postgres/protocol.rs
+++ b/wtx/src/database/client/postgres/protocol.rs
@@ -1,52 +1,58 @@
 use crate::{
   database::{
-    client::postgres::{
-      statements::statement::Statement, Config, EncodeValue, Oid, Postgres, PostgresError,
-    },
     RecordValues,
+    client::postgres::{Config, EncodeWrapper, Oid, Postgres, PostgresError, PostgresStatement},
+  },
+  misc::{
+    SuffixWriterFbvm, Vector,
+    counter_writer::{CounterWriter, I16Counter, I32Counter},
   },
-  misc::{FilledBufferWriter, Vector},
 };
-use base64::{engine::general_purpose::STANDARD, Engine};
-use hmac::{digest::FixedOutput, Hmac, Mac};
+use base64::{Engine, engine::general_purpose::STANDARD};
+use hmac::{Hmac, Mac, digest::FixedOutput};
 use sha2::{Digest, Sha256};
 
 #[inline]
 pub(crate) fn bind<E, RV>(
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
   portal: &str,
-  mut rv: RV,
-  _: &Statement<'_>,
-  stmt_id_str: &str,
+  rv: RV,
+  _: &PostgresStatement<'_>,
+  stmt_cmd_id_array: &[u8],
 ) -> Result<(), E>
 where
   E: From<crate::Error>,
   RV: RecordValues<Postgres<E>>,
 {
-  write(fbw, true, Some(b'B'), |local_fbw| {
-    local_fbw._extend_from_slices_each_c(&[portal.as_bytes(), stmt_id_str.as_bytes()])?;
+  I32Counter::default().write(sw, true, Some(b'B'), |local_sw| {
+    local_sw._extend_from_slices_each_c(&[portal.as_bytes(), stmt_cmd_id_array])?;
     let rv_len = rv.len();
 
-    write_iter(local_fbw, (0..rv_len).map(|_| 1i16), None, |elem, local_local_fbw| {
-      local_local_fbw.extend_from_slice(&elem.to_be_bytes())?;
-      Ok(())
-    })?;
+    I16Counter::default().write_iter(
+      local_sw,
+      (0..rv_len).map(|_| 1i16),
+      None,
+      |elem, local_local_sw| {
+        local_local_sw.extend_from_slice(&elem.to_be_bytes())?;
+        Ok(())
+      },
+    )?;
 
     {
-      local_fbw.extend_from_slice(&i16::try_from(rv_len).map_err(Into::into)?.to_be_bytes())?;
+      local_sw.extend_from_slice(&i16::try_from(rv_len).map_err(Into::into)?.to_be_bytes())?;
       let mut aux = (0usize, 0);
       let _ = rv.encode_values(
         &mut aux,
-        &mut EncodeValue::new(local_fbw),
+        &mut EncodeWrapper::new(local_sw),
         |(counter, start), local_ev| {
           *counter = counter.wrapping_add(1);
-          *start = local_ev.fbw()._len();
-          let _rslt = local_ev.fbw().extend_from_slice(&[0; 4]);
+          *start = local_ev.sw()._len();
+          let _rslt = local_ev.sw().extend_from_slice(&[0; 4]);
           4
         },
         |(_, start), local_ev, is_null, elem_len| {
           let written = if is_null { -1i32 } else { i32::try_from(elem_len).unwrap_or(i32::MAX) };
-          let bytes_opt = local_ev.fbw()._curr_bytes_mut().get_mut(*start..);
+          let bytes_opt = local_ev.sw()._curr_bytes_mut().get_mut(*start..);
           if let Some([a0, b0, c0, d0, ..]) = bytes_opt {
             let [a1, b1, c1, d1] = written.to_be_bytes();
             *a0 = a1;
@@ -62,8 +68,8 @@ where
       }
     }
 
-    write_iter(local_fbw, &[1i16], None, |elem, local_local_fbw| {
-      local_local_fbw.extend_from_slice(&elem.to_be_bytes())?;
+    I16Counter::default().write_iter(local_sw, &[1i16], None, |elem, local_local_sw| {
+      local_local_sw.extend_from_slice(&elem.to_be_bytes())?;
       Ok(())
     })?;
 
@@ -73,34 +79,34 @@ where
 
 #[inline]
 pub(crate) fn describe(
-  data: &str,
-  fbw: &mut FilledBufferWriter<'_>,
+  data: &[u8],
+  sw: &mut SuffixWriterFbvm<'_>,
   variant: u8,
 ) -> crate::Result<()> {
-  write(fbw, true, Some(b'D'), |local_fbw| {
-    local_fbw._extend_from_byte(variant)?;
-    local_fbw._extend_from_slice_c(data.as_bytes())?;
+  I32Counter::default().write(sw, true, Some(b'D'), |local_sw| {
+    local_sw._extend_from_byte(variant)?;
+    local_sw._extend_from_slice_c(data)?;
     Ok(())
   })
 }
 
 #[inline]
-pub(crate) fn encrypted_conn(fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
-  write(fbw, true, None, |local_fbw| {
-    local_fbw.extend_from_slice(&0b0000_0100_1101_0010_0001_0110_0010_1111i32.to_be_bytes())?;
+pub(crate) fn encrypted_conn(sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
+  I32Counter::default().write(sw, true, None, |local_sw| {
+    local_sw.extend_from_slice(&0b0000_0100_1101_0010_0001_0110_0010_1111i32.to_be_bytes())?;
     Ok::<_, crate::Error>(())
   })
 }
 
 #[inline]
 pub(crate) fn execute(
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
   max_rows: i32,
   portal: &str,
 ) -> crate::Result<()> {
-  write(fbw, true, Some(b'E'), |local_fbw| {
-    local_fbw._extend_from_slice_c(portal.as_bytes())?;
-    local_fbw.extend_from_slice(&max_rows.to_be_bytes())?;
+  I32Counter::default().write(sw, true, Some(b'E'), |local_sw| {
+    local_sw._extend_from_slice_c(portal.as_bytes())?;
+    local_sw.extend_from_slice(&max_rows.to_be_bytes())?;
     Ok::<_, crate::Error>(())
   })
 }
@@ -108,16 +114,17 @@ pub(crate) fn execute(
 #[inline]
 pub(crate) fn initial_conn_msg(
   config: &Config<'_>,
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
 ) -> crate::Result<()> {
-  write(fbw, true, None, |local_fbw| {
-    local_fbw.extend_from_slice(&0b11_0000_0000_0000_0000i32.to_be_bytes())?;
-    local_fbw._extend_from_slices_each_c(&[b"user", config.user.as_bytes()])?;
-    local_fbw._extend_from_slices_each_c(&[b"database", config.db.as_bytes()])?;
-    if !config.app_name.is_empty() {
-      local_fbw._extend_from_slices_each_c(&[b"application_name", config.app_name.as_bytes()])?;
+  I32Counter::default().write(sw, true, None, |local_sw| {
+    local_sw.extend_from_slice(&0b11_0000_0000_0000_0000i32.to_be_bytes())?;
+    local_sw._extend_from_slices_each_c(&[b"user", config.user.as_bytes()])?;
+    local_sw._extend_from_slices_each_c(&[b"database", config.db.as_bytes()])?;
+    if !config.application_name.is_empty() {
+      local_sw
+        ._extend_from_slices_each_c(&[b"application_name", config.application_name.as_bytes()])?;
     }
-    local_fbw._extend_from_slices_each_c(&[
+    local_sw._extend_from_slices_each_c(&[
       b"client_encoding",
       b"UTF8",
       b"DateStyle",
@@ -125,7 +132,7 @@ pub(crate) fn initial_conn_msg(
       b"TimeZone",
       b"UTC",
     ])?;
-    local_fbw._extend_from_slice_c(b"")?;
+    local_sw._extend_from_slice_c(b"")?;
     Ok::<_, crate::Error>(())
   })
 }
@@ -133,39 +140,39 @@ pub(crate) fn initial_conn_msg(
 #[inline]
 pub(crate) fn parse(
   cmd: &str,
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
   iter: impl IntoIterator<Item = Oid>,
-  name: &str,
+  name: &[u8],
 ) -> crate::Result<()> {
-  write(fbw, true, Some(b'P'), |local_fbw| {
-    local_fbw._extend_from_slices_each_c(&[name.as_bytes(), cmd.as_bytes()])?;
-    write_iter(local_fbw, iter, None, |ty, local_local_fbw| {
-      local_local_fbw.extend_from_slice(&ty.to_be_bytes())?;
+  I32Counter::default().write(sw, true, Some(b'P'), |local_sw| {
+    local_sw._extend_from_slices_each_c(&[name, cmd.as_bytes()])?;
+    I16Counter::default().write_iter(local_sw, iter, None, |ty, local_local_sw| {
+      local_local_sw.extend_from_slice(&ty.to_be_bytes())?;
       Ok(())
     })
   })
 }
 
 #[inline]
-pub(crate) fn query(cmd: &[u8], fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
-  write(fbw, true, Some(b'Q'), |local_fbw| {
-    local_fbw._extend_from_slice_c(cmd)?;
+pub(crate) fn query(cmd: &[u8], sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
+  I32Counter::default().write(sw, true, Some(b'Q'), |local_sw| {
+    local_sw._extend_from_slice_c(cmd)?;
     Ok::<_, crate::Error>(())
   })
 }
 
 #[inline]
 pub(crate) fn sasl_first(
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
   (method_bytes, method_header): (&[u8], &[u8]),
   nonce: &[u8],
 ) -> crate::Result<()> {
-  write(fbw, true, Some(b'p'), |local_fbw| {
-    local_fbw._extend_from_slice_c(method_bytes)?;
-    write(local_fbw, false, None, |local_local_fbw| {
-      local_local_fbw.extend_from_slice(method_header)?;
-      local_local_fbw.extend_from_slice(b"n=,r=")?;
-      local_local_fbw.extend_from_slice(nonce)?;
+  I32Counter::default().write(sw, true, Some(b'p'), |local_sw| {
+    local_sw._extend_from_slice_c(method_bytes)?;
+    I32Counter::default().write(local_sw, false, None, |local_local_sw| {
+      local_local_sw.extend_from_slice(method_header)?;
+      local_local_sw.extend_from_slice(b"n=,r=")?;
+      local_local_sw.extend_from_slice(nonce)?;
       Ok::<_, crate::Error>(())
     })
   })?;
@@ -175,25 +182,23 @@ pub(crate) fn sasl_first(
 #[inline]
 pub(crate) fn sasl_second(
   auth_data: &mut Vector<u8>,
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
   method_header: &[u8],
   response_nonce: &[u8],
   salted_password: &[u8; 32],
   tls_server_end_point: &[u8],
 ) -> crate::Result<()> {
-  write(fbw, true, Some(b'p'), |local_fbw| {
-    local_fbw.extend_from_slice(b"c=")?;
-    {
-      let n = STANDARD.encode_slice(method_header, local_fbw._remaining_bytes_mut())?;
-      local_fbw._shift_idx(n)?;
-    }
-    {
-      let n = STANDARD.encode_slice(tls_server_end_point, local_fbw._remaining_bytes_mut())?;
-      local_fbw._shift_idx(n)?;
-    }
-    local_fbw._extend_from_slices([b",r=", response_nonce])?;
+  I32Counter::default().write(sw, true, Some(b'p'), |local_sw| {
+    local_sw.extend_from_slice(b"c=")?;
+    local_sw._create_buffer(method_header.len().wrapping_mul(2), |slice| {
+      Ok(STANDARD.encode_slice(method_header, slice)?)
+    })?;
+    local_sw._create_buffer(tls_server_end_point.len().wrapping_mul(2), |slice| {
+      Ok(STANDARD.encode_slice(tls_server_end_point, slice)?)
+    })?;
+    local_sw._extend_from_slices([b",r=", response_nonce])?;
 
-    let local_bytes = local_fbw._curr_bytes().get(5..).unwrap_or_default();
+    let local_bytes = local_sw._curr_bytes().get(5..).unwrap_or_default();
     let _ = auth_data.extend_from_copyable_slices([&b","[..], local_bytes])?;
 
     let client_key: [u8; 32] = {
@@ -217,12 +222,10 @@ pub(crate) fn sasl_second(
     for (proof, signature) in client_proof.iter_mut().zip(client_signature) {
       *proof ^= signature;
     }
-
-    {
-      local_fbw.extend_from_slice(b",p=")?;
-      let n = STANDARD.encode_slice(client_proof, local_fbw._remaining_bytes_mut())?;
-      local_fbw._shift_idx(n)?;
-    }
+    local_sw.extend_from_slice(b",p=")?;
+    local_sw._create_buffer(client_proof.len().wrapping_mul(2), |slice| {
+      Ok(STANDARD.encode_slice(client_proof, slice)?)
+    })?;
 
     Ok::<_, crate::Error>(())
   })?;
@@ -230,69 +233,6 @@ pub(crate) fn sasl_second(
 }
 
 #[inline]
-pub(crate) fn sync(fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
-  write(fbw, true, Some(b'S'), |_| Ok::<_, crate::Error>(()))
-}
-
-#[inline]
-pub(crate) fn write<'buffer, E>(
-  fbw: &mut FilledBufferWriter<'buffer>,
-  include_len: bool,
-  prefix: Option<u8>,
-  cb: impl FnOnce(&mut FilledBufferWriter<'buffer>) -> Result<(), E>,
-) -> Result<(), E>
-where
-  E: From<crate::Error>,
-{
-  if let Some(elem) = prefix {
-    fbw._extend_from_byte(elem)?;
-  }
-  let (len_before, start) = if include_len {
-    let len = fbw._len();
-    fbw.extend_from_slice(&[0; 4])?;
-    (len, len)
-  } else {
-    let start = fbw._len();
-    fbw.extend_from_slice(&[0; 4])?;
-    (fbw._len(), start)
-  };
-  cb(fbw)?;
-  let written = fbw._len().wrapping_sub(len_before);
-  let [a1, b1, c1, d1] = i32::try_from(written).map_err(Into::into)?.to_be_bytes();
-  if let Some([a0, b0, c0, d0, ..]) = fbw._curr_bytes_mut().get_mut(start..) {
-    *a0 = a1;
-    *b0 = b1;
-    *c0 = c1;
-    *d0 = d1;
-  }
-  Ok(())
-}
-
-#[inline]
-pub(crate) fn write_iter<E, T>(
-  fbw: &mut FilledBufferWriter<'_>,
-  iter: impl IntoIterator<Item = T>,
-  prefix: Option<u8>,
-  mut cb: impl FnMut(T, &mut FilledBufferWriter<'_>) -> Result<(), E>,
-) -> Result<(), E>
-where
-  E: From<crate::Error>,
-{
-  if let Some(elem) = prefix {
-    fbw._extend_from_byte(elem)?;
-  }
-  let len_before = fbw._len();
-  fbw.extend_from_slice(&[0; 2])?;
-  let mut counter: usize = 0;
-  for elem in iter.into_iter().take(u16::MAX.into()) {
-    cb(elem, fbw)?;
-    counter = counter.wrapping_add(1);
-  }
-  let bytes = fbw._curr_bytes_mut();
-  if let Some([a0, b0, ..]) = bytes.get_mut(len_before..) {
-    let [a1, b1] = i16::try_from(counter).map_err(Into::into)?.to_be_bytes();
-    *a0 = a1;
-    *b0 = b1;
-  }
-  Ok(())
+pub(crate) fn sync(sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
+  I32Counter::default().write(sw, true, Some(b'S'), |_| Ok::<_, crate::Error>(()))
 }
diff --git a/wtx/src/database/client/postgres/statements.rs b/wtx/src/database/client/postgres/statements.rs
deleted file mode 100644
index dd21edb4..00000000
--- a/wtx/src/database/client/postgres/statements.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-pub(crate) mod column;
-pub(crate) mod statement;
-pub(crate) mod statement_builder;
-pub(crate) mod statements_misc;
-
-use crate::{
-  database::client::postgres::ty::Ty,
-  misc::{BlocksDeque, Rng, _random_state},
-};
-use foldhash::fast::FixedState;
-use hashbrown::HashMap;
-
-/// Statements
-#[derive(Debug)]
-pub struct Statements {
-  max_stmts: usize,
-  rs: FixedState,
-  stmts: BlocksDeque<(column::Column, Ty), statements_misc::StatementsMisc>,
-  stmts_indcs: HashMap<u64, usize>,
-}
-
-impl Statements {
-  #[inline]
-  pub(crate) fn new<RNG>(max_stmts: usize, rng: RNG) -> Self
-  where
-    RNG: Rng,
-  {
-    Self {
-      max_stmts: max_stmts.max(1),
-      rs: _random_state(rng),
-      stmts: BlocksDeque::new(),
-      stmts_indcs: HashMap::new(),
-    }
-  }
-
-  #[inline]
-  pub(crate) fn with_capacity<RNG>(
-    columns: usize,
-    max_stmts: usize,
-    rng: RNG,
-    stmts: usize,
-  ) -> crate::Result<Self>
-  where
-    RNG: Rng,
-  {
-    Ok(Self {
-      max_stmts: max_stmts.max(1),
-      rs: _random_state(rng),
-      stmts: BlocksDeque::with_capacity(stmts, columns)?,
-      stmts_indcs: HashMap::with_capacity(stmts),
-    })
-  }
-
-  #[inline]
-  pub(crate) fn builder(&mut self) -> statement_builder::StatementBuilder<'_> {
-    if self.stmts.blocks_len() >= self.max_stmts {
-      let to_remove = (self.max_stmts / 2).max(1);
-      for _ in 0..to_remove {
-        let _ = self.stmts.pop_front();
-      }
-      self.stmts_indcs.retain(|_, value| {
-        if *value < to_remove {
-          return false;
-        }
-        *value = value.wrapping_sub(to_remove);
-        true
-      })
-    }
-    statement_builder::StatementBuilder::new(&mut self.stmts, &mut self.stmts_indcs)
-  }
-
-  #[inline]
-  pub(crate) fn clear(&mut self) {
-    let Self { max_stmts: _, rs: _, stmts, stmts_indcs } = self;
-    stmts.clear();
-    stmts_indcs.clear();
-  }
-
-  #[inline]
-  pub(crate) fn get_by_idx(&self, idx: usize) -> Option<statement::Statement<'_>> {
-    let stmt = self.stmts.get(idx)?;
-    Some(statement::Statement::new(stmt.misc.columns_len, stmt.misc.types_len, stmt.data))
-  }
-
-  #[inline]
-  pub(crate) fn get_by_stmt_hash(&self, stmt_hash: u64) -> Option<statement::Statement<'_>> {
-    self.get_by_idx(*self.stmts_indcs.get(&stmt_hash)?)
-  }
-
-  #[inline]
-  pub(crate) fn hasher_mut(&mut self) -> &mut FixedState {
-    &mut self.rs
-  }
-}
-
-#[cfg(test)]
-mod tests {
-  use crate::{
-    database::client::postgres::{
-      statements::statements_misc::StatementsMisc,
-      tests::{column0, column1, column2, column3},
-      ty::Ty,
-      Statements,
-    },
-    misc::{simple_seed, Xorshift64},
-  };
-
-  // FIXME(MIRI): The modification of the vector's length makes MIRI think that there is an
-  // invalid pointer using stacked borrows.
-  //
-  // | A | B |   | <- Push back one block of 2 elements. Length is 2
-  // | A | B | C | <- Push back one block of 1 element. Length is 3
-  // |   |   | C | <- Pop front one block. Length is 1
-  //
-  // Such behaviour does not occur with "miri-tree-borrows".
-  #[cfg_attr(miri, ignore)]
-  #[test]
-  fn two_statements() {
-    let mut stmts = Statements::new(2, &mut Xorshift64::from(simple_seed()));
-
-    let stmt_id0 = 123;
-    let mut builder = stmts.builder();
-    let _ = builder.expand(2).unwrap();
-    builder.inserted_elements()[0] = (column0(), Ty::Int2);
-    builder.inserted_elements()[1] = (column1(), Ty::Int2);
-    let _ = builder.build(stmt_id0, StatementsMisc::new(2, 1)).unwrap();
-    {
-      let stmt = stmts.get_by_stmt_hash(stmt_id0).unwrap();
-      assert_eq!(stmt.columns().count(), 2);
-      assert_eq!(stmt.column(0).unwrap(), &column0());
-      assert_eq!(stmt.column(1).unwrap(), &column1());
-      assert_eq!(stmt.tys().count(), 1);
-      assert_eq!(stmt.ty(0).unwrap(), Ty::Int2);
-    }
-
-    let stmt_id1 = 456;
-    let mut builder = stmts.builder();
-    let _ = builder.expand(1).unwrap();
-    builder.inserted_elements()[0] = (column2(), Ty::Int4);
-    let _ = builder.build(stmt_id1, StatementsMisc::new(1, 1)).unwrap();
-    {
-      let stmt = stmts.get_by_stmt_hash(stmt_id0).unwrap();
-      assert_eq!(stmt.columns().count(), 2);
-      assert_eq!(stmt.column(0).unwrap(), &column0());
-      assert_eq!(stmt.column(1).unwrap(), &column1());
-      assert_eq!(stmt.tys().count(), 1);
-      assert_eq!(stmt.ty(0).unwrap(), Ty::Int2);
-    }
-    {
-      let stmt = stmts.get_by_stmt_hash(stmt_id1).unwrap();
-      assert_eq!(stmt.columns().count(), 1);
-      assert_eq!(stmt.column(0).unwrap(), &column2());
-      assert_eq!(stmt.tys().count(), 1);
-      assert_eq!(stmt.ty(0).unwrap(), Ty::Int4);
-    }
-
-    let stmt_id2 = 789;
-    let mut builder = stmts.builder();
-    let _ = builder.expand(1).unwrap();
-    builder.inserted_elements()[0].0 = column3();
-    let _ = builder.build(stmt_id2, StatementsMisc::new(1, 0)).unwrap();
-    assert_eq!(stmts.get_by_stmt_hash(stmt_id0), None);
-    {
-      let stmt = stmts.get_by_stmt_hash(stmt_id1).unwrap();
-      assert_eq!(stmt.columns().count(), 1);
-      assert_eq!(stmt.column(0).unwrap(), &column2());
-      assert_eq!(stmt.tys().count(), 1);
-      assert_eq!(stmt.ty(0).unwrap(), Ty::Int4);
-    }
-    {
-      let stmt = stmts.get_by_stmt_hash(stmt_id2).unwrap();
-      assert_eq!(stmt.columns().count(), 1);
-      assert_eq!(stmt.column(0).unwrap(), &column3());
-      assert_eq!(stmt.tys().count(), 0);
-    }
-
-    stmts.clear();
-    assert_eq!(stmts.get_by_stmt_hash(stmt_id0), None);
-    assert_eq!(stmts.get_by_stmt_hash(stmt_id1), None);
-    assert_eq!(stmts.get_by_stmt_hash(stmt_id2), None);
-  }
-}
diff --git a/wtx/src/database/client/postgres/statements/statement.rs b/wtx/src/database/client/postgres/statements/statement.rs
deleted file mode 100644
index 4ba23ed7..00000000
--- a/wtx/src/database/client/postgres/statements/statement.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use crate::database::client::postgres::{statements::column::Column, Ty};
-
-/// ```sql
-/// SELECT a,b,c,d FROM table WHERE e = $1 AND f = $2
-/// ```
-///
-/// The columns are "a", "b", "c", "d" and the types are "$1" and "$2".
-#[derive(Clone, Debug, Default, Eq, PartialEq)]
-pub(crate) struct Statement<'stmts> {
-  columns_len: usize,
-  tys_len: usize,
-  values: &'stmts [(Column, Ty)],
-}
-
-impl<'stmts> Statement<'stmts> {
-  #[inline]
-  pub(crate) const fn new(
-    columns_len: usize,
-    tys_len: usize,
-    values: &'stmts [(Column, Ty)],
-  ) -> Self {
-    Self { columns_len, tys_len, values }
-  }
-
-  #[inline]
-  pub(crate) fn column(&self, idx: usize) -> Option<&Column> {
-    let columns = self.values.get(..self.columns_len)?;
-    Some(&columns.get(idx)?.0)
-  }
-
-  #[inline]
-  pub(crate) fn columns(&self) -> impl Iterator<Item = &Column> {
-    let columns = self.values.get(..self.columns_len).unwrap_or_default();
-    columns.iter().map(|el| &el.0)
-  }
-
-  #[cfg(test)]
-  #[inline]
-  pub(crate) fn ty(&self, idx: usize) -> Option<Ty> {
-    Some(self.values.get(..self.tys_len)?.get(idx)?.1)
-  }
-
-  #[cfg(test)]
-  #[inline]
-  pub(crate) fn tys(&self) -> impl Iterator<Item = &Ty> {
-    self.values.get(..self.tys_len).unwrap_or_default().iter().map(|el| &el.1)
-  }
-}
diff --git a/wtx/src/database/client/postgres/statements/statements_misc.rs b/wtx/src/database/client/postgres/statements/statements_misc.rs
deleted file mode 100644
index dc114ea6..00000000
--- a/wtx/src/database/client/postgres/statements/statements_misc.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#[derive(Debug)]
-pub(crate) struct StatementsMisc {
-  pub(crate) columns_len: usize,
-  pub(crate) types_len: usize,
-}
-
-impl StatementsMisc {
-  #[inline]
-  pub(crate) fn new(columns_len: usize, types_len: usize) -> Self {
-    Self { columns_len, types_len }
-  }
-}
diff --git a/wtx/src/database/client/postgres/struct_decoder.rs b/wtx/src/database/client/postgres/struct_decoder.rs
index ab9efb8f..f71be74f 100644
--- a/wtx/src/database/client/postgres/struct_decoder.rs
+++ b/wtx/src/database/client/postgres/struct_decoder.rs
@@ -1,27 +1,24 @@
 use crate::{
-  database::{
-    client::postgres::{DecodeValue, Postgres, PostgresError, Ty},
-    Decode,
-  },
-  misc::Usize,
+  database::client::postgres::{DecodeWrapper, Postgres, PostgresError, Ty},
+  misc::{Decode, Usize},
 };
 use core::marker::PhantomData;
 
 /// Decodes a custom PostgreSQL type that represents a table into a Rust struct.
 #[derive(Debug)]
-pub struct StructDecoder<'any, E> {
-  bytes: &'any [u8],
+pub struct StructDecoder<'de, E> {
+  bytes: &'de [u8],
   phantom: PhantomData<fn() -> E>,
 }
 
-impl<'any, E> StructDecoder<'any, E>
+impl<'de, E> StructDecoder<'de, E>
 where
   E: From<crate::Error>,
 {
   /// Decodes initial data.
   #[inline]
-  pub fn new(dv: &DecodeValue<'any>) -> Self {
-    let bytes = if let [_, _, _, _, rest @ ..] = dv.bytes() { rest } else { dv.bytes() };
+  pub fn new(dw: &mut DecodeWrapper<'de>) -> Self {
+    let bytes = if let [_, _, _, _, rest @ ..] = dw.bytes() { rest } else { dw.bytes() };
     Self { bytes, phantom: PhantomData }
   }
 
@@ -30,7 +27,7 @@ where
   #[inline]
   pub fn decode<T>(&mut self) -> Result<T, E>
   where
-    T: Decode<'any, Postgres<E>>,
+    T: Decode<'de, Postgres<E>>,
   {
     Ok(self.decode_opt()?.ok_or_else(|| PostgresError::DecodingError.into())?)
   }
@@ -40,7 +37,7 @@ where
   #[inline]
   pub fn decode_opt<T>(&mut self) -> Result<Option<T>, E>
   where
-    T: Decode<'any, Postgres<E>>,
+    T: Decode<'de, Postgres<E>>,
   {
     let [a, b, c, d, e, f, g, h, rest @ ..] = self.bytes else {
       return Ok(None);
@@ -53,6 +50,6 @@ where
       return Ok(None);
     };
     self.bytes = after;
-    Ok(Some(T::decode(&DecodeValue::new(before, ty))?))
+    Ok(Some(T::decode(&mut (), &mut DecodeWrapper::new(before, ty))?))
   }
 }
diff --git a/wtx/src/database/client/postgres/struct_encoder.rs b/wtx/src/database/client/postgres/struct_encoder.rs
index 09f1c7d1..b06bdb59 100644
--- a/wtx/src/database/client/postgres/struct_encoder.rs
+++ b/wtx/src/database/client/postgres/struct_encoder.rs
@@ -1,28 +1,31 @@
-use crate::database::{
-  client::postgres::{EncodeValue, Postgres, Ty},
-  Encode, Typed,
+use crate::{
+  database::{
+    Typed,
+    client::postgres::{EncodeWrapper, Postgres, Ty},
+  },
+  misc::Encode,
 };
 use core::marker::PhantomData;
 
 /// Encodes a Rust struct into a custom PostgreSQL type that represents a table.
 #[derive(Debug)]
-pub struct StructEncoder<'buffer, 'ev, 'tmp, E> {
-  ev: &'ev mut EncodeValue<'buffer, 'tmp>,
+pub struct StructEncoder<'buffer, 'ew, 'tmp, E> {
+  ew: &'ew mut EncodeWrapper<'buffer, 'tmp>,
   len: u32,
   phantom: PhantomData<fn() -> E>,
   start: usize,
 }
 
-impl<'buffer, 'ev, 'tmp, E> StructEncoder<'buffer, 'ev, 'tmp, E>
+impl<'buffer, 'ew, 'tmp, E> StructEncoder<'buffer, 'ew, 'tmp, E>
 where
   E: From<crate::Error>,
 {
   /// Pushes initial encoding data.
   #[inline]
-  pub fn new(ev: &'ev mut EncodeValue<'buffer, 'tmp>) -> Result<Self, E> {
-    let start = ev.fbw()._len();
-    ev.fbw().extend_from_slice(&[0; 4])?;
-    Ok(Self { ev, len: 0, phantom: PhantomData, start })
+  pub fn new(ew: &'ew mut EncodeWrapper<'buffer, 'tmp>) -> Result<Self, E> {
+    let start = ew.sw()._len();
+    ew.sw().extend_from_slice(&[0; 4])?;
+    Ok(Self { ew, len: 0, phantom: PhantomData, start })
   }
 
   /// Encodes `value` with the [`Ty`] originated from [`Typed`].
@@ -40,16 +43,16 @@ where
   where
     T: Encode<Postgres<E>>,
   {
-    self.ev.fbw().extend_from_slice(&u32::from(ty).to_be_bytes())?;
+    self.ew.sw().extend_from_slice(&u32::from(ty).to_be_bytes())?;
     if value.is_null() {
-      self.ev.fbw().extend_from_slice(&(-1i32).to_be_bytes())?;
+      self.ew.sw().extend_from_slice(&(-1i32).to_be_bytes())?;
     } else {
-      let len_start = self.ev.fbw()._len();
-      self.ev.fbw().extend_from_slice(&[0; 4])?;
-      let elem_start = self.ev.fbw()._len();
-      value.encode(self.ev)?;
-      let len = self.ev.fbw()._len().wrapping_sub(elem_start).try_into().unwrap_or_default();
-      write_len(self.ev, len_start, len);
+      let len_start = self.ew.sw()._len();
+      self.ew.sw().extend_from_slice(&[0; 4])?;
+      let elem_start = self.ew.sw()._len();
+      value.encode(&mut (), self.ew)?;
+      let len = self.ew.sw()._len().wrapping_sub(elem_start).try_into().unwrap_or_default();
+      write_len(self.ew, len_start, len);
     }
     self.len = self.len.wrapping_add(1);
     Ok(self)
@@ -59,13 +62,13 @@ where
 impl<E> Drop for StructEncoder<'_, '_, '_, E> {
   #[inline]
   fn drop(&mut self) {
-    write_len(self.ev, self.start, self.len);
+    write_len(self.ew, self.start, self.len);
   }
 }
 
 #[inline]
-fn write_len(ev: &mut EncodeValue<'_, '_>, start: usize, len: u32) {
-  let Some([a, b, c, d, ..]) = ev.fbw()._curr_bytes_mut().get_mut(start..) else {
+fn write_len(ew: &mut EncodeWrapper<'_, '_>, start: usize, len: u32) {
+  let Some([a, b, c, d, ..]) = ew.sw()._curr_bytes_mut().get_mut(start..) else {
     return;
   };
   let [e, f, g, h] = len.to_be_bytes();
diff --git a/wtx/src/database/client/postgres/tys.rs b/wtx/src/database/client/postgres/tys.rs
index 53ee02a0..718582c7 100644
--- a/wtx/src/database/client/postgres/tys.rs
+++ b/wtx/src/database/client/postgres/tys.rs
@@ -5,11 +5,11 @@ macro_rules! kani {
     fn $name(instance: $ty) {
       let mut vec = &mut crate::misc::FilledBuffer::_new();
       {
-        let mut fbw = crate::misc::FilledBufferWriter::new(0, &mut vec);
-        let mut ev = EncodeValue::new(&mut fbw);
-        Encode::<Postgres<crate::Error>>::encode(&instance, &mut ev).unwrap();
+        let mut sw = crate::misc::FilledBufferWriter::new(0, &mut vec);
+        let mut ew = EncodeValue::new(&mut sw);
+        Encode::<Postgres<crate::Error>>::encode(&instance, &mut ew).unwrap();
         let decoded: $ty = Decode::<Postgres<crate::Error>>::decode(&DecodeValue::new(
-          ev.fbw()._curr_bytes(),
+          ew.sw()._curr_bytes(),
           crate::database::client::postgres::Ty::Any,
         ))
         .unwrap();
@@ -25,28 +25,37 @@ macro_rules! test {
     #[cfg(test)]
     #[test]
     fn $name() {
-      let vec = &mut crate::misc::filled_buffer::FilledBuffer::_new();
-      let mut fbw = crate::misc::FilledBufferWriter::new(0, vec);
-      let mut ev = EncodeValue::new(&mut fbw);
+      let vec = &mut crate::misc::FilledBuffer::_new();
+      let mut sw = crate::misc::SuffixWriter::_new(0, vec._vector_mut());
+      let mut ew = EncodeWrapper::new(&mut sw);
       let instance: $ty = $instance;
-      Encode::<Postgres<crate::Error>>::encode(&instance, &mut ev).unwrap();
-      let decoded: $ty = Decode::<Postgres<crate::Error>>::decode(&DecodeValue::new(
-        ev.fbw()._curr_bytes(),
-        crate::database::client::postgres::Ty::Any,
-      ))
+      Encode::<Postgres<crate::Error>>::encode(&instance, &mut (), &mut ew).unwrap();
+      let decoded: $ty = Decode::<Postgres<crate::Error>>::decode(
+        &mut (),
+        &mut DecodeWrapper::new(ew.sw()._curr_bytes(), crate::database::client::postgres::Ty::Any),
+      )
       .unwrap();
       assert_eq!(instance, decoded);
     }
   };
 }
 
+#[cfg(feature = "chrono")]
+mod chrono;
+#[cfg(feature = "rust_decimal")]
+mod rust_decimal;
+#[cfg(feature = "serde_json")]
+mod serde_json;
+#[cfg(feature = "uuid")]
+mod uuid;
+
 mod array {
   use crate::{
     database::{
-      client::postgres::{DecodeValue, EncodeValue, Postgres, Ty},
-      Decode, Encode, Typed,
+      Typed,
+      client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, Ty},
     },
-    misc::{from_utf8_basic, ArrayString},
+    misc::{ArrayString, Decode, Encode, from_utf8_basic},
   };
 
   impl<E, const N: usize> Decode<'_, Postgres<E>> for ArrayString<N>
@@ -54,8 +63,8 @@ mod array {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'_>) -> Result<Self, E> {
-      Ok(from_utf8_basic(dv.bytes()).map_err(Into::into)?.try_into()?)
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      Ok(from_utf8_basic(dw.bytes()).map_err(Into::into)?.try_into()?)
     }
   }
   impl<E, const N: usize> Encode<Postgres<E>> for ArrayString<N>
@@ -63,8 +72,8 @@ mod array {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw().extend_from_slice(self.as_str().as_bytes())?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw().extend_from_slice(self.as_str().as_bytes())?;
       Ok(())
     }
   }
@@ -78,155 +87,13 @@ mod array {
   test!(array_string, ArrayString<4>, ArrayString::try_from("123").unwrap());
 }
 
-#[cfg(feature = "chrono")]
-mod chrono {
-  use crate::database::{
-    client::postgres::{DecodeValue, EncodeValue, Postgres, PostgresError, Ty},
-    Decode, Encode, Typed,
-  };
-  use chrono::{DateTime, Duration, NaiveDate, NaiveDateTime, TimeDelta, TimeZone, Utc};
-
-  const MIN_PG_ND: Option<NaiveDate> = NaiveDate::from_ymd_opt(-4713, 1, 1);
-  const MAX_CHRONO_ND: Option<NaiveDate> = NaiveDate::from_ymd_opt(262142, 1, 1);
-
-  impl<E> Decode<'_, Postgres<E>> for DateTime<Utc>
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn decode(dv: &DecodeValue<'_>) -> Result<Self, E> {
-      let naive = <NaiveDateTime as Decode<Postgres<E>>>::decode(dv)?;
-      Ok(Utc.from_utc_datetime(&naive))
-    }
-  }
-  impl<E, TZ> Encode<Postgres<E>> for DateTime<TZ>
-  where
-    E: From<crate::Error>,
-    TZ: TimeZone,
-  {
-    #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      Encode::<Postgres<E>>::encode(&self.naive_utc(), ev)
-    }
-  }
-  impl<E, TZ> Typed<Postgres<E>> for DateTime<TZ>
-  where
-    E: From<crate::Error>,
-    TZ: TimeZone,
-  {
-    const TY: Ty = Ty::Timestamptz;
-  }
-
-  impl<E> Decode<'_, Postgres<E>> for NaiveDate
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn decode(dv: &DecodeValue<'_>) -> Result<Self, E> {
-      let days: i32 = Decode::<Postgres<E>>::decode(dv)?;
-      pg_epoch_nd()
-        .and_then(|el| el.checked_add_signed(TimeDelta::try_days(days.into())?))
-        .ok_or_else(|| {
-          E::from(PostgresError::UnexpectedValueFromBytes { expected: "timestamp" }.into())
-        })
-    }
-  }
-  impl<E> Encode<Postgres<E>> for NaiveDate
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      Encode::<Postgres<E>>::encode(
-        &match pg_epoch_nd().and_then(|epoch| {
-          if self < &MIN_PG_ND? || self > &MAX_CHRONO_ND? {
-            return None;
-          }
-          i32::try_from(self.signed_duration_since(epoch).num_days()).ok()
-        }) {
-          Some(time) => time,
-          None => {
-            return Err(E::from(
-              PostgresError::UnexpectedValueFromBytes { expected: "date" }.into(),
-            ));
-          }
-        },
-        ev,
-      )
-    }
-  }
-  impl<E> Typed<Postgres<E>> for NaiveDate
-  where
-    E: From<crate::Error>,
-  {
-    const TY: Ty = Ty::Date;
-  }
-
-  impl<E> Decode<'_, Postgres<E>> for NaiveDateTime
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn decode(input: &DecodeValue<'_>) -> Result<Self, E> {
-      let timestamp = Decode::<Postgres<E>>::decode(input)?;
-      pg_epoch_ndt()
-        .and_then(|el| el.checked_add_signed(Duration::microseconds(timestamp)))
-        .ok_or_else(|| {
-          E::from(PostgresError::UnexpectedValueFromBytes { expected: "timestamp" }.into())
-        })
-    }
-  }
-  impl<E> Encode<Postgres<E>> for NaiveDateTime
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      Encode::<Postgres<E>>::encode(
-        &match pg_epoch_ndt().and_then(|epoch| {
-          if self < &MIN_PG_ND?.and_hms_opt(0, 0, 0)?
-            || self > &MAX_CHRONO_ND?.and_hms_opt(0, 0, 0)?
-          {
-            return None;
-          }
-          self.signed_duration_since(epoch).num_microseconds()
-        }) {
-          Some(time) => time,
-          None => {
-            return Err(E::from(
-              PostgresError::UnexpectedValueFromBytes { expected: "timestamp" }.into(),
-            ));
-          }
-        },
-        ev,
-      )
-    }
-  }
-  impl<E> Typed<Postgres<E>> for NaiveDateTime
-  where
-    E: From<crate::Error>,
-  {
-    const TY: Ty = Ty::Timestamp;
-  }
-
-  fn pg_epoch_nd() -> Option<NaiveDate> {
-    NaiveDate::from_ymd_opt(2000, 1, 1)
-  }
-
-  fn pg_epoch_ndt() -> Option<NaiveDateTime> {
-    pg_epoch_nd()?.and_hms_opt(0, 0, 0)
-  }
-
-  test!(datetime_utc, DateTime<Utc>, Utc.from_utc_datetime(&pg_epoch_ndt().unwrap()));
-}
-
 mod collections {
   use crate::{
     database::{
-      client::postgres::{DecodeValue, EncodeValue, Postgres, Ty},
-      Decode, Encode, Typed,
+      Typed,
+      client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, Ty},
     },
-    misc::from_utf8_basic,
+    misc::{Decode, Encode, from_utf8_basic},
   };
   use alloc::string::String;
 
@@ -237,8 +104,8 @@ mod collections {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'exec>) -> Result<Self, E> {
-      Ok(dv.bytes())
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'exec>) -> Result<Self, E> {
+      Ok(dw.bytes())
     }
   }
   impl<E> Encode<Postgres<E>> for &[u8]
@@ -246,8 +113,8 @@ mod collections {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw().extend_from_slice(self)?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw().extend_from_slice(self)?;
       Ok(())
     }
   }
@@ -266,8 +133,8 @@ mod collections {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw().extend_from_slice(self.as_bytes())?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw().extend_from_slice(self.as_bytes())?;
       Ok(())
     }
   }
@@ -285,8 +152,8 @@ mod collections {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'exec>) -> Result<Self, E> {
-      Ok(from_utf8_basic(dv.bytes()).map_err(crate::Error::from)?)
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'exec>) -> Result<Self, E> {
+      Ok(from_utf8_basic(dw.bytes()).map_err(crate::Error::from)?)
     }
   }
   impl<E> Encode<Postgres<E>> for &str
@@ -294,8 +161,8 @@ mod collections {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw().extend_from_slice(self.as_bytes())?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw().extend_from_slice(self.as_bytes())?;
       Ok(())
     }
   }
@@ -314,8 +181,8 @@ mod collections {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'_>) -> Result<Self, E> {
-      match from_utf8_basic(dv.bytes()).map_err(crate::Error::from) {
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      match from_utf8_basic(dw.bytes()).map_err(crate::Error::from) {
         Ok(elem) => Ok(elem.into()),
         Err(err) => Err(err.into()),
       }
@@ -326,8 +193,8 @@ mod collections {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw().extend_from_slice(self.as_bytes())?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw().extend_from_slice(self.as_bytes())?;
       Ok(())
     }
   }
@@ -341,9 +208,12 @@ mod collections {
 }
 
 mod ip {
-  use crate::database::{
-    client::postgres::{DecodeValue, EncodeValue, Postgres, PostgresError, Ty},
-    Decode, Encode, Typed,
+  use crate::{
+    database::{
+      Typed,
+      client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, PostgresError, Ty},
+    },
+    misc::{Decode, Encode},
   };
   use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 
@@ -352,10 +222,10 @@ mod ip {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'exec>) -> Result<Self, E> {
-      Ok(match dv.bytes() {
-        [2, ..] => IpAddr::V4(Ipv4Addr::decode(dv)?),
-        [3, ..] => IpAddr::V6(Ipv6Addr::decode(dv)?),
+    fn decode(aux: &mut (), dw: &mut DecodeWrapper<'exec>) -> Result<Self, E> {
+      Ok(match dw.bytes() {
+        [2, ..] => IpAddr::V4(Ipv4Addr::decode(aux, dw)?),
+        [3, ..] => IpAddr::V6(Ipv6Addr::decode(aux, dw)?),
         _ => return Err(E::from(PostgresError::InvalidIpFormat.into())),
       })
     }
@@ -365,10 +235,10 @@ mod ip {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
+    fn encode(&self, aux: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
       match self {
-        IpAddr::V4(ipv4_addr) => ipv4_addr.encode(ev),
-        IpAddr::V6(ipv6_addr) => ipv6_addr.encode(ev),
+        IpAddr::V4(ipv4_addr) => ipv4_addr.encode(aux, ew),
+        IpAddr::V6(ipv6_addr) => ipv6_addr.encode(aux, ew),
       }
     }
   }
@@ -386,8 +256,8 @@ mod ip {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'exec>) -> Result<Self, E> {
-      let [2, 32, 0, 4, e, f, g, h] = dv.bytes() else {
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'exec>) -> Result<Self, E> {
+      let [2, 32, 0, 4, e, f, g, h] = dw.bytes() else {
         return Err(E::from(PostgresError::InvalidIpFormat.into()));
       };
       Ok(Ipv4Addr::from([*e, *f, *g, *h]))
@@ -398,8 +268,8 @@ mod ip {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw()._extend_from_slices([&[2, 32, 0, 4][..], &self.octets()])?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw()._extend_from_slices([&[2, 32, 0, 4][..], &self.octets()])?;
       Ok(())
     }
   }
@@ -416,8 +286,8 @@ mod ip {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'exec>) -> Result<Self, E> {
-      let [3, 128, 0, 16, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = dv.bytes() else {
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'exec>) -> Result<Self, E> {
+      let [3, 128, 0, 16, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = dw.bytes() else {
         return Err(E::from(PostgresError::InvalidIpFormat.into()));
       };
       Ok(Ipv6Addr::from([*e, *f, *g, *h, *i, *j, *k, *l, *m, *n, *o, *p, *q, *r, *s, *t]))
@@ -428,8 +298,8 @@ mod ip {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw()._extend_from_slices([&[3, 128, 0, 16][..], &self.octets()])?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw()._extend_from_slices([&[3, 128, 0, 16][..], &self.octets()])?;
       Ok(())
     }
   }
@@ -445,10 +315,10 @@ mod ip {
 mod pg_numeric {
   use crate::{
     database::{
-      client::postgres::{DecodeValue, EncodeValue, Postgres, PostgresError},
-      Decode, Encode,
+      DatabaseError,
+      client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, PostgresError},
     },
-    misc::{ArrayVector, Usize},
+    misc::{ArrayVector, Decode, Encode, Usize},
   };
 
   const _DIGITS_CAP: usize = 64;
@@ -466,12 +336,12 @@ mod pg_numeric {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'_>) -> Result<Self, E> {
-      let [a, b, c, d, e, f, g, h, rest @ ..] = dv.bytes() else {
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      let [a, b, c, d, e, f, g, h, rest @ ..] = dw.bytes() else {
         return Err(E::from(
-          PostgresError::UnexpectedBufferSize {
+          DatabaseError::UnexpectedBufferSize {
             expected: 8,
-            received: Usize::from(dv.bytes().len()).into_u64().try_into().unwrap_or(u32::MAX),
+            received: Usize::from(dw.bytes().len()).into_u64().try_into().unwrap_or(u32::MAX),
           }
           .into(),
         ));
@@ -510,22 +380,22 @@ mod pg_numeric {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
       match self {
         _PgNumeric::NaN => {
-          ev.fbw().extend_from_slice(&0i16.to_be_bytes())?;
-          ev.fbw().extend_from_slice(&0i16.to_be_bytes())?;
-          ev.fbw().extend_from_slice(&SIGN_NAN.to_be_bytes())?;
-          ev.fbw().extend_from_slice(&0u16.to_be_bytes())?;
+          ew.sw().extend_from_slice(&0i16.to_be_bytes())?;
+          ew.sw().extend_from_slice(&0i16.to_be_bytes())?;
+          ew.sw().extend_from_slice(&SIGN_NAN.to_be_bytes())?;
+          ew.sw().extend_from_slice(&0u16.to_be_bytes())?;
         }
         _PgNumeric::Number { digits, scale, sign, weight } => {
           let len: i16 = digits.len().try_into().map_err(Into::into)?;
-          ev.fbw().extend_from_slice(&len.to_be_bytes())?;
-          ev.fbw().extend_from_slice(&weight.to_be_bytes())?;
-          ev.fbw().extend_from_slice(&u16::from(*sign).to_be_bytes())?;
-          ev.fbw().extend_from_slice(&scale.to_be_bytes())?;
+          ew.sw().extend_from_slice(&len.to_be_bytes())?;
+          ew.sw().extend_from_slice(&weight.to_be_bytes())?;
+          ew.sw().extend_from_slice(&u16::from(*sign).to_be_bytes())?;
+          ew.sw().extend_from_slice(&scale.to_be_bytes())?;
           for digit in digits {
-            ev.fbw().extend_from_slice(&digit.to_be_bytes())?;
+            ew.sw().extend_from_slice(&digit.to_be_bytes())?;
           }
         }
       }
@@ -567,10 +437,10 @@ mod pg_numeric {
 mod primitives {
   use crate::{
     database::{
-      client::postgres::{DecodeValue, EncodeValue, Postgres, PostgresError, Ty},
-      Decode, Encode, Typed,
+      DatabaseError, Typed,
+      client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, PostgresError, Ty},
     },
-    misc::Usize,
+    misc::{Decode, Encode, Usize},
   };
 
   // bool
@@ -580,12 +450,12 @@ mod primitives {
     E: From<crate::Error>,
   {
     #[inline]
-    fn decode(dv: &DecodeValue<'_>) -> Result<Self, E> {
-      let &[byte] = dv.bytes() else {
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+      let &[byte] = dw.bytes() else {
         return Err(E::from(
-          PostgresError::UnexpectedBufferSize {
+          DatabaseError::UnexpectedBufferSize {
             expected: 1,
-            received: Usize::from(dv.bytes().len()).into_u64().try_into().unwrap_or(u32::MAX),
+            received: Usize::from(dw.bytes().len()).into_u64().try_into().unwrap_or(u32::MAX),
           }
           .into(),
         ));
@@ -598,8 +468,8 @@ mod primitives {
     E: From<crate::Error>,
   {
     #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw()._extend_from_byte((*self).into())?;
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+      ew.sw()._extend_from_byte((*self).into())?;
       Ok(())
     }
   }
@@ -622,8 +492,8 @@ mod primitives {
         E: From<crate::Error>,
       {
         #[inline]
-        fn decode(input: &DecodeValue<'_>) -> Result<Self, E> {
-          <$signed as Decode::<Postgres<E>>>::decode(input)?
+        fn decode(aux: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+          <$signed as Decode::<Postgres<E>>>::decode(aux, dw)?
             .try_into()
             .map_err(|_err| E::from(PostgresError::InvalidPostgresUint.into()))
         }
@@ -633,11 +503,11 @@ mod primitives {
         E: From<crate::Error>,
       {
         #[inline]
-        fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
+        fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
           if *self >> const { $unsigned::BITS - 1 } == 1 {
             return Err(E::from(PostgresError::InvalidPostgresUint.into()));
           }
-          ev.fbw().extend_from_slice(&self.to_be_bytes())?;
+          ew.sw().extend_from_slice(&self.to_be_bytes())?;
           Ok(())
         }
       }
@@ -659,13 +529,13 @@ mod primitives {
         E: From<crate::Error>,
       {
         #[inline]
-        fn decode(input: &DecodeValue<'_>) -> Result<Self, E> {
-          if let &[$($elem,)+] = input.bytes() {
-            return Ok(<$ty>::from_be_bytes([$($elem),+]));
+        fn decode(_: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+          if let &[$($elem,)+] = dw.bytes() {
+            return Ok(<Self>::from_be_bytes([$($elem),+]));
           }
-          Err(E::from(PostgresError::UnexpectedBufferSize {
+          Err(E::from(DatabaseError::UnexpectedBufferSize {
             expected: Usize::from(size_of::<$ty>()).into_u64().try_into().unwrap_or(u32::MAX),
-            received: Usize::from(input.bytes().len()).into_u64().try_into().unwrap_or(u32::MAX)
+            received: Usize::from(dw.bytes().len()).into_u64().try_into().unwrap_or(u32::MAX)
           }.into()))
         }
       }
@@ -675,8 +545,8 @@ mod primitives {
         E: From<crate::Error>,
       {
         #[inline]
-        fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-          ev.fbw().extend_from_slice(&self.to_be_bytes())?;
+        fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+          ew.sw().extend_from_slice(&self.to_be_bytes())?;
           Ok(())
         }
       }
@@ -700,198 +570,3 @@ mod primitives {
   impl_primitive_from_array!(37.0, [a, b, c, d], f32, Ty::Float4);
   impl_primitive_from_array!(37.0, [a, b, c, d, e, f, g, h], f64, Ty::Float8);
 }
-
-#[cfg(feature = "rust_decimal")]
-mod rust_decimal {
-  use crate::{
-    database::{
-      client::postgres::{
-        tys::pg_numeric::{Sign, _PgNumeric},
-        DecodeValue, EncodeValue, Postgres, PostgresError, Ty,
-      },
-      Decode, Encode, Typed,
-    },
-    misc::ArrayVector,
-  };
-  use rust_decimal::{Decimal, MathematicalOps};
-
-  impl<E> Decode<'_, Postgres<E>> for Decimal
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn decode(input: &DecodeValue<'_>) -> Result<Self, E> {
-      let pg_numeric = _PgNumeric::decode(input)?;
-      let (digits, sign, mut weight, scale) = match pg_numeric {
-        _PgNumeric::NaN => {
-          return Err(E::from(PostgresError::DecimalCanNotBeConvertedFromNaN.into()));
-        }
-        _PgNumeric::Number { digits, sign, weight, scale } => (digits, sign, weight, scale),
-      };
-      if digits.is_empty() {
-        return Ok(0u64.into());
-      }
-      let mut value = Decimal::ZERO;
-      for digit in digits.into_iter() {
-        let mut operations = || {
-          let mul = Decimal::from(10_000u16).checked_powi(weight.into())?;
-          let part = Decimal::from(digit).checked_mul(mul)?;
-          value = value.checked_add(part)?;
-          weight = weight.checked_sub(1)?;
-          Some(())
-        };
-        operations().ok_or_else(|| crate::Error::OutOfBoundsArithmetic)?;
-      }
-      match sign {
-        Sign::Positive => value.set_sign_positive(true),
-        Sign::Negative => value.set_sign_negative(true),
-      }
-      value.rescale(scale.into());
-      Ok(value)
-    }
-  }
-  impl<E> Encode<Postgres<E>> for Decimal
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      if self.is_zero() {
-        let rslt = _PgNumeric::Number {
-          digits: ArrayVector::new(),
-          scale: 0,
-          sign: Sign::Positive,
-          weight: 0,
-        };
-        rslt.encode(ev)?;
-        return Ok(());
-      }
-
-      let scale = self.scale() as u16;
-
-      let mut mantissa = u128::from_le_bytes(self.serialize());
-      mantissa >>= 32;
-      let diff = scale % 4;
-      if diff > 0 {
-        let remainder = 4u32.wrapping_sub(u32::from(diff));
-        mantissa = mantissa.wrapping_mul(u128::from(10u32.pow(remainder)));
-      }
-
-      let mut digits = ArrayVector::new();
-      while mantissa != 0 {
-        digits.push((mantissa % 10_000) as i16)?;
-        mantissa /= 10_000;
-      }
-      digits.reverse();
-
-      let after_decimal = scale.wrapping_add(3) / 4;
-      let weight = digits.len().wrapping_sub(after_decimal.into()).wrapping_sub(1) as i16;
-
-      while let Some(&0) = digits.last() {
-        let _ = digits.pop();
-      }
-
-      let rslt = _PgNumeric::Number {
-        digits,
-        scale,
-        sign: match self.is_sign_negative() {
-          false => Sign::Positive,
-          true => Sign::Negative,
-        },
-        weight,
-      };
-      rslt.encode(ev)?;
-      Ok(())
-    }
-  }
-  impl<E> Typed<Postgres<E>> for Decimal
-  where
-    E: From<crate::Error>,
-  {
-    const TY: Ty = Ty::Numeric;
-  }
-
-  kani!(rust_decimal, Decimal);
-}
-
-#[cfg(feature = "serde_json")]
-mod serde_json {
-  use crate::database::{
-    client::postgres::{DecodeValue, EncodeValue, Postgres, PostgresError, Ty},
-    Decode, Encode, Json, Typed,
-  };
-  use serde::{Deserialize, Serialize};
-
-  impl<'de, E, T> Decode<'de, Postgres<E>> for Json<T>
-  where
-    E: From<crate::Error>,
-    T: Deserialize<'de>,
-  {
-    #[inline]
-    fn decode(input: &DecodeValue<'de>) -> Result<Self, E> {
-      let [1, rest @ ..] = input.bytes() else {
-        return Err(E::from(PostgresError::InvalidJsonFormat.into()));
-      };
-      let elem = serde_json::from_slice(rest).map(Json).map_err(Into::into)?;
-      Ok(elem)
-    }
-  }
-  impl<E, T> Encode<Postgres<E>> for Json<T>
-  where
-    E: From<crate::Error>,
-    T: Serialize,
-  {
-    #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw()._extend_from_byte(1)?;
-      serde_json::to_writer(ev.fbw(), &self.0).map_err(Into::into)?;
-      Ok(())
-    }
-  }
-  impl<E, T> Typed<Postgres<E>> for Json<T>
-  where
-    E: From<crate::Error>,
-  {
-    const TY: Ty = Ty::Jsonb;
-  }
-}
-
-#[cfg(feature = "uuid")]
-mod uuid {
-  use crate::database::{
-    client::postgres::{DecodeValue, EncodeValue, Postgres, Ty},
-    Decode, Encode, Typed,
-  };
-  use uuid::Uuid;
-
-  impl<'de, E> Decode<'de, Postgres<E>> for Uuid
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn decode(input: &DecodeValue<'de>) -> Result<Self, E> {
-      let elem = Uuid::from_slice(input.bytes()).map_err(Into::into)?;
-      Ok(elem)
-    }
-  }
-
-  impl<E> Encode<Postgres<E>> for Uuid
-  where
-    E: From<crate::Error>,
-  {
-    #[inline]
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), E> {
-      ev.fbw().extend_from_slice(self.as_bytes())?;
-      Ok(())
-    }
-  }
-
-  impl<E> Typed<Postgres<E>> for Uuid
-  where
-    E: From<crate::Error>,
-  {
-    const TY: Ty = Ty::Uuid;
-  }
-
-  test!(uuid, Uuid, Uuid::max());
-}
diff --git a/wtx/src/database/client/postgres/tys/chrono.rs b/wtx/src/database/client/postgres/tys/chrono.rs
new file mode 100644
index 00000000..40b1b353
--- /dev/null
+++ b/wtx/src/database/client/postgres/tys/chrono.rs
@@ -0,0 +1,147 @@
+use crate::{
+  database::{
+    DatabaseError, Typed,
+    client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, Ty},
+  },
+  misc::{Decode, Encode},
+};
+use chrono::{DateTime, Duration, NaiveDate, NaiveDateTime, TimeDelta, TimeZone, Utc};
+
+const MIN_PG_ND: Option<NaiveDate> = NaiveDate::from_ymd_opt(-4713, 1, 1);
+const MAX_CHRONO_ND: Option<NaiveDate> = NaiveDate::from_ymd_opt(262142, 1, 1);
+
+impl<E> Decode<'_, Postgres<E>> for DateTime<Utc>
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+    let naive = <NaiveDateTime as Decode<Postgres<E>>>::decode(aux, dw)?;
+    Ok(Utc.from_utc_datetime(&naive))
+  }
+}
+
+impl<E, TZ> Encode<Postgres<E>> for DateTime<TZ>
+where
+  E: From<crate::Error>,
+  TZ: TimeZone,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+    Encode::<Postgres<E>>::encode(&self.naive_utc(), &mut (), ew)
+  }
+}
+
+impl<E, TZ> Typed<Postgres<E>> for DateTime<TZ>
+where
+  E: From<crate::Error>,
+  TZ: TimeZone,
+{
+  const TY: Ty = Ty::Timestamptz;
+}
+
+impl<E> Decode<'_, Postgres<E>> for NaiveDate
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+    let days: i32 = Decode::<Postgres<E>>::decode(aux, dw)?;
+    pg_epoch_nd()
+      .and_then(|el| el.checked_add_signed(TimeDelta::try_days(days.into())?))
+      .ok_or_else(|| {
+        E::from(DatabaseError::UnexpectedValueFromBytes { expected: "timestamp" }.into())
+      })
+  }
+}
+
+impl<E> Encode<Postgres<E>> for NaiveDate
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+    Encode::<Postgres<E>>::encode(
+      &match pg_epoch_nd().and_then(|epoch| {
+        if self < &MIN_PG_ND? || self > &MAX_CHRONO_ND? {
+          return None;
+        }
+        i32::try_from(self.signed_duration_since(epoch).num_days()).ok()
+      }) {
+        Some(time) => time,
+        None => {
+          return Err(E::from(DatabaseError::UnexpectedValueFromBytes { expected: "date" }.into()));
+        }
+      },
+      &mut (),
+      ew,
+    )
+  }
+}
+
+impl<E> Typed<Postgres<E>> for NaiveDate
+where
+  E: From<crate::Error>,
+{
+  const TY: Ty = Ty::Date;
+}
+
+impl<E> Decode<'_, Postgres<E>> for NaiveDateTime
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+    let timestamp = Decode::<Postgres<E>>::decode(aux, dw)?;
+    pg_epoch_ndt()
+      .and_then(|el| el.checked_add_signed(Duration::microseconds(timestamp)))
+      .ok_or_else(|| {
+        E::from(DatabaseError::UnexpectedValueFromBytes { expected: "timestamp" }.into())
+      })
+  }
+}
+
+impl<E> Encode<Postgres<E>> for NaiveDateTime
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+    Encode::<Postgres<E>>::encode(
+      &match pg_epoch_ndt().and_then(|epoch| {
+        if self < &MIN_PG_ND?.and_hms_opt(0, 0, 0)?
+          || self > &MAX_CHRONO_ND?.and_hms_opt(0, 0, 0)?
+        {
+          return None;
+        }
+        self.signed_duration_since(epoch).num_microseconds()
+      }) {
+        Some(time) => time,
+        None => {
+          return Err(E::from(
+            DatabaseError::UnexpectedValueFromBytes { expected: "timestamp" }.into(),
+          ));
+        }
+      },
+      &mut (),
+      ew,
+    )
+  }
+}
+
+impl<E> Typed<Postgres<E>> for NaiveDateTime
+where
+  E: From<crate::Error>,
+{
+  const TY: Ty = Ty::Timestamp;
+}
+
+fn pg_epoch_nd() -> Option<NaiveDate> {
+  NaiveDate::from_ymd_opt(2000, 1, 1)
+}
+
+fn pg_epoch_ndt() -> Option<NaiveDateTime> {
+  pg_epoch_nd()?.and_hms_opt(0, 0, 0)
+}
+
+test!(datetime_utc, DateTime<Utc>, Utc.from_utc_datetime(&pg_epoch_ndt().unwrap()));
diff --git a/wtx/src/database/client/postgres/tys/rust_decimal.rs b/wtx/src/database/client/postgres/tys/rust_decimal.rs
new file mode 100644
index 00000000..1854f560
--- /dev/null
+++ b/wtx/src/database/client/postgres/tys/rust_decimal.rs
@@ -0,0 +1,111 @@
+use crate::{
+  database::{
+    Typed,
+    client::postgres::{
+      DecodeWrapper, EncodeWrapper, Postgres, PostgresError, Ty,
+      tys::pg_numeric::{_PgNumeric, Sign},
+    },
+  },
+  misc::{ArrayVector, Decode, Encode},
+};
+use rust_decimal::{Decimal, MathematicalOps};
+
+impl<E> Decode<'_, Postgres<E>> for Decimal
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(aux: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, E> {
+    let pg_numeric = _PgNumeric::decode(aux, dw)?;
+    let (digits, sign, mut weight, scale) = match pg_numeric {
+      _PgNumeric::NaN => {
+        return Err(E::from(PostgresError::DecimalCanNotBeConvertedFromNaN.into()));
+      }
+      _PgNumeric::Number { digits, sign, weight, scale } => (digits, sign, weight, scale),
+    };
+    if digits.is_empty() {
+      return Ok(0u64.into());
+    }
+    let mut value = Decimal::ZERO;
+    for digit in digits.into_iter() {
+      let mut operations = || {
+        let mul = Decimal::from(10_000u16).checked_powi(weight.into())?;
+        let part = Decimal::from(digit).checked_mul(mul)?;
+        value = value.checked_add(part)?;
+        weight = weight.checked_sub(1)?;
+        Some(())
+      };
+      operations().ok_or_else(|| crate::Error::OutOfBoundsArithmetic)?;
+    }
+    match sign {
+      Sign::Positive => value.set_sign_positive(true),
+      Sign::Negative => value.set_sign_negative(true),
+    }
+    value.rescale(scale.into());
+    Ok(value)
+  }
+}
+
+impl<E> Encode<Postgres<E>> for Decimal
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, aux: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+    if self.is_zero() {
+      let rslt = _PgNumeric::Number {
+        digits: ArrayVector::new(),
+        scale: 0,
+        sign: Sign::Positive,
+        weight: 0,
+      };
+      rslt.encode(aux, ew)?;
+      return Ok(());
+    }
+
+    let scale = self.scale() as u16;
+
+    let mut mantissa = u128::from_le_bytes(self.serialize());
+    mantissa >>= 32;
+    let diff = scale % 4;
+    if diff > 0 {
+      let remainder = 4u32.wrapping_sub(u32::from(diff));
+      mantissa = mantissa.wrapping_mul(u128::from(10u32.pow(remainder)));
+    }
+
+    let mut digits = ArrayVector::new();
+    while mantissa != 0 {
+      digits.push((mantissa % 10_000) as i16)?;
+      mantissa /= 10_000;
+    }
+    digits.reverse();
+
+    let after_decimal = scale.wrapping_add(3) / 4;
+    let weight = digits.len().wrapping_sub(after_decimal.into()).wrapping_sub(1) as i16;
+
+    while let Some(&0) = digits.last() {
+      let _ = digits.pop();
+    }
+
+    let rslt = _PgNumeric::Number {
+      digits,
+      scale,
+      sign: match self.is_sign_negative() {
+        false => Sign::Positive,
+        true => Sign::Negative,
+      },
+      weight,
+    };
+    rslt.encode(aux, ew)?;
+    Ok(())
+  }
+}
+
+impl<E> Typed<Postgres<E>> for Decimal
+where
+  E: From<crate::Error>,
+{
+  const TY: Ty = Ty::Numeric;
+}
+
+kani!(rust_decimal, Decimal);
diff --git a/wtx/src/database/client/postgres/tys/serde_json.rs b/wtx/src/database/client/postgres/tys/serde_json.rs
new file mode 100644
index 00000000..1b18df5b
--- /dev/null
+++ b/wtx/src/database/client/postgres/tys/serde_json.rs
@@ -0,0 +1,41 @@
+use crate::{
+  database::{
+    Json, Typed,
+    client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, PostgresError, Ty},
+  },
+  misc::{Decode, Encode},
+};
+use serde::{Deserialize, Serialize};
+
+impl<'de, E, T> Decode<'de, Postgres<E>> for Json<T>
+where
+  E: From<crate::Error>,
+  T: Deserialize<'de>,
+{
+  #[inline]
+  fn decode(_: &mut (), input: &mut DecodeWrapper<'de>) -> Result<Self, E> {
+    let [1, rest @ ..] = input.bytes() else {
+      return Err(E::from(PostgresError::InvalidJsonFormat.into()));
+    };
+    let elem = serde_json::from_slice(rest).map(Json).map_err(Into::into)?;
+    Ok(elem)
+  }
+}
+impl<E, T> Encode<Postgres<E>> for Json<T>
+where
+  E: From<crate::Error>,
+  T: Serialize,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+    ew.sw()._extend_from_byte(1)?;
+    serde_json::to_writer(ew.sw(), &self.0).map_err(Into::into)?;
+    Ok(())
+  }
+}
+impl<E, T> Typed<Postgres<E>> for Json<T>
+where
+  E: From<crate::Error>,
+{
+  const TY: Ty = Ty::Jsonb;
+}
diff --git a/wtx/src/database/client/postgres/tys/uuid.rs b/wtx/src/database/client/postgres/tys/uuid.rs
new file mode 100644
index 00000000..87761f8a
--- /dev/null
+++ b/wtx/src/database/client/postgres/tys/uuid.rs
@@ -0,0 +1,39 @@
+use crate::{
+  database::{
+    Typed,
+    client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, Ty},
+  },
+  misc::{Decode, Encode},
+};
+use uuid::Uuid;
+
+impl<'de, E> Decode<'de, Postgres<E>> for Uuid
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn decode(_: &mut (), dw: &mut DecodeWrapper<'de>) -> Result<Self, E> {
+    let elem = Uuid::from_slice(dw.bytes()).map_err(Into::into)?;
+    Ok(elem)
+  }
+}
+
+impl<E> Encode<Postgres<E>> for Uuid
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
+    ew.sw().extend_from_slice(self.as_bytes())?;
+    Ok(())
+  }
+}
+
+impl<E> Typed<Postgres<E>> for Uuid
+where
+  E: From<crate::Error>,
+{
+  const TY: Ty = Ty::Uuid;
+}
+
+test!(uuid, Uuid, Uuid::max());
diff --git a/wtx/src/database/client/rdbms.rs b/wtx/src/database/client/rdbms.rs
new file mode 100644
index 00000000..c7b22e91
--- /dev/null
+++ b/wtx/src/database/client/rdbms.rs
@@ -0,0 +1,63 @@
+pub(crate) mod statement;
+pub(crate) mod statement_builder;
+pub(crate) mod statements;
+pub(crate) mod statements_misc;
+
+use crate::misc::{ArrayVector, UriRef, str_split_once1, str_split1};
+
+pub(crate) type U64Array = ArrayVector<u8, 20>;
+
+#[inline]
+pub(crate) fn query_walker<'uri>(
+  uri: &'uri UriRef<'_>,
+  mut cb: impl FnMut(&'uri str, &'uri str) -> crate::Result<()>,
+) -> crate::Result<()> {
+  let mut pair_iter = str_split1(uri.query_and_fragment(), b'&');
+  if let Some(mut key_value) = pair_iter.next() {
+    key_value = key_value.get(1..).unwrap_or_default();
+    if let Some((key, value)) = str_split_once1(key_value, b'=') {
+      cb(key, value)?;
+    }
+  }
+  for key_value in pair_iter {
+    if let Some((key, value)) = str_split_once1(key_value, b'=') {
+      cb(key, value)?;
+    }
+  }
+  Ok(())
+}
+
+#[inline]
+pub(crate) fn u64_array(mut value: u64) -> U64Array {
+  let mut idx: u8 = 20;
+  let mut buffer = [0u8; 20];
+  for local_idx in 1..=20 {
+    idx = 20u8.wrapping_sub(local_idx);
+    let Some(elem) = buffer.get_mut(usize::from(idx)) else {
+      break;
+    };
+    *elem = u8::try_from(value % 10).unwrap_or_default().wrapping_add(48);
+    value /= 10;
+    if value == 0 {
+      break;
+    }
+  }
+  let mut data = [0u8; 20];
+  let len = 20u16.wrapping_sub(idx.into());
+  let slice = data.get_mut(..usize::from(len)).unwrap_or_default();
+  slice.copy_from_slice(buffer.get(usize::from(idx)..).unwrap_or_default());
+  ArrayVector::from_parts(data, Some(len.into()))
+}
+
+#[cfg(test)]
+pub(crate) mod tests {
+  use crate::database::client::rdbms::u64_array;
+
+  #[test]
+  fn has_correct_stmt_number() {
+    assert_eq!(u64_array(0).as_slice(), b"0");
+    assert_eq!(u64_array(12).as_slice(), b"12");
+    assert_eq!(u64_array(1844674407370955161).as_slice(), b"1844674407370955161");
+    assert_eq!(u64_array(18446744073709551615).as_slice(), b"18446744073709551615");
+  }
+}
diff --git a/wtx/src/database/client/rdbms/statement.rs b/wtx/src/database/client/rdbms/statement.rs
new file mode 100644
index 00000000..3606af0d
--- /dev/null
+++ b/wtx/src/database/client/rdbms/statement.rs
@@ -0,0 +1,77 @@
+/// ```sql
+/// SELECT a,b,c,d FROM table WHERE e = $1 AND f = $2
+/// ```
+///
+/// The columns are "a", "b", "c", "d" and the types are "$1" and "$2".
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub(crate) struct Statement<'stmts, A, C, T> {
+  aux: A,
+  columns_len: usize,
+  tys_len: usize,
+  values: &'stmts [(C, T)],
+}
+
+impl<'stmts, A, C, T> Statement<'stmts, A, C, T> {
+  #[inline]
+  pub(crate) const fn new(
+    aux: A,
+    columns_len: usize,
+    tys_len: usize,
+    values: &'stmts [(C, T)],
+  ) -> Self {
+    Self { aux, columns_len, tys_len, values }
+  }
+
+  #[inline]
+  pub(crate) fn _aux(&self) -> &A {
+    &self.aux
+  }
+
+  #[inline]
+  pub(crate) fn _column(&self, idx: usize) -> Option<&C> {
+    let columns = self.values.get(..self.columns_len)?;
+    Some(&columns.get(idx)?.0)
+  }
+
+  #[inline]
+  pub(crate) fn _columns(&self) -> impl Iterator<Item = &C> {
+    let columns = self.values.get(..self.columns_len).unwrap_or_default();
+    columns.iter().map(|el| &el.0)
+  }
+
+  #[inline]
+  pub(crate) fn _columns_len(&self) -> usize {
+    self.columns_len
+  }
+
+  #[cfg(test)]
+  #[inline]
+  pub(crate) fn _ty(&self, idx: usize) -> Option<&T> {
+    Some(&self.values.get(..self.tys_len)?.get(idx)?.1)
+  }
+
+  #[inline]
+  pub(crate) fn _tys(&self) -> impl Iterator<Item = &T> {
+    self.values.get(..self.tys_len).unwrap_or_default().iter().map(|el| &el.1)
+  }
+
+  #[inline]
+  pub(crate) fn _tys_len(&self) -> usize {
+    self.tys_len
+  }
+
+  #[inline]
+  pub(crate) fn _values(&self) -> &[(C, T)] {
+    &self.values
+  }
+}
+
+impl<'stmts, A, C, T> Default for Statement<'stmts, A, C, T>
+where
+  A: Default,
+{
+  #[inline]
+  fn default() -> Self {
+    Self { aux: A::default(), columns_len: 0, tys_len: 0, values: &[] }
+  }
+}
diff --git a/wtx/src/database/client/postgres/statements/statement_builder.rs b/wtx/src/database/client/rdbms/statement_builder.rs
similarity index 53%
rename from wtx/src/database/client/postgres/statements/statement_builder.rs
rename to wtx/src/database/client/rdbms/statement_builder.rs
index feebccd1..2aebab68 100644
--- a/wtx/src/database/client/postgres/statements/statement_builder.rs
+++ b/wtx/src/database/client/rdbms/statement_builder.rs
@@ -1,26 +1,20 @@
 use crate::{
-  database::{
-    client::postgres::{
-      statements::{column::Column, statements_misc::StatementsMisc},
-      Ty,
-    },
-    Identifier,
-  },
+  database::client::rdbms::statements_misc::StatementsMisc,
   misc::{BlocksDeque, BlocksDequeBuilder, BufferMode},
 };
 use hashbrown::HashMap;
 
 #[derive(Debug)]
-pub(crate) struct StatementBuilder<'stmts> {
-  pub(crate) builder: BlocksDequeBuilder<'stmts, (Column, Ty), StatementsMisc, true>,
+pub(crate) struct StatementBuilder<'stmts, A, C, T> {
+  pub(crate) builder: BlocksDequeBuilder<'stmts, (C, T), StatementsMisc<A>, true>,
   pub(crate) curr_len: usize,
   pub(crate) indcs: &'stmts mut HashMap<u64, usize>,
 }
 
-impl<'stmts> StatementBuilder<'stmts> {
+impl<'stmts, A, C, T> StatementBuilder<'stmts, A, C, T> {
   #[inline]
   pub(crate) fn new(
-    stmts: &'stmts mut BlocksDeque<(Column, Ty), StatementsMisc>,
+    stmts: &'stmts mut BlocksDeque<(C, T), StatementsMisc<A>>,
     stmts_indcs: &'stmts mut HashMap<u64, usize>,
   ) -> Self {
     let curr_len = stmts.blocks_len();
@@ -28,7 +22,7 @@ impl<'stmts> StatementBuilder<'stmts> {
   }
 
   #[inline]
-  pub(crate) fn build(mut self, hash: u64, mut sm: StatementsMisc) -> crate::Result<usize> {
+  pub(crate) fn build(mut self, hash: u64, mut sm: StatementsMisc<A>) -> crate::Result<usize> {
     let len = self.builder.inserted_elements().len();
     sm.columns_len = sm.columns_len.min(len);
     sm.types_len = sm.types_len.min(len);
@@ -38,16 +32,17 @@ impl<'stmts> StatementBuilder<'stmts> {
   }
 
   #[inline]
-  pub(crate) fn expand(&mut self, additional: usize) -> crate::Result<&mut Self> {
-    let _ = self.builder.expand(
-      BufferMode::Additional(additional),
-      (Column::new(Identifier::new(), Ty::Any), Ty::Any),
-    )?;
+  pub(crate) fn expand(&mut self, additional: usize, elem: (C, T)) -> crate::Result<&mut Self>
+  where
+    C: Clone,
+    T: Clone,
+  {
+    let _ = self.builder.expand(BufferMode::Additional(additional), elem)?;
     Ok(self)
   }
 
   #[inline]
-  pub(crate) fn inserted_elements(&mut self) -> &mut [(Column, Ty)] {
+  pub(crate) fn inserted_elements(&mut self) -> &mut [(C, T)] {
     self.builder.inserted_elements()
   }
 }
diff --git a/wtx/src/database/client/rdbms/statements.rs b/wtx/src/database/client/rdbms/statements.rs
new file mode 100644
index 00000000..48ac0bf8
--- /dev/null
+++ b/wtx/src/database/client/rdbms/statements.rs
@@ -0,0 +1,197 @@
+use crate::{
+  database::client::rdbms::{
+    statement::Statement, statement_builder::StatementBuilder, statements_misc::StatementsMisc,
+  },
+  misc::{_random_state, BlocksDeque, Rng},
+};
+use foldhash::fast::FixedState;
+use hashbrown::HashMap;
+
+/// Statements
+#[derive(Debug)]
+pub(crate) struct Statements<A, C, T> {
+  max_stmts: usize,
+  rs: FixedState,
+  stmts: BlocksDeque<(C, T), StatementsMisc<A>>,
+  stmts_indcs: HashMap<u64, usize>,
+}
+
+impl<A, C, T> Statements<A, C, T> {
+  #[inline]
+  pub(crate) fn new<RNG>(max_stmts: usize, rng: RNG) -> Self
+  where
+    RNG: Rng,
+  {
+    Self {
+      max_stmts: max_stmts.max(1),
+      rs: _random_state(rng),
+      stmts: BlocksDeque::new(),
+      stmts_indcs: HashMap::new(),
+    }
+  }
+
+  #[inline]
+  pub(crate) fn with_capacity<RNG>(
+    columns: usize,
+    max_stmts: usize,
+    rng: RNG,
+    stmts: usize,
+  ) -> crate::Result<Self>
+  where
+    RNG: Rng,
+  {
+    Ok(Self {
+      max_stmts: max_stmts.max(1),
+      rs: _random_state(rng),
+      stmts: BlocksDeque::with_capacity(stmts, columns)?,
+      stmts_indcs: HashMap::with_capacity(stmts),
+    })
+  }
+
+  #[inline]
+  pub(crate) fn builder(&mut self) -> StatementBuilder<'_, A, C, T> {
+    if self.stmts.blocks_len() >= self.max_stmts {
+      let to_remove = (self.max_stmts / 2).max(1);
+      for _ in 0..to_remove {
+        drop(self.stmts.pop_front());
+      }
+      self.stmts_indcs.retain(|_, value| {
+        if *value < to_remove {
+          return false;
+        }
+        *value = value.wrapping_sub(to_remove);
+        true
+      })
+    }
+    StatementBuilder::new(&mut self.stmts, &mut self.stmts_indcs)
+  }
+
+  #[inline]
+  pub(crate) fn clear(&mut self) {
+    let Self { max_stmts: _, rs: _, stmts, stmts_indcs } = self;
+    stmts.clear();
+    stmts_indcs.clear();
+  }
+
+  #[inline]
+  pub(crate) fn get_by_idx(&self, idx: usize) -> Option<Statement<'_, A, C, T>>
+  where
+    A: Copy,
+  {
+    let stmt = self.stmts.get(idx)?;
+    Some(Statement::new(stmt.misc._aux, stmt.misc.columns_len, stmt.misc.types_len, stmt.data))
+  }
+
+  #[inline]
+  pub(crate) fn get_by_stmt_cmd_id(&self, stmt_cmd_id: u64) -> Option<Statement<'_, A, C, T>>
+  where
+    A: Copy,
+  {
+    self.get_by_idx(*self.stmts_indcs.get(&stmt_cmd_id)?)
+  }
+
+  #[inline]
+  pub(crate) fn hasher_mut(&mut self) -> &mut FixedState {
+    &mut self.rs
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use crate::{
+    database::client::rdbms::{statements::Statements, statements_misc::StatementsMisc},
+    misc::{Xorshift64, simple_seed},
+  };
+
+  // FIXME(MIRI): The modification of the vector's length makes MIRI think that there is an
+  // invalid pointer using stacked borrows.
+  //
+  // | A | B |   | <- Push back one block of 2 elements. Length is 2
+  // | A | B | C | <- Push back one block of 1 element. Length is 3
+  // |   |   | C | <- Pop front one block. Length is 1
+  //
+  // Such behaviour does not occur with "miri-tree-borrows".
+  #[cfg_attr(miri, ignore)]
+  #[test]
+
+  fn two_statements() {
+    let mut stmts = Statements::new(2, &mut Xorshift64::from(simple_seed()));
+
+    let stmt_id0 = 123;
+    let mut builder = stmts.builder();
+    let _ = builder.expand(2, ("", 0)).unwrap();
+    builder.inserted_elements()[0] = (column0(), 100);
+    builder.inserted_elements()[1] = (column1(), 100);
+    let _ = builder.build(stmt_id0, StatementsMisc::new(10, 2, 1)).unwrap();
+    {
+      let stmt = stmts.get_by_stmt_cmd_id(stmt_id0).unwrap();
+      assert_eq!(stmt._columns().count(), 2);
+      assert_eq!(stmt._column(0).unwrap(), &column0());
+      assert_eq!(stmt._column(1).unwrap(), &column1());
+      assert_eq!(stmt._tys().count(), 1);
+      assert_eq!(stmt._ty(0).unwrap(), &100);
+    }
+
+    let stmt_id1 = 456;
+    let mut builder = stmts.builder();
+    let _ = builder.expand(1, ("", 0)).unwrap();
+    builder.inserted_elements()[0] = (column2(), 200);
+    let _ = builder.build(stmt_id1, StatementsMisc::new(11, 1, 1)).unwrap();
+    {
+      let stmt = stmts.get_by_stmt_cmd_id(stmt_id0).unwrap();
+      assert_eq!(stmt._columns().count(), 2);
+      assert_eq!(stmt._column(0).unwrap(), &column0());
+      assert_eq!(stmt._column(1).unwrap(), &column1());
+      assert_eq!(stmt._tys().count(), 1);
+      assert_eq!(stmt._ty(0).unwrap(), &100);
+    }
+    {
+      let stmt = stmts.get_by_stmt_cmd_id(stmt_id1).unwrap();
+      assert_eq!(stmt._columns().count(), 1);
+      assert_eq!(stmt._column(0).unwrap(), &column2());
+      assert_eq!(stmt._tys().count(), 1);
+      assert_eq!(stmt._ty(0).unwrap(), &200);
+    }
+
+    let stmt_id2 = 789;
+    let mut builder = stmts.builder();
+    let _ = builder.expand(1, ("", 0)).unwrap();
+    builder.inserted_elements()[0].0 = column3();
+    let _ = builder.build(stmt_id2, StatementsMisc::new(12, 1, 0)).unwrap();
+    assert_eq!(stmts.get_by_stmt_cmd_id(stmt_id0), None);
+    {
+      let stmt = stmts.get_by_stmt_cmd_id(stmt_id1).unwrap();
+      assert_eq!(stmt._columns().count(), 1);
+      assert_eq!(stmt._column(0).unwrap(), &column2());
+      assert_eq!(stmt._tys().count(), 1);
+      assert_eq!(stmt._ty(0).unwrap(), &200);
+    }
+    {
+      let stmt = stmts.get_by_stmt_cmd_id(stmt_id2).unwrap();
+      assert_eq!(stmt._columns().count(), 1);
+      assert_eq!(stmt._column(0).unwrap(), &column3());
+      assert_eq!(stmt._tys().count(), 0);
+    }
+
+    stmts.clear();
+    assert_eq!(stmts.get_by_stmt_cmd_id(stmt_id0), None);
+    assert_eq!(stmts.get_by_stmt_cmd_id(stmt_id1), None);
+    assert_eq!(stmts.get_by_stmt_cmd_id(stmt_id2), None);
+  }
+
+  pub(crate) fn column0() -> &'static str {
+    "a"
+  }
+
+  pub(crate) fn column1() -> &'static str {
+    "b"
+  }
+
+  pub(crate) fn column2() -> &'static str {
+    "c"
+  }
+
+  pub(crate) fn column3() -> &'static str {
+    "d"
+  }
+}
diff --git a/wtx/src/database/client/rdbms/statements_misc.rs b/wtx/src/database/client/rdbms/statements_misc.rs
new file mode 100644
index 00000000..3d913a76
--- /dev/null
+++ b/wtx/src/database/client/rdbms/statements_misc.rs
@@ -0,0 +1,13 @@
+#[derive(Debug)]
+pub(crate) struct StatementsMisc<A> {
+  pub(crate) _aux: A,
+  pub(crate) columns_len: usize,
+  pub(crate) types_len: usize,
+}
+
+impl<A> StatementsMisc<A> {
+  #[inline]
+  pub(crate) fn new(aux: A, columns_len: usize, types_len: usize) -> Self {
+    Self { _aux: aux, columns_len, types_len }
+  }
+}
diff --git a/wtx/src/database/database_error.rs b/wtx/src/database/database_error.rs
index 650f31d9..3766dd3e 100644
--- a/wtx/src/database/database_error.rs
+++ b/wtx/src/database/database_error.rs
@@ -3,4 +3,18 @@
 pub enum DatabaseError {
   /// A "null" field received from the database was decoded as a non-nullable type or value.
   MissingFieldDataInDecoding(&'static str),
+  /// Received size differs from expected size.
+  UnexpectedBufferSize {
+    /// Expected
+    expected: u32,
+    /// Received
+    received: u32,
+  },
+  /// Bytes don't represent expected type
+  UnexpectedValueFromBytes {
+    /// Expected
+    expected: &'static str,
+  },
+  /// Received a statement ID that is not present in the local cache.
+  UnknownStatementId,
 }
diff --git a/wtx/src/database/database_ty.rs b/wtx/src/database/database_ty.rs
index ae24f4f4..6b7ac17f 100644
--- a/wtx/src/database/database_ty.rs
+++ b/wtx/src/database/database_ty.rs
@@ -2,16 +2,10 @@ create_enum! {
   /// Database
   #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
   pub enum DatabaseTy<u8> {
-    /// MS-SQL
-    Mssql = (0, "mssql"),
     /// MySql
     Mysql = (1, "mysql"),
     /// PostgreSQL
     Postgres = (2, "postgres"),
-    /// Redis
-    Redis = (3, "redis"),
-    /// SQLite
-    Sqlite = (4, "sqlite"),
     /// Unit (Dummy used for testing)
     Unit = (5, "unit")
   }
diff --git a/wtx/src/database/decode.rs b/wtx/src/database/decode.rs
deleted file mode 100644
index 9b28c0ee..00000000
--- a/wtx/src/database/decode.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use crate::database::Database;
-
-/// Similar to `TryFrom`. Avoids problems with coherence and has an additional `E` type.
-pub trait Decode<'de, D>: Sized
-where
-  D: Database,
-{
-  /// Performs the conversion.
-  fn decode(dv: &D::DecodeValue<'de>) -> Result<Self, D::Error>;
-}
-
-impl Decode<'_, ()> for &str {
-  #[inline]
-  fn decode(_: &()) -> Result<Self, crate::Error> {
-    Ok("")
-  }
-}
-
-impl Decode<'_, ()> for u32 {
-  #[inline]
-  fn decode(_: &()) -> Result<Self, crate::Error> {
-    Ok(0)
-  }
-}
-
-impl Decode<'_, ()> for u64 {
-  #[inline]
-  fn decode(_: &()) -> Result<Self, crate::Error> {
-    Ok(0)
-  }
-}
diff --git a/wtx/src/database/encode.rs b/wtx/src/database/encode.rs
deleted file mode 100644
index 756c6d05..00000000
--- a/wtx/src/database/encode.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-use crate::{
-  database::Database,
-  misc::{Either, FilledBufferWriter},
-};
-
-/// Encodes a type into a byte representation.
-pub trait Encode<D>
-where
-  D: Database,
-{
-  /// Performs the conversion.
-  fn encode(&self, ev: &mut D::EncodeValue<'_, '_>) -> Result<(), D::Error>;
-
-  /// In rust terms, is the element `Option::None`?
-  #[inline]
-  fn is_null(&self) -> bool {
-    false
-  }
-}
-
-impl Encode<()> for u32 {
-  #[inline]
-  fn encode(&self, _: &mut FilledBufferWriter<'_>) -> Result<(), crate::Error> {
-    Ok(())
-  }
-}
-
-impl Encode<()> for &str {
-  #[inline]
-  fn encode(&self, _: &mut FilledBufferWriter<'_>) -> Result<(), crate::Error> {
-    Ok(())
-  }
-}
-
-impl<D, T> Encode<D> for &T
-where
-  D: Database,
-  T: Encode<D>,
-{
-  #[inline]
-  fn encode(&self, ev: &mut D::EncodeValue<'_, '_>) -> Result<(), D::Error> {
-    (**self).encode(ev)
-  }
-
-  #[inline]
-  fn is_null(&self) -> bool {
-    (**self).is_null()
-  }
-}
-
-impl<D, L, R> Encode<D> for Either<L, R>
-where
-  D: Database,
-  L: Encode<D>,
-  R: Encode<D>,
-{
-  #[inline]
-  fn encode(&self, ev: &mut D::EncodeValue<'_, '_>) -> Result<(), D::Error> {
-    match self {
-      Self::Left(left) => left.encode(ev),
-      Self::Right(right) => right.encode(ev),
-    }
-  }
-
-  #[inline]
-  fn is_null(&self) -> bool {
-    match self {
-      Self::Left(left) => left.is_null(),
-      Self::Right(right) => right.is_null(),
-    }
-  }
-}
-
-impl<D> Encode<D> for &dyn Encode<D>
-where
-  D: Database,
-{
-  #[inline]
-  fn encode(&self, ev: &mut D::EncodeValue<'_, '_>) -> Result<(), D::Error> {
-    (**self).encode(ev)
-  }
-
-  #[inline]
-  fn is_null(&self) -> bool {
-    (**self).is_null()
-  }
-}
-
-impl<D, T> Encode<D> for Option<T>
-where
-  D: Database,
-  T: Encode<D>,
-{
-  #[inline]
-  fn encode(&self, ev: &mut D::EncodeValue<'_, '_>) -> Result<(), D::Error> {
-    match self {
-      None => Ok(()),
-      Some(elem) => elem.encode(ev),
-    }
-  }
-
-  #[inline]
-  fn is_null(&self) -> bool {
-    self.is_none()
-  }
-}
diff --git a/wtx/src/database/executor.rs b/wtx/src/database/executor.rs
index a6eb6899..610b6b93 100644
--- a/wtx/src/database/executor.rs
+++ b/wtx/src/database/executor.rs
@@ -2,7 +2,7 @@
 
 use crate::{
   database::{Database, FromRecord, RecordValues, StmtCmd},
-  misc::ConnectionState,
+  misc::{ConnectionState, DEController},
 };
 use core::future::Future;
 
@@ -17,7 +17,11 @@ pub trait Executor {
   /// Allows the evaluation of severals commands returning the number of affected records on each `cb` call.
   ///
   /// Commands are not cached or inspected for potential vulnerabilities.
-  fn execute(&mut self, cmd: &str, cb: impl FnMut(u64)) -> impl Future<Output = crate::Result<()>>;
+  fn execute(
+    &mut self,
+    cmd: &str,
+    cb: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> impl Future<Output = Result<(), <Self::Database as DEController>::Error>>;
 
   /// Executes a **single** statement automatically binding the values of `rv` to the referenced
   /// `stmt` and then returns the number of affected records.
@@ -25,7 +29,7 @@ pub trait Executor {
     &mut self,
     sc: SC,
     rv: RV,
-  ) -> impl Future<Output = Result<u64, <Self::Database as Database>::Error>>
+  ) -> impl Future<Output = Result<u64, <Self::Database as DEController>::Error>>
   where
     RV: RecordValues<Self::Database>,
     SC: StmtCmd;
@@ -37,7 +41,10 @@ pub trait Executor {
     sc: SC,
     rv: RV,
   ) -> impl Future<
-    Output = Result<<Self::Database as Database>::Record<'_>, <Self::Database as Database>::Error>,
+    Output = Result<
+      <Self::Database as Database>::Record<'_>,
+      <Self::Database as DEController>::Error,
+    >,
   >
   where
     RV: RecordValues<Self::Database>,
@@ -51,9 +58,12 @@ pub trait Executor {
     rv: RV,
     cb: impl FnMut(
       &<Self::Database as Database>::Record<'_>,
-    ) -> Result<(), <Self::Database as Database>::Error>,
+    ) -> Result<(), <Self::Database as DEController>::Error>,
   ) -> impl Future<
-    Output = Result<<Self::Database as Database>::Records<'_>, <Self::Database as Database>::Error>,
+    Output = Result<
+      <Self::Database as Database>::Records<'_>,
+      <Self::Database as DEController>::Error,
+    >,
   >
   where
     RV: RecordValues<Self::Database>,
@@ -66,7 +76,7 @@ pub trait Executor {
   fn prepare(
     &mut self,
     cmd: &str,
-  ) -> impl Future<Output = Result<u64, <Self::Database as Database>::Error>>;
+  ) -> impl Future<Output = Result<u64, <Self::Database as DEController>::Error>>;
 
   /// Retrieves a record and maps it to `T`. See [`FromRecord`].
   #[inline]
@@ -74,7 +84,7 @@ pub trait Executor {
     &mut self,
     cmd: &str,
     sv: SV,
-  ) -> impl Future<Output = Result<T, <Self::Database as Database>::Error>>
+  ) -> impl Future<Output = Result<T, <Self::Database as DEController>::Error>>
   where
     T: FromRecord<Self::Database>,
     SV: RecordValues<Self::Database>,
@@ -88,8 +98,8 @@ pub trait Executor {
     &mut self,
     cmd: &str,
     sv: SV,
-    mut cb: impl FnMut(T) -> Result<(), <Self::Database as Database>::Error>,
-  ) -> impl Future<Output = Result<(), <Self::Database as Database>::Error>>
+    mut cb: impl FnMut(T) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> impl Future<Output = Result<(), <Self::Database as DEController>::Error>>
   where
     SV: RecordValues<Self::Database>,
     T: FromRecord<Self::Database>,
@@ -104,24 +114,101 @@ pub trait Executor {
   fn transaction<'this, F, R>(
     &'this mut self,
     fun: impl FnOnce(&'this mut Self) -> F,
-  ) -> impl Future<Output = Result<R, <Self::Database as Database>::Error>>
+  ) -> impl Future<Output = Result<R, <Self::Database as DEController>::Error>>
   where
-    F: Future<Output = Result<(R, &'this mut Self), <Self::Database as Database>::Error>>,
+    F: Future<Output = Result<(R, &'this mut Self), <Self::Database as DEController>::Error>>,
   {
     async move {
-      self.execute("BEGIN", |_| {}).await?;
+      self.execute("BEGIN", |_| Ok(())).await?;
       let (rslt, this) = fun(self).await?;
-      this.execute("COMMIT", |_| {}).await?;
+      this.execute("COMMIT", |_| Ok(())).await?;
       Ok(rslt)
     }
   }
 }
 
+impl<T> Executor for &mut T
+where
+  T: Executor,
+{
+  type Database = T::Database;
+
+  #[inline]
+  fn connection_state(&self) -> ConnectionState {
+    (**self).connection_state()
+  }
+
+  #[inline]
+  async fn execute(
+    &mut self,
+    cmd: &str,
+    cb: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> Result<(), <Self::Database as DEController>::Error> {
+    (**self).execute(cmd, cb).await
+  }
+
+  #[inline]
+  async fn execute_with_stmt<SC, RV>(
+    &mut self,
+    sc: SC,
+    rv: RV,
+  ) -> Result<u64, <Self::Database as DEController>::Error>
+  where
+    RV: RecordValues<Self::Database>,
+    SC: StmtCmd,
+  {
+    (**self).execute_with_stmt(sc, rv).await
+  }
+
+  #[inline]
+  async fn fetch_many_with_stmt<SC, RV>(
+    &mut self,
+    sc: SC,
+    rv: RV,
+    cb: impl FnMut(
+      &<Self::Database as Database>::Record<'_>,
+    ) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> Result<<Self::Database as Database>::Records<'_>, <Self::Database as DEController>::Error>
+  where
+    RV: RecordValues<Self::Database>,
+    SC: StmtCmd,
+  {
+    (**self).fetch_many_with_stmt(sc, rv, cb).await
+  }
+
+  #[inline]
+  async fn fetch_with_stmt<S, RV>(
+    &mut self,
+    sc: S,
+    rv: RV,
+  ) -> Result<<Self::Database as Database>::Record<'_>, <Self::Database as DEController>::Error>
+  where
+    RV: RecordValues<Self::Database>,
+    S: StmtCmd,
+  {
+    (**self).fetch_with_stmt(sc, rv).await
+  }
+
+  #[inline]
+  async fn prepare(&mut self, cmd: &str) -> Result<u64, <Self::Database as DEController>::Error> {
+    (**self).prepare(cmd).await
+  }
+}
+
 impl Executor for () {
   type Database = ();
 
   #[inline]
-  async fn execute(&mut self, _: &str, _: impl FnMut(u64)) -> crate::Result<()> {
+  fn connection_state(&self) -> ConnectionState {
+    ConnectionState::Closed
+  }
+
+  #[inline]
+  async fn execute(
+    &mut self,
+    _: &str,
+    _: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> crate::Result<()> {
     Ok(())
   }
 
@@ -130,7 +217,7 @@ impl Executor for () {
     &mut self,
     _: SC,
     _: RV,
-  ) -> Result<u64, <Self::Database as Database>::Error>
+  ) -> Result<u64, <Self::Database as DEController>::Error>
   where
     RV: RecordValues<Self::Database>,
     SC: StmtCmd,
@@ -143,7 +230,7 @@ impl Executor for () {
     &mut self,
     _: S,
     _: RV,
-  ) -> Result<<Self::Database as Database>::Record<'_>, <Self::Database as Database>::Error>
+  ) -> Result<<Self::Database as Database>::Record<'_>, <Self::Database as DEController>::Error>
   where
     RV: RecordValues<Self::Database>,
     S: StmtCmd,
@@ -158,8 +245,8 @@ impl Executor for () {
     _: RV,
     _: impl FnMut(
       &<Self::Database as Database>::Record<'_>,
-    ) -> Result<(), <Self::Database as Database>::Error>,
-  ) -> Result<(), <Self::Database as Database>::Error>
+    ) -> Result<(), <Self::Database as DEController>::Error>,
+  ) -> Result<<Self::Database as Database>::Records<'_>, <Self::Database as DEController>::Error>
   where
     RV: RecordValues<Self::Database>,
     SC: StmtCmd,
@@ -168,12 +255,7 @@ impl Executor for () {
   }
 
   #[inline]
-  fn connection_state(&self) -> ConnectionState {
-    ConnectionState::Closed
-  }
-
-  #[inline]
-  async fn prepare(&mut self, _: &str) -> Result<u64, <Self::Database as Database>::Error> {
+  async fn prepare(&mut self, _: &str) -> Result<u64, <Self::Database as DEController>::Error> {
     Ok(0)
   }
 }
diff --git a/wtx/src/database/misc.rs b/wtx/src/database/misc.rs
index 5f825ce1..c617af5a 100644
--- a/wtx/src/database/misc.rs
+++ b/wtx/src/database/misc.rs
@@ -1,4 +1,7 @@
-use crate::database::{records::Records, Database, Decode, FromRecords, Record};
+use crate::{
+  database::{Database, FromRecords, Record, records::Records},
+  misc::Decode,
+};
 
 /// Seeks all rows that have an ID equal to `parent_record_id`.
 #[inline]
diff --git a/wtx/src/database/record.rs b/wtx/src/database/record.rs
index 1a9bef2f..9787cf1e 100644
--- a/wtx/src/database/record.rs
+++ b/wtx/src/database/record.rs
@@ -1,21 +1,24 @@
+use crate::{
+  database::{Database, DatabaseError, ValueIdent},
+  misc::{DEController, Decode},
+};
 use core::any::type_name;
 
-use crate::database::{Database, DatabaseError, Decode, ValueIdent};
-
 /// A collection of values.
 pub trait Record<'exec>: Sized {
   /// See [Database].
-  type Database: Database;
+  type Database: Database<Aux = ()>;
 
   /// Tries to retrieve and decode a value.
   #[inline]
-  fn decode<CI, D>(&self, ci: CI) -> Result<D, <Self::Database as Database>::Error>
+  fn decode<CI, D>(&self, ci: CI) -> Result<D, <Self::Database as DEController>::Error>
   where
     CI: ValueIdent<Self>,
     D: Decode<'exec, Self::Database>,
   {
     D::decode(
-      &self
+      &mut (),
+      &mut self
         .value(ci)
         .ok_or_else(|| DatabaseError::MissingFieldDataInDecoding(type_name::<D>()).into())?,
     )
@@ -23,13 +26,13 @@ pub trait Record<'exec>: Sized {
 
   /// Tries to retrieve and decode an optional value.
   #[inline]
-  fn decode_opt<CI, D>(&self, ci: CI) -> Result<Option<D>, <Self::Database as Database>::Error>
+  fn decode_opt<CI, D>(&self, ci: CI) -> Result<Option<D>, <Self::Database as DEController>::Error>
   where
     CI: ValueIdent<Self>,
     D: Decode<'exec, Self::Database>,
   {
     match self.value(ci) {
-      Some(elem) => Ok(Some(D::decode(&elem)?)),
+      Some(mut elem) => Ok(Some(D::decode(&mut (), &mut elem)?)),
       None => Ok(None),
     }
   }
@@ -38,7 +41,7 @@ pub trait Record<'exec>: Sized {
   fn len(&self) -> usize;
 
   /// Tries to retrieve a value.
-  fn value<CI>(&self, ci: CI) -> Option<<Self::Database as Database>::DecodeValue<'exec>>
+  fn value<CI>(&self, ci: CI) -> Option<<Self::Database as DEController>::DecodeWrapper<'exec, '_>>
   where
     CI: ValueIdent<Self>;
 }
@@ -52,7 +55,7 @@ impl Record<'_> for () {
   }
 
   #[inline]
-  fn value<CI>(&self, _: CI) -> Option<<Self::Database as Database>::DecodeValue<'_>>
+  fn value<CI>(&self, _: CI) -> Option<<Self::Database as DEController>::DecodeWrapper<'_, '_>>
   where
     CI: ValueIdent<Self>,
   {
diff --git a/wtx/src/database/record_values.rs b/wtx/src/database/record_values.rs
index 1446294c..77aaaa67 100644
--- a/wtx/src/database/record_values.rs
+++ b/wtx/src/database/record_values.rs
@@ -1,6 +1,6 @@
 use crate::{
-  database::{Database, Encode},
-  misc::{Lease, Wrapper},
+  database::Database,
+  misc::{Encode, Lease, Wrapper},
 };
 
 /// Values that can passed to a record as parameters. For example, in a query.
@@ -10,15 +10,18 @@ where
 {
   /// Converts the inner values into a byte representation.
   fn encode_values<'buffer, 'tmp, A>(
-    &mut self,
+    &self,
     aux: &mut A,
-    ev: &mut D::EncodeValue<'buffer, 'tmp>,
-    prefix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>) -> usize,
-    suffix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>, bool, usize) -> usize,
+    ew: &mut D::EncodeWrapper<'buffer, 'tmp>,
+    prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>) -> usize,
+    suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>, bool, usize) -> usize,
   ) -> Result<usize, D::Error>
   where
     'buffer: 'tmp;
 
+  /// Walks through all elements stating if they are null.
+  fn is_null(&self, cb: impl FnMut(bool) -> Result<(), D::Error>) -> Result<(), D::Error>;
+
   /// The number of values
   fn len(&self) -> usize;
 }
@@ -30,13 +33,18 @@ where
 {
   #[inline]
   fn encode_values<'buffer, 'tmp, A>(
-    &mut self,
+    &self,
     aux: &mut A,
-    ev: &mut D::EncodeValue<'buffer, 'tmp>,
-    prefix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>) -> usize,
-    suffix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>, bool, usize) -> usize,
+    ew: &mut D::EncodeWrapper<'buffer, 'tmp>,
+    prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>) -> usize,
+    suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>, bool, usize) -> usize,
   ) -> Result<usize, D::Error> {
-    (**self).encode_values(aux, ev, prefix_cb, suffix_cb)
+    (**self).encode_values(aux, ew, prefix_cb, suffix_cb)
+  }
+
+  #[inline]
+  fn is_null(&self, cb: impl FnMut(bool) -> Result<(), D::Error>) -> Result<(), D::Error> {
+    (**self).is_null(cb)
   }
 
   #[inline]
@@ -47,24 +55,32 @@ where
 
 impl<D, T> RecordValues<D> for &[T]
 where
-  D: Database,
+  D: Database<Aux = ()>,
   T: Encode<D>,
 {
   #[inline]
   fn encode_values<'buffer, 'tmp, A>(
-    &mut self,
+    &self,
     aux: &mut A,
-    ev: &mut D::EncodeValue<'buffer, 'tmp>,
-    mut prefix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>) -> usize,
-    mut suffix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>, bool, usize) -> usize,
+    ew: &mut D::EncodeWrapper<'buffer, 'tmp>,
+    mut prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>) -> usize,
+    mut suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>, bool, usize) -> usize,
   ) -> Result<usize, D::Error> {
     let mut n: usize = 0;
     for elem in *self {
-      encode(aux, elem, ev, &mut n, &mut prefix_cb, &mut suffix_cb)?;
+      encode(aux, elem, ew, &mut n, &mut prefix_cb, &mut suffix_cb)?;
     }
     Ok(n)
   }
 
+  #[inline]
+  fn is_null(&self, mut cb: impl FnMut(bool) -> Result<(), D::Error>) -> Result<(), D::Error> {
+    for elem in *self {
+      cb(elem.is_null())?;
+    }
+    Ok(())
+  }
+
   #[inline]
   fn len(&self) -> usize {
     (*self).len()
@@ -73,25 +89,33 @@ where
 
 impl<D, I, T> RecordValues<D> for Wrapper<I>
 where
-  D: Database,
-  I: Iterator<Item = T>,
+  D: Database<Aux = ()>,
+  I: Clone + Iterator<Item = T>,
   T: Encode<D>,
 {
   #[inline]
   fn encode_values<'buffer, 'tmp, A>(
-    &mut self,
+    &self,
     aux: &mut A,
-    ev: &mut D::EncodeValue<'buffer, 'tmp>,
-    mut prefix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>) -> usize,
-    mut suffix_cb: impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>, bool, usize) -> usize,
+    ew: &mut D::EncodeWrapper<'buffer, 'tmp>,
+    mut prefix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>) -> usize,
+    mut suffix_cb: impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>, bool, usize) -> usize,
   ) -> Result<usize, D::Error> {
     let mut n: usize = 0;
-    for elem in self.0.by_ref() {
-      encode(aux, &elem, ev, &mut n, &mut prefix_cb, &mut suffix_cb)?;
+    for elem in self.0.clone() {
+      encode(aux, &elem, ew, &mut n, &mut prefix_cb, &mut suffix_cb)?;
     }
     Ok(n)
   }
 
+  #[inline]
+  fn is_null(&self, mut cb: impl FnMut(bool) -> Result<(), D::Error>) -> Result<(), D::Error> {
+    for elem in self.0.clone() {
+      cb(elem.is_null())?;
+    }
+    Ok(())
+  }
+
   #[inline]
   fn len(&self) -> usize {
     let (l, u) = self.0.size_hint();
@@ -102,20 +126,20 @@ where
 pub(crate) fn encode<'buffer, 'tmp, A, D, T>(
   aux: &mut A,
   elem: &T,
-  ev: &mut D::EncodeValue<'buffer, 'tmp>,
+  ew: &mut D::EncodeWrapper<'buffer, 'tmp>,
   n: &mut usize,
-  prefix_cb: &mut impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>) -> usize,
-  suffix_cb: &mut impl FnMut(&mut A, &mut D::EncodeValue<'buffer, 'tmp>, bool, usize) -> usize,
+  prefix_cb: &mut impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>) -> usize,
+  suffix_cb: &mut impl FnMut(&mut A, &mut D::EncodeWrapper<'buffer, 'tmp>, bool, usize) -> usize,
 ) -> Result<(), D::Error>
 where
-  D: Database,
+  D: Database<Aux = ()>,
   T: Encode<D>,
 {
-  *n = n.wrapping_add(prefix_cb(aux, ev));
-  let elem_before = ev.lease()._len();
-  elem.encode(ev)?;
-  let elem_len = ev.lease()._len().wrapping_sub(elem_before);
+  *n = n.wrapping_add(prefix_cb(aux, ew));
+  let elem_before = ew.lease().len();
+  elem.encode(&mut (), ew)?;
+  let elem_len = ew.lease().len().wrapping_sub(elem_before);
   *n = n.wrapping_add(elem_len);
-  *n = n.wrapping_add(suffix_cb(aux, ev, elem.is_null(), elem_len));
+  *n = n.wrapping_add(suffix_cb(aux, ew, elem.is_null(), elem_len));
   Ok(())
 }
diff --git a/wtx/src/database/schema_manager.rs b/wtx/src/database/schema_manager.rs
index 701db858..bcffd30d 100644
--- a/wtx/src/database/schema_manager.rs
+++ b/wtx/src/database/schema_manager.rs
@@ -23,7 +23,7 @@ mod schema_manager_error;
 pub mod toml_parser;
 
 use crate::{
-  database::{executor::Executor, DatabaseTy, Identifier},
+  database::{DatabaseTy, Identifier, executor::Executor},
   misc::{Lease, Vector},
 };
 use alloc::string::String;
@@ -38,7 +38,8 @@ pub const DEFAULT_BATCH_SIZE: usize = 128;
 /// Default configuration file name.
 pub const DEFAULT_CFG_FILE_NAME: &str = "wtx.toml";
 pub(crate) const _WTX: &str = "wtx";
-pub(crate) const _WTX_SCHEMA_PREFIX: &str = "_wtx.";
+pub(crate) const _WTX_PREFIX: &str = "_wtx";
+pub(crate) const _WTX_SCHEMA: &str = "_wtx.";
 
 /// Useful in constant environments where the type must be explicitly declared.
 ///
@@ -166,26 +167,112 @@ impl SchemaManagement for () {
   }
 }
 
-#[cfg(feature = "postgres")]
-mod postgres {
+#[cfg(feature = "mysql")]
+mod mysql {
+  use crate::{
+    database::{
+      DatabaseTy, Executor as _, Identifier,
+      client::mysql::{ExecutorBuffer, MysqlExecutor},
+      schema_manager::{
+        _WTX_PREFIX, DbMigration, MigrationGroup, SchemaManagement, UserMigration,
+        fixed_sql_commands::{
+          _delete_migrations, _insert_migrations, _migrations_by_mg_version_query,
+          mysql::{_CREATE_MIGRATION_TABLES, _clear, _table_names},
+        },
+      },
+    },
+    misc::{Lease, LeaseMut, Stream, Vector},
+  };
   use alloc::string::String;
 
+  impl<EB, STREAM> SchemaManagement for MysqlExecutor<crate::Error, EB, STREAM>
+  where
+    EB: LeaseMut<ExecutorBuffer>,
+    STREAM: Stream,
+  {
+    #[inline]
+    async fn clear(&mut self, _: (&mut String, &mut Vector<Identifier>)) -> crate::Result<()> {
+      _clear(self).await
+    }
+
+    #[inline]
+    async fn create_wtx_tables(&mut self) -> crate::Result<()> {
+      self.execute(_CREATE_MIGRATION_TABLES, |_| Ok(())).await?;
+      Ok(())
+    }
+
+    #[inline]
+    async fn delete_migrations<S>(
+      &mut self,
+      buffer_cmd: &mut String,
+      mg: &MigrationGroup<S>,
+      version: i32,
+    ) -> crate::Result<()>
+    where
+      S: Lease<str>,
+    {
+      _delete_migrations(buffer_cmd, self, mg, _WTX_PREFIX, version).await
+    }
+
+    #[inline]
+    async fn insert_migrations<'migration, DBS, I, S>(
+      &mut self,
+      buffer_cmd: &mut String,
+      mg: &MigrationGroup<S>,
+      migrations: I,
+    ) -> crate::Result<()>
+    where
+      DBS: Lease<[DatabaseTy]> + 'migration,
+      I: Clone + Iterator<Item = &'migration UserMigration<DBS, S>>,
+      S: Lease<str> + 'migration,
+    {
+      _insert_migrations(buffer_cmd, self, mg, migrations, _WTX_PREFIX).await
+    }
+
+    #[inline]
+    async fn migrations<S>(
+      &mut self,
+      buffer_cmd: &mut String,
+      mg: &MigrationGroup<S>,
+      results: &mut Vector<DbMigration>,
+    ) -> crate::Result<()>
+    where
+      S: Lease<str>,
+    {
+      _migrations_by_mg_version_query(buffer_cmd, self, mg.version(), results, _WTX_PREFIX).await
+    }
+
+    #[inline]
+    async fn table_names(
+      &mut self,
+      _: &mut String,
+      results: &mut Vector<Identifier>,
+      _: &str,
+    ) -> crate::Result<()> {
+      _table_names(self, results).await
+    }
+  }
+}
+
+#[cfg(feature = "postgres")]
+mod postgres {
   use crate::{
     database::{
-      client::postgres::{Executor, ExecutorBuffer},
+      DatabaseTy, Executor as _, Identifier,
+      client::postgres::{ExecutorBuffer, PostgresExecutor},
       schema_manager::{
+        _WTX_SCHEMA, DbMigration, MigrationGroup, SchemaManagement, UserMigration,
         fixed_sql_commands::{
           _delete_migrations, _insert_migrations, _migrations_by_mg_version_query,
-          postgres::{_clear, _table_names, _CREATE_MIGRATION_TABLES},
+          postgres::{_CREATE_MIGRATION_TABLES, _clear, _table_names},
         },
-        DbMigration, MigrationGroup, SchemaManagement, UserMigration, _WTX_SCHEMA_PREFIX,
       },
-      DatabaseTy, Executor as _, Identifier,
     },
     misc::{Lease, LeaseMut, Stream, Vector},
   };
+  use alloc::string::String;
 
-  impl<EB, STREAM> SchemaManagement for Executor<crate::Error, EB, STREAM>
+  impl<EB, STREAM> SchemaManagement for PostgresExecutor<crate::Error, EB, STREAM>
   where
     EB: LeaseMut<ExecutorBuffer>,
     STREAM: Stream,
@@ -197,7 +284,7 @@ mod postgres {
 
     #[inline]
     async fn create_wtx_tables(&mut self) -> crate::Result<()> {
-      self.execute(_CREATE_MIGRATION_TABLES, |_| {}).await?;
+      self.execute(_CREATE_MIGRATION_TABLES, |_| Ok(())).await?;
       Ok(())
     }
 
@@ -211,7 +298,7 @@ mod postgres {
     where
       S: Lease<str>,
     {
-      _delete_migrations(buffer_cmd, self, mg, _WTX_SCHEMA_PREFIX, version).await
+      _delete_migrations(buffer_cmd, self, mg, _WTX_SCHEMA, version).await
     }
 
     #[inline]
@@ -226,7 +313,7 @@ mod postgres {
       I: Clone + Iterator<Item = &'migration UserMigration<DBS, S>>,
       S: Lease<str> + 'migration,
     {
-      _insert_migrations(buffer_cmd, self, mg, migrations, _WTX_SCHEMA_PREFIX).await
+      _insert_migrations(buffer_cmd, self, mg, migrations, _WTX_SCHEMA).await
     }
 
     #[inline]
@@ -239,8 +326,7 @@ mod postgres {
     where
       S: Lease<str>,
     {
-      _migrations_by_mg_version_query(buffer_cmd, self, mg.version(), results, _WTX_SCHEMA_PREFIX)
-        .await
+      _migrations_by_mg_version_query(buffer_cmd, self, mg.version(), results, _WTX_SCHEMA).await
     }
 
     #[inline]
diff --git a/wtx/src/database/schema_manager/commands.rs b/wtx/src/database/schema_manager/commands.rs
index 54b7673a..96185deb 100644
--- a/wtx/src/database/schema_manager/commands.rs
+++ b/wtx/src/database/schema_manager/commands.rs
@@ -8,9 +8,9 @@ mod validate;
 
 use crate::{
   database::{
-    executor::Executor,
-    schema_manager::{UserMigration, DEFAULT_BATCH_SIZE},
     Database, DatabaseTy,
+    executor::Executor,
+    schema_manager::{DEFAULT_BATCH_SIZE, UserMigration},
   },
   misc::Lease,
 };
@@ -56,11 +56,7 @@ where
     S: Lease<str> + 'migration,
   {
     migrations.filter(move |m| {
-      if m.dbs().is_empty() {
-        true
-      } else {
-        m.dbs().contains(&<E::Database as Database>::TY)
-      }
+      if m.dbs().is_empty() { true } else { m.dbs().contains(&<E::Database as Database>::TY) }
     })
   }
 }
diff --git a/wtx/src/database/schema_manager/commands/clear.rs b/wtx/src/database/schema_manager/commands/clear.rs
index cf251961..96e54b42 100644
--- a/wtx/src/database/schema_manager/commands/clear.rs
+++ b/wtx/src/database/schema_manager/commands/clear.rs
@@ -1,7 +1,7 @@
 use crate::{
   database::{
-    schema_manager::{Commands, SchemaManagement},
     Identifier,
+    schema_manager::{Commands, SchemaManagement},
   },
   misc::Vector,
 };
diff --git a/wtx/src/database/schema_manager/commands/migrate.rs b/wtx/src/database/schema_manager/commands/migrate.rs
index 5665b0b7..faeb63b9 100644
--- a/wtx/src/database/schema_manager/commands/migrate.rs
+++ b/wtx/src/database/schema_manager/commands/migrate.rs
@@ -1,7 +1,7 @@
 use crate::{
   database::{
-    schema_manager::{Commands, DbMigration, MigrationGroup, SchemaManagement, UserMigration},
     DatabaseTy,
+    schema_manager::{Commands, DbMigration, MigrationGroup, SchemaManagement, UserMigration},
   },
   misc::{Lease, Vector},
 };
diff --git a/wtx/src/database/schema_manager/commands/rollback.rs b/wtx/src/database/schema_manager/commands/rollback.rs
index c9957f6d..3e5733aa 100644
--- a/wtx/src/database/schema_manager/commands/rollback.rs
+++ b/wtx/src/database/schema_manager/commands/rollback.rs
@@ -1,15 +1,15 @@
 use crate::{
   database::{
+    DatabaseTy,
     schema_manager::{Commands, DbMigration, MigrationGroup, SchemaManagement, UserMigration},
-    Database, DatabaseTy,
   },
-  misc::{Lease, Vector},
+  misc::{DEController, Lease, Vector},
 };
 use alloc::string::String;
 #[cfg(feature = "std")]
 use {
-  crate::database::schema_manager::misc::{group_and_migrations_from_path, parse_root_toml},
   crate::database::schema_manager::SchemaManagerError,
+  crate::database::schema_manager::misc::{group_and_migrations_from_path, parse_root_toml},
   std::path::Path,
 };
 
@@ -27,7 +27,7 @@ where
     mg: &MigrationGroup<S>,
     migrations: I,
     version: i32,
-  ) -> Result<(), <E::Database as Database>::Error>
+  ) -> Result<(), <E::Database as DEController>::Error>
   where
     DBS: Lease<[DatabaseTy]> + 'migration,
     I: Clone + Iterator<Item = &'migration UserMigration<DBS, S>>,
@@ -42,7 +42,7 @@ where
     self
       .executor
       .transaction(|this| async {
-        this.execute(buffer_cmd.as_str(), |_| {}).await?;
+        this.execute(buffer_cmd.as_str(), |_| Ok(())).await?;
         Ok(((), this))
       })
       .await?;
@@ -60,7 +60,7 @@ where
     (buffer_cmd, buffer_db_migrations): (&mut String, &mut Vector<DbMigration>),
     path: &Path,
     versions: &[i32],
-  ) -> Result<(), <E::Database as Database>::Error> {
+  ) -> Result<(), <E::Database as DEController>::Error> {
     let (mut migration_groups, _) = parse_root_toml(path)?;
     if migration_groups.len() != versions.len() {
       return Err(crate::Error::from(SchemaManagerError::DifferentRollbackVersions).into());
@@ -80,7 +80,7 @@ where
     buffer: (&mut String, &mut Vector<DbMigration>),
     path: &Path,
     version: i32,
-  ) -> Result<(), <E::Database as Database>::Error> {
+  ) -> Result<(), <E::Database as DEController>::Error> {
     self.do_rollback_from_dir(buffer, path, version).await
   }
 
@@ -91,7 +91,7 @@ where
     (buffer_cmd, buffer_db_migrations): (&mut String, &mut Vector<DbMigration>),
     path: &Path,
     version: i32,
-  ) -> Result<(), <E::Database as Database>::Error> {
+  ) -> Result<(), <E::Database as DEController>::Error> {
     let opt = group_and_migrations_from_path(path, |a, b| b.cmp(a));
     let Ok((mg, mut migrations)) = opt else { return Ok(()) };
     let mut tmp_migrations = Vector::new();
diff --git a/wtx/src/database/schema_manager/commands/seed.rs b/wtx/src/database/schema_manager/commands/seed.rs
index 0ae21c59..0eb8a716 100644
--- a/wtx/src/database/schema_manager/commands/seed.rs
+++ b/wtx/src/database/schema_manager/commands/seed.rs
@@ -1,6 +1,6 @@
 use crate::{
-  database::{executor::Executor, schema_manager::Commands, Database},
-  misc::Lease,
+  database::{executor::Executor, schema_manager::Commands},
+  misc::{DEController, Lease},
 };
 use alloc::string::String;
 #[cfg(feature = "std")]
@@ -18,7 +18,7 @@ where
     &mut self,
     buffer_cmd: &mut String,
     seeds: I,
-  ) -> Result<(), <E::Database as Database>::Error>
+  ) -> Result<(), <E::Database as DEController>::Error>
   where
     I: Iterator<Item = S>,
     S: Lease<str>,
@@ -29,7 +29,7 @@ where
     self
       .executor
       .transaction(|this| async {
-        this.execute(buffer_cmd.as_str(), |_| {}).await?;
+        this.execute(buffer_cmd.as_str(), |_| Ok(())).await?;
         Ok(((), this))
       })
       .await?;
@@ -44,7 +44,7 @@ where
     &mut self,
     buffer_cmd: &mut String,
     dir: &Path,
-  ) -> Result<(), <E::Database as Database>::Error> {
+  ) -> Result<(), <E::Database as DEController>::Error> {
     let iter = crate::database::schema_manager::misc::files(dir)?.filter_map(|el_rslt| {
       let el = el_rslt.ok()?;
       read_to_string(el.path()).ok()
diff --git a/wtx/src/database/schema_manager/commands/validate.rs b/wtx/src/database/schema_manager/commands/validate.rs
index 8afbcaba..f47e892b 100644
--- a/wtx/src/database/schema_manager/commands/validate.rs
+++ b/wtx/src/database/schema_manager/commands/validate.rs
@@ -1,10 +1,10 @@
 use crate::{
   database::{
+    DatabaseTy,
     schema_manager::{
-      misc::is_migration_divergent, Commands, DbMigration, MigrationGroup, Repeatability,
-      SchemaManagement, SchemaManagerError, UserMigration,
+      Commands, DbMigration, MigrationGroup, Repeatability, SchemaManagement, SchemaManagerError,
+      UserMigration, misc::is_migration_divergent,
     },
-    DatabaseTy,
   },
   misc::{Lease, Vector},
 };
diff --git a/wtx/src/database/schema_manager/fixed_sql_commands.rs b/wtx/src/database/schema_manager/fixed_sql_commands.rs
index 1e6e0281..80a42ee5 100644
--- a/wtx/src/database/schema_manager/fixed_sql_commands.rs
+++ b/wtx/src/database/schema_manager/fixed_sql_commands.rs
@@ -25,16 +25,18 @@ macro_rules! _serial_id {
   };
 }
 
+#[cfg(feature = "mysql")]
+pub(crate) mod mysql;
 #[cfg(feature = "postgres")]
 pub(crate) mod postgres;
 
 use crate::{
   database::{
+    Database, DatabaseTy, FromRecord,
     executor::Executor,
     schema_manager::{DbMigration, MigrationGroup, UserMigration},
-    Database, DatabaseTy, FromRecord,
   },
-  misc::{Lease, Vector},
+  misc::{DEController, Lease, Vector},
 };
 use alloc::string::String;
 use core::fmt::Write;
@@ -46,7 +48,7 @@ pub(crate) async fn _delete_migrations<E, S>(
   mg: &MigrationGroup<S>,
   schema_prefix: &str,
   version: i32,
-) -> crate::Result<()>
+) -> Result<(), <E::Database as DEController>::Error>
 where
   E: Executor,
   S: Lease<str>,
@@ -54,8 +56,8 @@ where
   buffer_cmd.write_fmt(format_args!(
     "DELETE FROM {schema_prefix}_wtx_migration WHERE _wtx_migration_omg_version = {mg_version} AND version > {version}",
     mg_version = mg.version(),
-  ))?;
-  executor.execute(buffer_cmd.as_str(), |_| {}).await?;
+  )).map_err(crate::Error::from)?;
+  executor.execute(buffer_cmd.as_str(), |_| Ok(())).await?;
   buffer_cmd.clear();
   Ok(())
 }
@@ -67,7 +69,7 @@ pub(crate) async fn _insert_migrations<'migration, DBS, E, I, S>(
   mg: &MigrationGroup<S>,
   migrations: I,
   schema_prefix: &str,
-) -> Result<(), <E::Database as Database>::Error>
+) -> Result<(), <E::Database as DEController>::Error>
 where
   DBS: Lease<[DatabaseTy]> + 'migration,
   E: Executor,
@@ -85,7 +87,7 @@ where
       mg_version = mg.version(),
     ))
     .map_err(Into::into)?;
-  executor.execute(buffer_cmd.as_str(), |_| {}).await?;
+  executor.execute(buffer_cmd.as_str(), |_| Ok(())).await?;
   buffer_cmd.clear();
 
   for migration in migrations.clone() {
@@ -93,7 +95,7 @@ where
   }
   executor
     .transaction(|this| async {
-      this.execute(buffer_cmd.as_str(), |_| {}).await?;
+      this.execute(buffer_cmd.as_str(), |_| Ok(())).await?;
       Ok(((), this))
     })
     .await?;
@@ -117,7 +119,7 @@ where
   }
   executor
     .transaction(|this| async {
-      this.execute(buffer_cmd.as_str(), |_| {}).await?;
+      this.execute(buffer_cmd.as_str(), |_| Ok(())).await?;
       Ok(((), this))
     })
     .await?;
@@ -135,7 +137,7 @@ pub(crate) async fn _migrations_by_mg_version_query<E, D>(
   schema_prefix: &str,
 ) -> crate::Result<()>
 where
-  D: Database<Error = crate::Error>,
+  D: Database<Aux = (), Error = crate::Error>,
   E: Executor<Database = D>,
   DbMigration: FromRecord<E::Database>,
 {
diff --git a/wtx/src/database/schema_manager/fixed_sql_commands/mysql.rs b/wtx/src/database/schema_manager/fixed_sql_commands/mysql.rs
new file mode 100644
index 00000000..eaf44262
--- /dev/null
+++ b/wtx/src/database/schema_manager/fixed_sql_commands/mysql.rs
@@ -0,0 +1,71 @@
+use crate::{
+  database::{Executor, Identifier, client::mysql::Mysql},
+  misc::Vector,
+};
+
+pub(crate) const _CREATE_MIGRATION_TABLES: &str = concat!(
+  "CREATE TABLE IF NOT EXISTS _oapth_migration_group (",
+  _wtx_migration_group_columns!(),
+  ");
+  CREATE TABLE IF NOT EXISTS _oapth_migration (",
+  _serial_id!(),
+  "created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,",
+  _wtx_migration_columns!(),
+  ");"
+);
+
+// https://stackoverflow.com/questions/12403662/how-to-remove-all-mysql-tables-from-the-command-line-without-drop-database-permi/18625545#18625545
+#[inline]
+pub(crate) async fn _clear<E>(executor: &mut E) -> crate::Result<()>
+where
+  E: Executor<Database = Mysql<crate::Error>>,
+{
+  let cmd = "
+    SET FOREIGN_KEY_CHECKS = 0;
+    SET GROUP_CONCAT_MAX_LEN=32768;
+    SET @tables = NULL;
+    SELECT GROUP_CONCAT('`', table_name, '`') INTO @tables
+      FROM information_schema.tables
+      WHERE table_schema = (SELECT DATABASE());
+    SELECT IFNULL(@tables,'dummy') INTO @tables;
+
+    SET @tables = CONCAT('DROP TABLE IF EXISTS ', @tables);
+    PREPARE stmt FROM @tables;
+    EXECUTE stmt;
+    DEALLOCATE PREPARE stmt;
+    SET FOREIGN_KEY_CHECKS = 1;
+  ";
+  executor
+    .transaction(|this| async {
+      this.execute(cmd, |_| Ok(())).await?;
+      Ok(((), this))
+    })
+    .await?;
+  Ok(())
+}
+
+// https://github.com/flyway/flyway/blob/master/flyway-core/src/main/java/org/flywaydb/core/internal/database/mysql/MySQLSchema.java
+#[inline]
+pub(crate) async fn _table_names<E>(
+  executor: &mut E,
+  results: &mut Vector<Identifier>,
+) -> crate::Result<()>
+where
+  E: Executor<Database = Mysql<crate::Error>>,
+{
+  let cmd = "
+    SELECT
+      all_tables.table_name AS table_name
+    FROM
+      information_schema.tables AS all_tables
+    WHERE
+      all_tables.table_type IN ('BASE TABLE', 'SYSTEM VERSIONED')
+  ";
+  executor
+    .simple_entities(cmd, (), |result| {
+      results.push(result)?;
+      Ok(())
+    })
+    .await?;
+  Ok(())
+}
diff --git a/wtx/src/database/schema_manager/fixed_sql_commands/postgres.rs b/wtx/src/database/schema_manager/fixed_sql_commands/postgres.rs
index 79314b84..17069d8d 100644
--- a/wtx/src/database/schema_manager/fixed_sql_commands/postgres.rs
+++ b/wtx/src/database/schema_manager/fixed_sql_commands/postgres.rs
@@ -1,5 +1,5 @@
 use crate::{
-  database::{client::postgres::Postgres, executor::Executor, Identifier},
+  database::{Identifier, client::postgres::Postgres, executor::Executor},
   misc::Vector,
 };
 use alloc::string::String;
@@ -51,7 +51,7 @@ where
 
   executor
     .transaction(|this| async {
-      this.execute(buffer_cmd.as_str(), |_| {}).await?;
+      this.execute(buffer_cmd.as_str(), |_| Ok(())).await?;
       Ok(((), this))
     })
     .await?;
@@ -206,6 +206,7 @@ where
     .await
 }
 
+#[inline]
 pub(crate) async fn _table_names<E>(
   buffer_cmd: &mut String,
   executor: &mut E,
@@ -218,7 +219,7 @@ where
   let before = buffer_cmd.len();
   buffer_cmd.write_fmt(format_args!(
     "SELECT
-    tables.table_name AS generic_column
+      tables.table_name AS generic_column
     FROM
       information_schema.tables tables
       -- that don't depend on an extension
diff --git a/wtx/src/database/schema_manager/migration/db_migration.rs b/wtx/src/database/schema_manager/migration/db_migration.rs
index 92a2d1b2..fbbf5f22 100644
--- a/wtx/src/database/schema_manager/migration/db_migration.rs
+++ b/wtx/src/database/schema_manager/migration/db_migration.rs
@@ -1,10 +1,10 @@
 use crate::{
   database::{
+    DatabaseTy, Identifier,
     schema_manager::{
-      migration::migration_common::MigrationCommon, MigrationGroup, Repeatability,
-      SchemaManagerError,
+      MigrationGroup, Repeatability, SchemaManagerError,
+      migration::migration_common::MigrationCommon,
     },
-    DatabaseTy, Identifier,
   },
   misc::FromRadix10,
 };
@@ -58,13 +58,40 @@ impl DbMigration {
   }
 }
 
+#[cfg(feature = "mysql")]
+impl<E> crate::database::FromRecord<crate::database::client::mysql::Mysql<E>> for DbMigration
+where
+  E: From<crate::Error>,
+{
+  #[inline]
+  fn from_record(from: &crate::database::client::mysql::MysqlRecord<'_, E>) -> Result<Self, E> {
+    use crate::database::Record as _;
+    Ok(Self {
+      common: MigrationCommon {
+        checksum: _checksum_from_str(from.decode("checksum")?)?,
+        name: from.decode::<_, &str>("name")?.try_into()?,
+        repeatability: _from_u32(from.decode_opt("repeatability")?),
+        version: from.decode("version")?,
+      },
+      created_on: from.decode("created_on")?,
+      db_ty: DatabaseTy::Mysql,
+      group: MigrationGroup::new(
+        from.decode::<_, &str>("omg_name")?.try_into()?,
+        from.decode("omg_version")?,
+      ),
+    })
+  }
+}
+
 #[cfg(feature = "postgres")]
 impl<E> crate::database::FromRecord<crate::database::client::postgres::Postgres<E>> for DbMigration
 where
   E: From<crate::Error>,
 {
   #[inline]
-  fn from_record(from: &crate::database::client::postgres::Record<'_, E>) -> Result<Self, E> {
+  fn from_record(
+    from: &crate::database::client::postgres::PostgresRecord<'_, E>,
+  ) -> Result<Self, E> {
     use crate::database::Record as _;
     Ok(Self {
       common: MigrationCommon {
diff --git a/wtx/src/database/schema_manager/migration/user_migration.rs b/wtx/src/database/schema_manager/migration/user_migration.rs
index 342599d9..a3e0c76f 100644
--- a/wtx/src/database/schema_manager/migration/user_migration.rs
+++ b/wtx/src/database/schema_manager/migration/user_migration.rs
@@ -1,11 +1,11 @@
 use crate::{
   database::{
+    DatabaseTy,
     schema_manager::{
+      Repeatability,
       migration::migration_common::MigrationCommon,
       misc::{calc_checksum, is_sorted_and_unique},
-      Repeatability,
     },
-    DatabaseTy,
   },
   misc::{ArrayVector, Lease},
 };
diff --git a/wtx/src/database/schema_manager/migration_parser.rs b/wtx/src/database/schema_manager/migration_parser.rs
index 27e2e8db..af069536 100644
--- a/wtx/src/database/schema_manager/migration_parser.rs
+++ b/wtx/src/database/schema_manager/migration_parser.rs
@@ -2,13 +2,13 @@
 
 use crate::{
   database::{
+    DatabaseTy,
     schema_manager::{
-      toml_parser::{toml, Expr},
       Repeatability, SchemaManagerError,
+      toml_parser::{Expr, toml},
     },
-    DatabaseTy,
   },
-  misc::{str_split1, ArrayVector},
+  misc::{ArrayVector, str_split1},
 };
 use alloc::string::String;
 use std::io::{BufRead, BufReader, Read};
@@ -159,8 +159,8 @@ where
 #[cfg(test)]
 mod tests {
   use crate::database::{
-    schema_manager::{migration_parser::parse_unified_migration, Repeatability},
     DatabaseTy,
+    schema_manager::{Repeatability, migration_parser::parse_unified_migration},
   };
 
   #[test]
@@ -189,9 +189,9 @@ mod tests {
     let with_incorrect_declaration = parse_unified_migration(s.as_bytes()).unwrap();
     assert!(with_incorrect_declaration.cfg.dbs.is_empty());
 
-    let s = "-- wtx dbs mssql,postgres\n-- wtx IN\nSOMETHING";
+    let s = "-- wtx dbs mysql,postgres\n-- wtx IN\nSOMETHING";
     let two_dbs = parse_unified_migration(s.as_bytes()).unwrap();
-    assert_eq!(two_dbs.cfg.dbs[0], DatabaseTy::Mssql);
+    assert_eq!(two_dbs.cfg.dbs[0], DatabaseTy::Mysql);
     assert_eq!(two_dbs.cfg.dbs[1], DatabaseTy::Postgres);
   }
 
diff --git a/wtx/src/database/schema_manager/misc.rs b/wtx/src/database/schema_manager/misc.rs
index c5535d26..3b41b06f 100644
--- a/wtx/src/database/schema_manager/misc.rs
+++ b/wtx/src/database/schema_manager/misc.rs
@@ -9,11 +9,11 @@ macro_rules! opt_to_inv_mig {
 
 use crate::{
   database::{
+    DatabaseTy,
     schema_manager::{
-      migration::{DbMigration, UserMigration},
       SchemaManagerError,
+      migration::{DbMigration, UserMigration},
     },
-    DatabaseTy,
   },
   misc::Lease,
 };
@@ -22,15 +22,15 @@ use core::hash::{Hash, Hasher};
 use {
   crate::{
     database::schema_manager::{
-      toml_parser::{toml, Expr},
       MigrationGroup, Repeatability, UserMigrationOwned,
+      toml_parser::{Expr, toml},
     },
     misc::{ArrayVector, FromRadix10, Vector},
   },
   alloc::string::String,
   core::{cmp::Ordering, fmt::Write},
   std::{
-    fs::{read_to_string, DirEntry, File},
+    fs::{DirEntry, File, read_to_string},
     io::Read,
     path::{Path, PathBuf},
   },
@@ -71,8 +71,8 @@ where
 {
   use crate::{
     database::schema_manager::{
-      migration_parser::{parse_migration_toml, parse_unified_migration},
       SchemaManagerError,
+      migration_parser::{parse_migration_toml, parse_unified_migration},
     },
     misc::ArrayString,
   };
diff --git a/wtx/src/database/schema_manager/toml_parser.rs b/wtx/src/database/schema_manager/toml_parser.rs
index 11e42ad2..74a129e8 100644
--- a/wtx/src/database/schema_manager/toml_parser.rs
+++ b/wtx/src/database/schema_manager/toml_parser.rs
@@ -2,7 +2,7 @@
 
 use crate::{
   database::schema_manager::SchemaManagerError,
-  misc::{str_split1, ArrayString, ArrayVector},
+  misc::{ArrayString, ArrayVector, str_split1},
 };
 use alloc::string::String;
 use std::io::{BufRead, BufReader, Read};
@@ -145,7 +145,7 @@ fn parse_expr_string(s: &str) -> crate::Result<ExprStringTy> {
 #[cfg(test)]
 mod tests {
   use crate::{
-    database::schema_manager::toml_parser::{toml, Expr, ExprArrayTy},
+    database::schema_manager::toml_parser::{Expr, ExprArrayTy, toml},
     misc::ArrayVector,
   };
 
diff --git a/wtx/src/error.rs b/wtx/src/error.rs
index f9aea742..d17cfea5 100644
--- a/wtx/src/error.rs
+++ b/wtx/src/error.rs
@@ -40,8 +40,6 @@ pub enum Error {
   EmbassyNet(embassy_net::tcp::Error),
   #[cfg(feature = "base64")]
   EncodeSliceError(base64::EncodeSliceError),
-  #[cfg(feature = "embedded-tls")]
-  EmbassyTlsError(embedded_tls::TlsError),
   #[cfg(feature = "flate2")]
   Flate2CompressError(flate2::CompressError),
   #[cfg(feature = "flate2")]
@@ -62,8 +60,12 @@ pub enum Error {
   QuickProtobuf(Box<quick_protobuf::Error>),
   #[cfg(feature = "rustls")]
   RustlsError(Box<rustls::Error>),
+  #[cfg(feature = "serde")]
+  SerdeDeValue(::serde::de::value::Error),
   #[cfg(feature = "serde_json")]
   SerdeJson(serde_json::Error),
+  #[cfg(feature = "serde_urlencoded")]
+  SerdeUrlencodedSer(Box<serde_urlencoded::ser::Error>),
   #[cfg(feature = "http-session")]
   SessionError(crate::http::SessionError),
   #[cfg(feature = "tokio")]
@@ -96,6 +98,8 @@ pub enum Error {
   ClosedConnection,
   /// Generic error
   Generic(&'static str),
+  /// Generic error
+  GenericOwned(Box<str>),
   /// `GenericTime` needs a backend
   GenericTimeNeedsBackend,
   /// The hardware returned an incorrect time value
@@ -134,10 +138,12 @@ pub enum Error {
   },
   /// Unexpected Unsigned integer
   UnexpectedUint {
-    received: u32,
+    received: u64,
   },
   /// Only appending is possible but overwritten is still viable through resetting.
   UriCanNotBeOverwritten,
+  /// In the current platform a number is larger than `usize`.
+  UsizeConversionOverflow,
 
   // Internal
   //
@@ -157,6 +163,8 @@ pub enum Error {
   Http2ErrorGoAway(crate::http2::Http2ErrorCode, Option<crate::http2::Http2Error>),
   #[cfg(feature = "http2")]
   Http2ErrorReset(crate::http2::Http2ErrorCode, Option<crate::http2::Http2Error>, u32),
+  #[cfg(feature = "mysql")]
+  MysqlError(crate::database::client::mysql::MysqlError),
   #[cfg(feature = "postgres")]
   PostgresError(crate::database::client::postgres::PostgresError),
   QueueError(DequeueError),
@@ -270,14 +278,6 @@ impl From<base64::EncodeSliceError> for Error {
   }
 }
 
-#[cfg(feature = "embedded-tls")]
-impl From<embedded_tls::TlsError> for Error {
-  #[inline]
-  fn from(from: embedded_tls::TlsError) -> Self {
-    Self::EmbassyTlsError(from)
-  }
-}
-
 #[cfg(feature = "flate2")]
 impl From<flate2::CompressError> for Error {
   #[inline]
@@ -398,6 +398,14 @@ impl From<rustls::Error> for Error {
   }
 }
 
+#[cfg(feature = "serde")]
+impl From<::serde::de::value::Error> for Error {
+  #[inline]
+  fn from(from: ::serde::de::value::Error) -> Self {
+    Self::SerdeDeValue(from)
+  }
+}
+
 #[cfg(feature = "serde_json")]
 impl From<serde_json::Error> for Error {
   #[inline]
@@ -406,6 +414,14 @@ impl From<serde_json::Error> for Error {
   }
 }
 
+#[cfg(feature = "serde_urlencoded")]
+impl From<serde_urlencoded::ser::Error> for Error {
+  #[inline]
+  fn from(from: serde_urlencoded::ser::Error) -> Self {
+    Self::SerdeUrlencodedSer(from.into())
+  }
+}
+
 #[cfg(feature = "http-session")]
 impl From<crate::http::SessionError> for Error {
   #[inline]
@@ -535,6 +551,14 @@ impl From<FromRadix10Error> for Error {
   }
 }
 
+#[cfg(feature = "mysql")]
+impl From<crate::database::client::mysql::MysqlError> for Error {
+  #[inline]
+  fn from(from: crate::database::client::mysql::MysqlError) -> Self {
+    Self::MysqlError(from)
+  }
+}
+
 #[cfg(feature = "postgres")]
 impl From<crate::database::client::postgres::PostgresError> for Error {
   #[inline]
@@ -594,3 +618,19 @@ pub enum VarError {
   /// variant.
   NotUnicode,
 }
+
+#[cfg(feature = "serde")]
+mod serde {
+  use alloc::string::ToString;
+  use core::fmt::Display;
+
+  impl serde::ser::Error for crate::Error {
+    #[inline]
+    fn custom<T>(msg: T) -> Self
+    where
+      T: Display,
+    {
+      Self::GenericOwned(msg.to_string().into())
+    }
+  }
+}
diff --git a/wtx/src/grpc.rs b/wtx/src/grpc.rs
index 407e23eb..9547894d 100644
--- a/wtx/src/grpc.rs
+++ b/wtx/src/grpc.rs
@@ -2,28 +2,31 @@
 //! framework.
 
 #[cfg(feature = "grpc-client")]
-mod client;
+mod grpc_client;
 mod grpc_manager;
 #[cfg(feature = "grpc-server")]
 mod grpc_middleware;
 mod grpc_status_code;
 
-use crate::{data_transformation::dnsn::Serialize, misc::Vector};
+use crate::{
+  data_transformation::dnsn::{De, EncodeWrapper},
+  misc::{Encode, Vector},
+};
 #[cfg(feature = "grpc-client")]
-pub use client::Client;
+pub use grpc_client::GrpcClient;
 pub use grpc_manager::GrpcManager;
 #[cfg(feature = "grpc-server")]
 pub use grpc_middleware::GrpcMiddleware;
 pub use grpc_status_code::GrpcStatusCode;
 
 #[inline]
-fn serialize<DRSR, T>(bytes: &mut Vector<u8>, mut data: T, drsr: &mut DRSR) -> crate::Result<()>
+fn serialize<DRSR, T>(bytes: &mut Vector<u8>, data: T, drsr: &mut DRSR) -> crate::Result<()>
 where
-  T: Serialize<DRSR>,
+  T: Encode<De<DRSR>>,
 {
   bytes.extend_from_copyable_slice(&[0; 5])?;
   let before_len = bytes.len();
-  data.to_bytes(bytes, drsr)?;
+  data.encode(drsr, &mut EncodeWrapper::_new(bytes))?;
   let after_len = bytes.len();
   if let [_, a, b, c, d, ..] = bytes.as_mut() {
     let len = u32::try_from(after_len.wrapping_sub(before_len)).unwrap_or_default();
diff --git a/wtx/src/grpc/client.rs b/wtx/src/grpc/grpc_client.rs
similarity index 73%
rename from wtx/src/grpc/client.rs
rename to wtx/src/grpc/grpc_client.rs
index 5ab3707e..2b056054 100644
--- a/wtx/src/grpc/client.rs
+++ b/wtx/src/grpc/grpc_client.rs
@@ -1,27 +1,28 @@
 use crate::{
   data_transformation::{
-    dnsn::{Deserialize, Serialize},
+    dnsn::{De, DecodeWrapper},
     format::{VerbatimRequest, VerbatimResponse},
   },
   grpc::serialize,
   http::{
-    Header, Headers, KnownHeaderName, ReqBuilder, ReqResBuffer, ReqUri, Response, WTX_USER_AGENT,
+    Header, Headers, HttpClient, KnownHeaderName, Method, ReqResBuffer, ReqUri, Response,
+    WTX_USER_AGENT,
   },
   http2::{Http2, Http2Buffer, Http2Data},
-  misc::{LeaseMut, Lock, RefCounter, SingleTypeStorage, StreamWriter},
+  misc::{Decode, Encode, LeaseMut, Lock, RefCounter, SingleTypeStorage, StreamWriter},
 };
 
 /// Performs requests to gRPC servers.
 #[derive(Debug)]
-pub struct Client<C, DRSR> {
+pub struct GrpcClient<C, DRSR> {
   client: C,
   drsr: DRSR,
 }
 
-impl<C, DRSR, HD, SW> Client<C, DRSR>
+impl<C, DRSR, HD, SW> GrpcClient<C, DRSR>
 where
   C: LeaseMut<Http2<HD, true>> + SingleTypeStorage<Item = HD>,
-  HD: RefCounter + 'static,
+  HD: RefCounter,
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   SW: StreamWriter,
 {
@@ -33,12 +34,12 @@ where
 
   /// Deserialize From Response Bytes
   #[inline]
-  pub fn des_from_res_bytes<'de, T>(&mut self, bytes: &'de [u8]) -> crate::Result<T>
+  pub fn des_from_res_bytes<'de, T>(&mut self, bytes: &mut &'de [u8]) -> crate::Result<T>
   where
-    VerbatimResponse<T>: Deserialize<'de, DRSR>,
+    VerbatimResponse<T>: Decode<'de, De<DRSR>>,
   {
     let elem = if let [_, _, _, _, _, elem @ ..] = bytes { elem } else { &[] };
-    Ok(VerbatimResponse::from_bytes(elem, &mut self.drsr)?.data)
+    Ok(VerbatimResponse::decode(&mut self.drsr, &mut DecodeWrapper::_new(elem))?.data)
   }
 
   /// Send Unary Request
@@ -54,7 +55,7 @@ where
     mut rrb: ReqResBuffer,
   ) -> crate::Result<Response<ReqResBuffer>>
   where
-    VerbatimRequest<T>: Serialize<DRSR>,
+    VerbatimRequest<T>: Encode<De<DRSR>>,
   {
     rrb.body.clear();
     rrb.headers.clear();
@@ -62,7 +63,7 @@ where
     rrb.uri.push_path(format_args!("/{package}.{service}/{method}"))?;
     serialize(&mut rrb.body, VerbatimRequest { data }, &mut self.drsr)?;
     Self::push_headers(&mut rrb.headers)?;
-    let res = ReqBuilder::post(rrb).send(self.client.lease_mut(), ReqUri::Data).await?;
+    let res = self.client.lease_mut().send_recv_single(Method::Post, ReqUri::Data, rrb).await?;
     Ok(Response::http2(res.rrd, res.status_code))
   }
 
diff --git a/wtx/src/grpc/grpc_manager.rs b/wtx/src/grpc/grpc_manager.rs
index 6aea1b17..c8a13bb5 100644
--- a/wtx/src/grpc/grpc_manager.rs
+++ b/wtx/src/grpc/grpc_manager.rs
@@ -1,10 +1,10 @@
 use crate::{
   data_transformation::{
-    dnsn::{Deserialize, Serialize},
+    dnsn::{De, DecodeWrapper},
     format::{VerbatimRequest, VerbatimResponse},
   },
-  grpc::{serialize, GrpcStatusCode},
-  misc::Vector,
+  grpc::{GrpcStatusCode, serialize},
+  misc::{Decode, Encode, Vector},
 };
 
 /// Responsible for managing internal structures that interact with gRPC.
@@ -25,19 +25,19 @@ impl<DRSR> GrpcManager<DRSR> {
 
   /// Deserialize From Request Bytes.
   #[inline]
-  pub fn des_from_req_bytes<'de, T>(&mut self, bytes: &'de [u8]) -> crate::Result<T>
+  pub fn des_from_req_bytes<'de, T>(&mut self, bytes: &mut &'de [u8]) -> crate::Result<T>
   where
-    VerbatimRequest<T>: Deserialize<'de, DRSR>,
+    VerbatimRequest<T>: Decode<'de, De<DRSR>>,
   {
     let elem = if let [_, _, _, _, _, elem @ ..] = bytes { elem } else { &[] };
-    Ok(VerbatimRequest::from_bytes(elem, &mut self.drsr)?.data)
+    Ok(VerbatimRequest::decode(&mut self.drsr, &mut DecodeWrapper::_new(elem))?.data)
   }
 
   /// Serialize to Response Bytes
   #[inline]
   pub fn ser_to_res_bytes<T>(&mut self, bytes: &mut Vector<u8>, data: T) -> crate::Result<()>
   where
-    VerbatimResponse<T>: Serialize<DRSR>,
+    VerbatimResponse<T>: Encode<De<DRSR>>,
   {
     serialize(bytes, VerbatimResponse { data }, &mut self.drsr)
   }
diff --git a/wtx/src/grpc/grpc_middleware.rs b/wtx/src/grpc/grpc_middleware.rs
index 0e880ec3..5ada77e7 100644
--- a/wtx/src/grpc/grpc_middleware.rs
+++ b/wtx/src/grpc/grpc_middleware.rs
@@ -1,8 +1,8 @@
 use crate::{
   grpc::GrpcManager,
   http::{
-    server_framework::Middleware, Header, KnownHeaderName, Mime, ReqResBuffer, Request, Response,
-    StatusCode,
+    Header, KnownHeaderName, Mime, ReqResBuffer, Request, Response, StatusCode,
+    server_framework::Middleware,
   },
 };
 use core::ops::ControlFlow;
diff --git a/wtx/src/http.rs b/wtx/src/http.rs
index eb0bc22e..8fe09929 100644
--- a/wtx/src/http.rs
+++ b/wtx/src/http.rs
@@ -11,6 +11,7 @@ mod generic_request;
 mod generic_response;
 mod header_name;
 mod headers;
+mod http_client;
 mod http_error;
 mod method;
 mod mime;
@@ -18,7 +19,6 @@ mod misc;
 mod operation_mode;
 #[cfg(feature = "nightly")]
 mod optioned_server;
-mod percent_encoding;
 mod protocol;
 #[cfg(feature = "http2")]
 mod req_builder;
@@ -41,6 +41,7 @@ pub use generic_request::GenericRequest;
 pub use generic_response::GenericResponse;
 pub use header_name::*;
 pub use headers::{Header, Headers, Trailers};
+pub use http_client::HttpClient;
 pub use http_error::HttpError;
 pub use method::Method;
 pub use mime::Mime;
@@ -48,7 +49,6 @@ pub use misc::*;
 pub use operation_mode::*;
 #[cfg(feature = "nightly")]
 pub use optioned_server::OptionedServer;
-pub use percent_encoding::{AsciiSet, PercentDecode, PercentEncode};
 pub use protocol::Protocol;
 #[cfg(feature = "http2")]
 pub use req_builder::ReqBuilder;
@@ -65,7 +65,7 @@ pub use version::Version;
 /// Maximum number of bytes for the name of a header.
 pub const MAX_HEADER_NAME_LEN: usize = 128;
 /// Maximum number of bytes for the value of a header.
-pub const MAX_HEADER_VALUE_LEN: usize = 1024 + 1024;
+pub const MAX_HEADER_VALUE_LEN: usize = 1024 * 2 + 128;
 /// Current user agent of this project
 pub const WTX_USER_AGENT: &str = concat!("wtx/", env!("CARGO_PKG_VERSION"));
 
diff --git a/wtx/src/http/client_pool.rs b/wtx/src/http/client_pool.rs
index 26ab28fa..3a9460f8 100644
--- a/wtx/src/http/client_pool.rs
+++ b/wtx/src/http/client_pool.rs
@@ -42,11 +42,11 @@ where
   HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
   RM: ResourceManager<
-    CreateAux = str,
-    Error = crate::Error,
-    RecycleAux = str,
-    Resource = ClientPoolResource<AUX, Http2<HD, true>>,
-  >,
+      CreateAux = str,
+      Error = crate::Error,
+      RecycleAux = str,
+      Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+    >,
   SW: StreamWriter,
   for<'any> RL: 'any,
   for<'any> RM: 'any,
@@ -66,9 +66,9 @@ where
   #[inline]
   pub async fn lock(
     &self,
-    req_uri: &UriRef<'_>,
+    uri: &UriRef<'_>,
   ) -> crate::Result<SimplePoolGetElem<<RL as Lock>::Guard<'_>>> {
-    self.pool.get(req_uri.as_str(), req_uri.as_str()).await
+    self.pool.get(uri.as_str(), uri.as_str()).await
   }
 }
 
@@ -81,7 +81,7 @@ mod tokio {
     pool::{ResourceManager, SimplePoolResource},
   };
   use tokio::{
-    net::{tcp::OwnedWriteHalf, TcpStream},
+    net::{TcpStream, tcp::OwnedWriteHalf},
     sync::Mutex,
   };
 
diff --git a/wtx/src/http/cookie.rs b/wtx/src/http/cookie.rs
index 09719ec9..8494e008 100644
--- a/wtx/src/http/cookie.rs
+++ b/wtx/src/http/cookie.rs
@@ -24,8 +24,8 @@ pub(crate) fn decrypt<'buffer>(
   (name, value): (&[u8], &[u8]),
 ) -> crate::Result<&'buffer mut [u8]> {
   use crate::misc::BufferMode;
-  use aes_gcm::{aead::AeadInPlace, aes::cipher::Array, Aes256Gcm};
-  use base64::{engine::general_purpose::STANDARD, Engine};
+  use aes_gcm::{Aes256Gcm, aead::AeadInPlace, aes::cipher::Array};
+  use base64::{Engine, engine::general_purpose::STANDARD};
 
   #[rustfmt::skip]
   let (nonce, content, tag) = {
@@ -71,8 +71,8 @@ where
   RNG: Rng,
 {
   use crate::misc::BufferMode;
-  use aes_gcm::{aead::AeadInPlace, aes::cipher::Array, Aes256Gcm};
-  use base64::{engine::general_purpose::STANDARD, Engine};
+  use aes_gcm::{Aes256Gcm, aead::AeadInPlace, aes::cipher::Array};
+  use base64::{Engine, engine::general_purpose::STANDARD};
 
   let start = buffer.len();
   let content_len = NONCE_LEN.wrapping_add(value.len()).wrapping_add(TAG_LEN);
diff --git a/wtx/src/http/cookie/cookie_bytes.rs b/wtx/src/http/cookie/cookie_bytes.rs
index af39ed51..78ed1c07 100644
--- a/wtx/src/http/cookie/cookie_bytes.rs
+++ b/wtx/src/http/cookie/cookie_bytes.rs
@@ -1,10 +1,9 @@
 use crate::{
   http::{
-    cookie::{cookie_generic::CookieGeneric, make_lowercase, SameSite, FMT1, FMT2, FMT3, FMT4},
-    percent_encoding::PercentDecode,
     CookieError,
+    cookie::{FMT1, FMT2, FMT3, FMT4, SameSite, cookie_generic::CookieGeneric, make_lowercase},
   },
-  misc::{bytes_split1, bytes_split_once1, ArrayVector, FromRadix10, Vector},
+  misc::{ArrayVector, FromRadix10, PercentDecode, Vector, bytes_split_once1, bytes_split1},
 };
 use chrono::{DateTime, NaiveDateTime, Utc};
 use core::{str, time::Duration};
diff --git a/wtx/src/http/cookie/cookie_generic.rs b/wtx/src/http/cookie/cookie_generic.rs
index e0d857b2..afea7fe4 100644
--- a/wtx/src/http/cookie/cookie_generic.rs
+++ b/wtx/src/http/cookie/cookie_generic.rs
@@ -1,5 +1,5 @@
 use crate::{
-  http::cookie::{SameSite, FMT1},
+  http::cookie::{FMT1, SameSite},
   misc::{BytesFmt, Lease},
 };
 use chrono::{DateTime, Utc};
diff --git a/wtx/src/http/generic_request.rs b/wtx/src/http/generic_request.rs
index 71eaed1b..7539c2ce 100644
--- a/wtx/src/http/generic_request.rs
+++ b/wtx/src/http/generic_request.rs
@@ -39,20 +39,12 @@ mod httparse {
   impl GenericRequest for httparse::Request<'_, '_> {
     #[inline]
     fn method(&self) -> &[u8] {
-      if let Some(el) = self.method {
-        el.as_bytes()
-      } else {
-        _unreachable()
-      }
+      if let Some(el) = self.method { el.as_bytes() } else { _unreachable() }
     }
 
     #[inline]
     fn path(&self) -> &[u8] {
-      if let Some(el) = self.path {
-        el.as_bytes()
-      } else {
-        _unreachable()
-      }
+      if let Some(el) = self.path { el.as_bytes() } else { _unreachable() }
     }
 
     #[inline]
diff --git a/wtx/src/http/generic_response.rs b/wtx/src/http/generic_response.rs
index ac316a90..885b4777 100644
--- a/wtx/src/http/generic_response.rs
+++ b/wtx/src/http/generic_response.rs
@@ -31,11 +31,7 @@ mod httparse {
   impl GenericResponse for httparse::Response<'_, '_> {
     #[inline]
     fn code(&self) -> u16 {
-      if let Some(el) = self.code {
-        el
-      } else {
-        _unreachable()
-      }
+      if let Some(el) = self.code { el } else { _unreachable() }
     }
 
     #[inline]
diff --git a/wtx/src/http/http_client.rs b/wtx/src/http/http_client.rs
new file mode 100644
index 00000000..4759a7cc
--- /dev/null
+++ b/wtx/src/http/http_client.rs
@@ -0,0 +1,211 @@
+use crate::{
+  http::{Method, ReqResBuffer, ReqResData, ReqUri, Response},
+  misc::Lease,
+};
+
+/// Generic HTTP client
+pub trait HttpClient {
+  /// Stream received in a request
+  type Stream;
+
+  /// Receives a response
+  fn recv_res(
+    &mut self,
+    rrb: ReqResBuffer,
+    stream: Self::Stream,
+  ) -> impl Future<Output = crate::Result<Response<ReqResBuffer>>>;
+
+  /// Sends a request a [`ReqResData`] and receives a response using [`ReqResBuffer`].
+  #[inline]
+  fn send_recv_dual<'uri, RRD>(
+    &mut self,
+    method: Method,
+    req_uri: impl Into<ReqUri<'uri>>,
+    rrb: ReqResBuffer,
+    rrd: RRD,
+  ) -> impl Future<Output = crate::Result<Response<ReqResBuffer>>>
+  where
+    RRD: ReqResData,
+    RRD::Body: Lease<[u8]>,
+  {
+    async move {
+      let stream = self.send_req(method, req_uri, rrd).await?;
+      self.recv_res(rrb, stream).await
+    }
+  }
+
+  /// Sends a request and receives a response using a single [`ReqResBuffer`].
+  #[inline]
+  fn send_recv_single<'uri>(
+    &mut self,
+    method: Method,
+    req_uri: impl Into<ReqUri<'uri>>,
+    rrb: ReqResBuffer,
+  ) -> impl Future<Output = crate::Result<Response<ReqResBuffer>>> {
+    async move {
+      let stream = self.send_req(method, req_uri, &rrb).await?;
+      self.recv_res(rrb, stream).await
+    }
+  }
+
+  /// Sends a request
+  fn send_req<'uri, RRD>(
+    &mut self,
+    method: Method,
+    req_uri: impl Into<ReqUri<'uri>>,
+    rrd: RRD,
+  ) -> impl Future<Output = crate::Result<Self::Stream>>
+  where
+    RRD: ReqResData,
+    RRD::Body: Lease<[u8]>;
+}
+
+impl<T> HttpClient for &mut T
+where
+  T: HttpClient,
+{
+  type Stream = T::Stream;
+
+  #[inline]
+  async fn recv_res(
+    &mut self,
+    rrb: ReqResBuffer,
+    stream: Self::Stream,
+  ) -> crate::Result<Response<ReqResBuffer>> {
+    (**self).recv_res(rrb, stream).await
+  }
+
+  #[inline]
+  async fn send_req<'uri, RRD>(
+    &mut self,
+    method: Method,
+    req_uri: impl Into<ReqUri<'uri>>,
+    rrd: RRD,
+  ) -> crate::Result<Self::Stream>
+  where
+    RRD: ReqResData,
+    RRD::Body: Lease<[u8]>,
+  {
+    (**self).send_req(method, req_uri, rrd).await
+  }
+}
+
+#[cfg(feature = "http2")]
+mod http2 {
+  use crate::{
+    http::{HttpClient, Method, ReqResBuffer, ReqResData, ReqUri, Request, Response},
+    http2::{ClientStream, Http2, Http2Buffer, Http2Data, Http2RecvStatus},
+    misc::{Lease, LeaseMut, Lock, RefCounter, StreamWriter},
+  };
+
+  impl<HB, HD, SW> HttpClient for Http2<HD, true>
+  where
+    HB: LeaseMut<Http2Buffer>,
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<HB, SW, true>>,
+    SW: StreamWriter,
+  {
+    type Stream = ClientStream<HD>;
+
+    #[inline]
+    async fn recv_res(
+      &mut self,
+      rrb: ReqResBuffer,
+      mut stream: Self::Stream,
+    ) -> crate::Result<Response<ReqResBuffer>> {
+      let (hrs, res_rrb) = stream.recv_res(rrb).await?;
+      let status_code = match hrs {
+        Http2RecvStatus::Eos(elem) => elem,
+        _ => return Err(crate::Error::ClosedConnection),
+      };
+      stream.common().clear(false).await?;
+      Ok(Response::http2(res_rrb, status_code))
+    }
+
+    #[inline]
+    async fn send_req<'uri, RRD>(
+      &mut self,
+      method: Method,
+      req_uri: impl Into<ReqUri<'uri>>,
+      rrd: RRD,
+    ) -> crate::Result<Self::Stream>
+    where
+      RRD: ReqResData,
+      RRD::Body: Lease<[u8]>,
+    {
+      let mut stream = self.stream().await?;
+      if stream.send_req(Request::http2(method, rrd), req_uri).await?.is_closed() {
+        return Err(crate::Error::ClosedConnection);
+      }
+      Ok(stream)
+    }
+  }
+}
+
+#[cfg(feature = "http-client-pool")]
+mod http_client_pool {
+  use crate::{
+    http::{
+      HttpClient, Method, ReqResBuffer, ReqResData, ReqUri, Request, Response,
+      client_pool::{ClientPool, ClientPoolResource},
+    },
+    http2::{ClientStream, Http2, Http2Buffer, Http2Data, Http2RecvStatus},
+    misc::{Lease, Lock, RefCounter, StreamWriter},
+    pool::{ResourceManager, SimplePoolResource},
+  };
+
+  impl<AUX, HD, RL, RM, SW> HttpClient for &ClientPool<RL, RM>
+  where
+    HD: RefCounter,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
+    RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
+    RM: ResourceManager<
+        CreateAux = str,
+        Error = crate::Error,
+        RecycleAux = str,
+        Resource = ClientPoolResource<AUX, Http2<HD, true>>,
+      >,
+    SW: StreamWriter,
+    for<'any> RL: 'any,
+    for<'any> RM: 'any,
+  {
+    type Stream = ClientStream<HD>;
+
+    #[inline]
+    async fn recv_res(
+      &mut self,
+      rrb: ReqResBuffer,
+      mut stream: Self::Stream,
+    ) -> crate::Result<Response<ReqResBuffer>> {
+      let (hrs, res_rrb) = stream.recv_res(rrb).await?;
+      let status_code = match hrs {
+        Http2RecvStatus::Eos(elem) => elem,
+        _ => return Err(crate::Error::ClosedConnection),
+      };
+      stream.common().clear(false).await?;
+      Ok(Response::http2(res_rrb, status_code))
+    }
+
+    #[inline]
+    async fn send_req<'uri, RRD>(
+      &mut self,
+      method: Method,
+      req_uri: impl Into<ReqUri<'uri>>,
+      rrd: RRD,
+    ) -> crate::Result<Self::Stream>
+    where
+      RRD: ReqResData,
+      RRD::Body: Lease<[u8]>,
+    {
+      let (req_uri, uri) = match req_uri.into() {
+        ReqUri::Data => (ReqUri::Data, &rrd.uri().to_ref()),
+        ReqUri::Param(elem) => (ReqUri::Param(elem), elem),
+      };
+      let mut stream = self.lock(uri).await?.client.stream().await?;
+      if stream.send_req(Request::http2(method, rrd), req_uri).await?.is_closed() {
+        return Err(crate::Error::ClosedConnection);
+      }
+      Ok(stream)
+    }
+  }
+}
diff --git a/wtx/src/http/http_error.rs b/wtx/src/http/http_error.rs
index cf23e4a4..0686072b 100644
--- a/wtx/src/http/http_error.rs
+++ b/wtx/src/http/http_error.rs
@@ -18,6 +18,8 @@ pub enum HttpError {
   MissingRequestMethod,
   /// Received response does not contain a status code field
   MissingResponseStatusCode,
+  /// The URI doesn't have any placeholder
+  MissingUriPlaceholder,
   /// Content-Type mismatch
   UnexpectedContentType,
   /// HTTP version does not match the expected method.
diff --git a/wtx/src/http/method.rs b/wtx/src/http/method.rs
index 2aa17419..2712b1d7 100644
--- a/wtx/src/http/method.rs
+++ b/wtx/src/http/method.rs
@@ -43,7 +43,7 @@ impl Method {
 #[cfg(feature = "serde")]
 mod serde {
   use crate::http::Method;
-  use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
+  use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
 
   impl<'de> Deserialize<'de> for Method {
     #[inline]
diff --git a/wtx/src/http/optioned_server/http2_tokio.rs b/wtx/src/http/optioned_server/http2_tokio.rs
index 4f410d5e..4b13edb9 100644
--- a/wtx/src/http/optioned_server/http2_tokio.rs
+++ b/wtx/src/http/optioned_server/http2_tokio.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    optioned_server::OptionedServer, AutoStream, ManualServerStreamTokio, OperationMode, Protocol,
-    ReqResBuffer, Request, Response,
+    AutoStream, ManualServerStreamTokio, OperationMode, Protocol, ReqResBuffer, Request, Response,
+    optioned_server::OptionedServer,
   },
   http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2Tokio},
   misc::{Either, FnFut, StreamReader, StreamWriter},
diff --git a/wtx/src/http/optioned_server/web_socket_tokio.rs b/wtx/src/http/optioned_server/web_socket_tokio.rs
index 0c057ded..a4f59b57 100644
--- a/wtx/src/http/optioned_server/web_socket_tokio.rs
+++ b/wtx/src/http/optioned_server/web_socket_tokio.rs
@@ -1,6 +1,6 @@
 use crate::{
   http::OptionedServer,
-  misc::{FnFut, Stream, _number_or_available_parallelism},
+  misc::{_number_or_available_parallelism, FnFut, Stream},
   pool::{SimplePoolTokio, WebSocketRM},
   web_socket::{Compression, WebSocket, WebSocketAcceptor, WebSocketBuffer},
 };
diff --git a/wtx/src/http/req_builder.rs b/wtx/src/http/req_builder.rs
index 9396933b..54759385 100644
--- a/wtx/src/http/req_builder.rs
+++ b/wtx/src/http/req_builder.rs
@@ -1,8 +1,8 @@
 use crate::{
-  http::{Header, KnownHeaderName, Method, Mime, ReqResBuffer, ReqUri, Request, Response},
-  http2::{Http2, Http2Buffer, Http2Data, Http2RecvStatus},
-  misc::{LeaseMut, Lock, RefCounter, StreamWriter},
+  http::{Header, KnownHeaderName, Method, Mime, ReqResBuffer},
+  misc::LeaseMut,
 };
+use core::fmt::Arguments;
 
 /// Request builder
 ///
@@ -32,29 +32,52 @@ impl ReqBuilder {
 }
 
 impl ReqBuilder {
-  /// Sends a request with inner parameters.
+  /// Applies a header field in the form of `Authorization: Basic <credentials>` where
+  /// <credentials> is the Base64 encoding of `id` and `pw` joined by a single colon `:`.
   #[inline]
-  pub async fn send<HD, SW>(
-    self,
-    client: &mut Http2<HD, true>,
-    req_uri: impl Into<ReqUri<'_>>,
-  ) -> crate::Result<Response<ReqResBuffer>>
-  where
-    HD: RefCounter,
-    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
-    SW: StreamWriter,
-  {
-    let mut stream = client.stream().await?;
-    if stream.send_req(Request::http2(self.method, &self.rrb), req_uri).await?.is_closed() {
-      return Err(crate::Error::ClosedConnection);
-    }
-    let (hrs, res_rrb) = stream.recv_res(self.rrb).await?;
-    let status_code = match hrs {
-      Http2RecvStatus::Eos(elem) => elem,
-      _ => return Err(crate::Error::ClosedConnection),
+  #[cfg(feature = "base64")]
+  pub fn auth_basic(mut self, id: Arguments<'_>, pw: Arguments<'_>) -> crate::Result<Self> {
+    use base64::{Engine, engine::general_purpose::STANDARD};
+    use core::fmt::Write;
+    let body_idx = self.rrb.body.len();
+    let mut fun = || {
+      self.rrb.uri._buffer(|buffer| {
+        let uri_idx = buffer.len();
+        buffer.write_fmt(format_args!("Basic {id}:{pw}"))?;
+        let input = buffer.get(uri_idx..).unwrap_or_default();
+        let _ = STANDARD.encode_slice(input, &mut self.rrb.body)?;
+        Ok(())
+      })?;
+      let ReqResBuffer { body, headers, uri: _ } = self.rrb.lease_mut();
+      headers.push_from_iter(Header::from_name_and_value(
+        KnownHeaderName::Authorization.into(),
+        [body.get(body_idx..).unwrap_or_default()],
+      ))
     };
-    stream.common().clear(false).await?;
-    Ok(Response::http2(res_rrb, status_code))
+    if let Err(err) = fun() {
+      self.rrb.body.truncate(body_idx);
+      return Err(err);
+    }
+    Ok(self)
+  }
+
+  /// Applies a header field in the form of `Authorization: Bearer <token>`.
+  #[inline]
+  pub fn auth_bearer(mut self, token: Arguments<'_>) -> crate::Result<Self> {
+    self.rrb.lease_mut().headers.push_from_fmt(Header::from_name_and_value(
+      KnownHeaderName::Authorization.into(),
+      format_args!("Bearer {token}"),
+    ))?;
+    Ok(self)
+  }
+
+  /// Injects a sequence of bytes into the internal buffer.
+  ///
+  /// No `content-type` header is applied in this method.
+  #[inline]
+  pub fn bytes(mut self, data: &[u8]) -> crate::Result<Self> {
+    self.rrb.body.extend_from_copyable_slice(data)?;
+    Ok(self)
   }
 
   /// Media type of the resource.
@@ -74,6 +97,42 @@ impl ReqBuilder {
     self
   }
 
+  /// Uses `serde_json` to inject a raw structure as JSON into the internal buffer.
+  ///
+  /// A `content-type` header of type `application/json` is also applied.
+  #[inline]
+  #[cfg(feature = "serde_json")]
+  pub fn serde_json<T>(mut self, data: &T) -> crate::Result<Self>
+  where
+    T: serde::Serialize,
+  {
+    serde_json::to_writer(&mut self.rrb.body, data)?;
+    self.content_type(Mime::ApplicationJson)
+  }
+
+  /// Uses `serde_urlencoded` to inject a raw structure as Percent-encoding into the internal
+  /// buffer.
+  ///
+  /// A `content-type` header of type `application/x-www-form-urlencoded` is also applied.
+  #[inline]
+  #[cfg(feature = "serde_urlencoded")]
+  pub fn serde_urlencoded<T>(mut self, data: &T) -> crate::Result<Self>
+  where
+    T: serde::Serialize,
+  {
+    self.rrb.body.extend_from_copyable_slice(serde_urlencoded::to_string(data)?.as_bytes())?;
+    self.content_type(Mime::ApplicationXWwwFormUrlEncoded)
+  }
+
+  /// Injects a sequence of bytes into the internal buffer.
+  ///
+  /// A `content-type` header of type `text/plain` is also applied.
+  #[inline]
+  pub fn text(mut self, data: &[u8]) -> crate::Result<Self> {
+    self.rrb.body.extend_from_copyable_slice(data)?;
+    self.content_type(Mime::TextPlain)
+  }
+
   /// Characteristic string that lets servers and network peers identify the application.
   #[inline]
   pub fn user_agent(mut self, value: &[u8]) -> crate::Result<Self> {
@@ -85,3 +144,10 @@ impl ReqBuilder {
     Ok(self)
   }
 }
+
+impl Default for ReqBuilder {
+  #[inline]
+  fn default() -> Self {
+    Self::get(ReqResBuffer::default())
+  }
+}
diff --git a/wtx/src/http/req_res_data.rs b/wtx/src/http/req_res_data.rs
index cdce5b5a..253ebfbe 100644
--- a/wtx/src/http/req_res_data.rs
+++ b/wtx/src/http/req_res_data.rs
@@ -144,6 +144,29 @@ where
   }
 }
 
+impl<B, H, U> ReqResData for (B, H, U)
+where
+  H: Lease<Headers>,
+  U: Lease<UriString>,
+{
+  type Body = B;
+
+  #[inline]
+  fn body(&self) -> &Self::Body {
+    &self.0
+  }
+
+  #[inline]
+  fn headers(&self) -> &Headers {
+    self.1.lease()
+  }
+
+  #[inline]
+  fn uri(&self) -> &UriString {
+    self.2.lease()
+  }
+}
+
 impl<T> ReqResData for Box<T>
 where
   T: ReqResData,
@@ -300,3 +323,17 @@ where
     (&mut self.0, self.1.lease_mut(), &EMPTY_URI_STRING)
   }
 }
+
+impl<B, H, U> ReqResDataMut for (B, H, U)
+where
+  H: LeaseMut<Headers>,
+  U: Lease<UriString>,
+{
+  #[inline]
+  fn clear(&mut self) {}
+
+  #[inline]
+  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, &UriString) {
+    (&mut self.0, self.1.lease_mut(), self.2.lease())
+  }
+}
diff --git a/wtx/src/http/server_framework.rs b/wtx/src/http/server_framework.rs
index a5baaccc..4c10d0cc 100644
--- a/wtx/src/http/server_framework.rs
+++ b/wtx/src/http/server_framework.rs
@@ -25,7 +25,7 @@ mod tests;
 mod tokio;
 
 use crate::{
-  http::{conn_params::ConnParams, AutoStream, OperationMode, ReqResBuffer, Response},
+  http::{AutoStream, OperationMode, ReqResBuffer, Response, conn_params::ConnParams},
   misc::{Arc, ArrayVector},
 };
 pub use arguments::*;
@@ -34,10 +34,10 @@ pub use cors_middleware::CorsMiddleware;
 pub use endpoint::Endpoint;
 pub use endpoint_node::EndpointNode;
 pub use methods::{
-  get::{get, Get},
-  json::{json, Json},
-  post::{post, Post},
-  web_socket::{web_socket, WebSocket},
+  get::{Get, get},
+  json::{Json, json},
+  post::{Post, post},
+  web_socket::{WebSocket, web_socket},
 };
 pub use middleware::Middleware;
 pub use path_params::PathParams;
diff --git a/wtx/src/http/server_framework/arguments.rs b/wtx/src/http/server_framework/arguments.rs
index c23bf459..c44ca86d 100644
--- a/wtx/src/http/server_framework/arguments.rs
+++ b/wtx/src/http/server_framework/arguments.rs
@@ -4,8 +4,8 @@ mod path_str;
 mod serde_json;
 
 use crate::{
-  http::{server_framework::RouteMatch, HttpError},
-  misc::{bytes_split1, UriString},
+  http::{HttpError, server_framework::RouteMatch},
+  misc::{UriString, bytes_split1},
 };
 pub use path_owned::PathOwned;
 pub use path_str::PathStr;
@@ -39,5 +39,5 @@ fn manage_path<'uri>(
     }
     None
   };
-  fun().ok_or_else(|| crate::Error::from(HttpError::UriMismatch))
+  fun().ok_or_else(|| crate::Error::from(HttpError::MissingUriPlaceholder))
 }
diff --git a/wtx/src/http/server_framework/arguments/path_owned.rs b/wtx/src/http/server_framework/arguments/path_owned.rs
index b0ad5331..522f00e4 100644
--- a/wtx/src/http/server_framework/arguments/path_owned.rs
+++ b/wtx/src/http/server_framework/arguments/path_owned.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::{arguments::manage_path, Endpoint, ResFinalizer, RouteMatch, StateGeneric},
     AutoStream, ReqResBuffer, StatusCode,
+    server_framework::{Endpoint, ResFinalizer, RouteMatch, StateGeneric, arguments::manage_path},
   },
   misc::{FnFut, FnFutWrapper},
 };
diff --git a/wtx/src/http/server_framework/arguments/path_str.rs b/wtx/src/http/server_framework/arguments/path_str.rs
index 30d14f0b..9177eb5b 100644
--- a/wtx/src/http/server_framework/arguments/path_str.rs
+++ b/wtx/src/http/server_framework/arguments/path_str.rs
@@ -1,10 +1,10 @@
 use crate::{
   http::{
+    AutoStream, Headers, Request, StatusCode,
     server_framework::{
-      arguments::{manage_path, RouteMatch},
       Endpoint, ResFinalizer, StateGeneric,
+      arguments::{RouteMatch, manage_path},
     },
-    AutoStream, Headers, Request, StatusCode,
   },
   misc::{FnFut, FnFutWrapper, Vector},
 };
@@ -42,9 +42,9 @@ impl<CA, E, F, RES, S, SA, const CLEAN: bool> Endpoint<CA, E, S, SA>
 where
   E: From<crate::Error>,
   F: for<'any> FnFut<
-    (StateGeneric<'any, CA, SA, (&'any mut Vector<u8>, &'any mut Headers), CLEAN>, PathStr<'any>),
-    Result = RES,
-  >,
+      (StateGeneric<'any, CA, SA, (&'any mut Vector<u8>, &'any mut Headers), CLEAN>, PathStr<'any>),
+      Result = RES,
+    >,
   RES: ResFinalizer<E>,
 {
   #[inline]
diff --git a/wtx/src/http/server_framework/arguments/serde_json.rs b/wtx/src/http/server_framework/arguments/serde_json.rs
index bff4184e..a4e8453e 100644
--- a/wtx/src/http/server_framework/arguments/serde_json.rs
+++ b/wtx/src/http/server_framework/arguments/serde_json.rs
@@ -1,11 +1,11 @@
 use crate::{
   http::{
-    server_framework::{Endpoint, ResFinalizer, RouteMatch, StateGeneric},
     AutoStream, Header, KnownHeaderName, Mime, ReqResBuffer, Request, StatusCode,
+    server_framework::{Endpoint, ResFinalizer, RouteMatch, StateGeneric},
   },
-  misc::{serde_collect_seq_rslt, FnFut, FnFutWrapper, LeaseMut, Wrapper},
+  misc::{FnFut, FnFutWrapper, LeaseMut},
 };
-use serde::{de::DeserializeOwned, Serialize};
+use serde::{Serialize, de::DeserializeOwned};
 
 /// Serializes and deserializes using `serde_json`
 #[derive(Debug)]
@@ -79,23 +79,6 @@ where
   }
 }
 
-impl<E, I, T> ResFinalizer<E> for SerdeJson<Wrapper<I>>
-where
-  E: From<crate::Error> + From<serde_json::Error>,
-  I: Iterator<Item = Result<T, E>>,
-  T: Serialize,
-{
-  #[inline]
-  fn finalize_response(self, req: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
-    push_content_type(req)?;
-    serde_collect_seq_rslt(
-      &mut serde_json::Serializer::new(&mut req.rrd.lease_mut().body),
-      self.0 .0,
-    )?;
-    Ok(StatusCode::Ok)
-  }
-}
-
 #[inline]
 fn push_content_type(req: &mut Request<ReqResBuffer>) -> crate::Result<()> {
   req.rrd.lease_mut().headers.push_from_iter(Header::from_name_and_value(
diff --git a/wtx/src/http/server_framework/cors_middleware.rs b/wtx/src/http/server_framework/cors_middleware.rs
index cde0acd9..9a522c1b 100644
--- a/wtx/src/http/server_framework/cors_middleware.rs
+++ b/wtx/src/http/server_framework/cors_middleware.rs
@@ -1,10 +1,10 @@
 use crate::{
   http::{
-    server_framework::{ConnAux, Middleware, ServerFrameworkError},
     Header, Headers, HttpError, KnownHeaderName, Method, ReqResBuffer, Request, Response,
     StatusCode,
+    server_framework::{ConnAux, Middleware, ServerFrameworkError},
   },
-  misc::{bytes_split1, ArrayVector, Intersperse, Vector},
+  misc::{ArrayVector, Intersperse, Vector, bytes_split1},
 };
 use core::ops::ControlFlow;
 use hashbrown::HashSet;
diff --git a/wtx/src/http/server_framework/endpoint.rs b/wtx/src/http/server_framework/endpoint.rs
index 2a2444db..f76ef6b4 100644
--- a/wtx/src/http/server_framework/endpoint.rs
+++ b/wtx/src/http/server_framework/endpoint.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::{ResFinalizer, RouteMatch, ServerFrameworkError},
     AutoStream, ManualStream, OperationMode, StatusCode,
+    server_framework::{ResFinalizer, RouteMatch, ServerFrameworkError},
   },
   misc::{FnFut, FnFutWrapper},
 };
diff --git a/wtx/src/http/server_framework/endpoint_node.rs b/wtx/src/http/server_framework/endpoint_node.rs
index eb8aa4d8..cf7313e7 100644
--- a/wtx/src/http/server_framework/endpoint_node.rs
+++ b/wtx/src/http/server_framework/endpoint_node.rs
@@ -40,8 +40,8 @@ where
 mod tests {
   use crate::{
     http::{
-      server_framework::{get, EndpointNode, RouteMatch, Router, StateClean},
       ManualStream, OperationMode, ReqResBuffer, StatusCode,
+      server_framework::{EndpointNode, RouteMatch, Router, StateClean, get},
     },
     misc::{ArrayVector, Vector},
   };
diff --git a/wtx/src/http/server_framework/methods.rs b/wtx/src/http/server_framework/methods.rs
index 53f1cdac..411d691c 100644
--- a/wtx/src/http/server_framework/methods.rs
+++ b/wtx/src/http/server_framework/methods.rs
@@ -23,7 +23,7 @@ where
 {
   if headers
     .get_by_name(KnownHeaderName::ContentType.into())
-    .is_none_or(|el| el.value == Mime::ApplicationJson.as_str().as_bytes())
+    .is_none_or(|el| el.value != Mime::ApplicationJson.as_str().as_bytes())
   {
     return Err(E::from(crate::Error::from(HttpError::UnexpectedContentType)));
   }
diff --git a/wtx/src/http/server_framework/methods/get.rs b/wtx/src/http/server_framework/methods/get.rs
index 27c3de6e..10715a1f 100644
--- a/wtx/src/http/server_framework/methods/get.rs
+++ b/wtx/src/http/server_framework/methods/get.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::{methods::check_method, Endpoint, EndpointNode, RouteMatch},
     AutoStream, ManualStream, Method, OperationMode, StatusCode,
+    server_framework::{Endpoint, EndpointNode, RouteMatch, methods::check_method},
   },
   misc::{ArrayVector, FnFut, Vector},
 };
diff --git a/wtx/src/http/server_framework/methods/json.rs b/wtx/src/http/server_framework/methods/json.rs
index 9bc8945f..f6236acc 100644
--- a/wtx/src/http/server_framework/methods/json.rs
+++ b/wtx/src/http/server_framework/methods/json.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::{methods::check_json, Endpoint, EndpointNode, RouteMatch},
     AutoStream, ManualStream, OperationMode, StatusCode,
+    server_framework::{Endpoint, EndpointNode, RouteMatch, methods::check_json},
   },
   misc::{ArrayVector, FnFut, Vector},
 };
diff --git a/wtx/src/http/server_framework/methods/post.rs b/wtx/src/http/server_framework/methods/post.rs
index 91fd414f..841dc099 100644
--- a/wtx/src/http/server_framework/methods/post.rs
+++ b/wtx/src/http/server_framework/methods/post.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::{methods::check_method, Endpoint, EndpointNode, RouteMatch},
     AutoStream, ManualStream, Method, OperationMode, StatusCode,
+    server_framework::{Endpoint, EndpointNode, RouteMatch, methods::check_method},
   },
   misc::{ArrayVector, FnFut, Vector},
 };
diff --git a/wtx/src/http/server_framework/methods/web_socket.rs b/wtx/src/http/server_framework/methods/web_socket.rs
index cedf874e..6e8a8831 100644
--- a/wtx/src/http/server_framework/methods/web_socket.rs
+++ b/wtx/src/http/server_framework/methods/web_socket.rs
@@ -1,8 +1,7 @@
 use crate::{
   http::{
-    is_web_socket_handshake,
+    AutoStream, ManualStream, OperationMode, StatusCode, is_web_socket_handshake,
     server_framework::{Endpoint, EndpointNode, RouteMatch, ServerFrameworkError},
-    AutoStream, ManualStream, OperationMode, StatusCode,
   },
   misc::{ArrayVector, FnFut, Vector},
 };
diff --git a/wtx/src/http/server_framework/redirect.rs b/wtx/src/http/server_framework/redirect.rs
index c2a21367..1f3ebd40 100644
--- a/wtx/src/http/server_framework/redirect.rs
+++ b/wtx/src/http/server_framework/redirect.rs
@@ -1,6 +1,6 @@
 use crate::http::{
-  server_framework::ResFinalizer, Header, Headers, KnownHeaderName, ReqResBuffer, ReqResDataMut,
-  Request, StatusCode,
+  Header, Headers, KnownHeaderName, ReqResBuffer, ReqResDataMut, Request, StatusCode,
+  server_framework::ResFinalizer,
 };
 
 /// Redirects a request to another location.
diff --git a/wtx/src/http/server_framework/router.rs b/wtx/src/http/server_framework/router.rs
index 8aed68f8..925862f7 100644
--- a/wtx/src/http/server_framework/router.rs
+++ b/wtx/src/http/server_framework/router.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::{Endpoint, EndpointNode, Middleware, RouteMatch},
     AutoStream, ManualStream, OperationMode, Response, StatusCode,
+    server_framework::{Endpoint, EndpointNode, Middleware, RouteMatch},
   },
   misc::{ArrayVector, Vector},
 };
diff --git a/wtx/src/http/server_framework/state.rs b/wtx/src/http/server_framework/state.rs
index 3300b428..e11beb16 100644
--- a/wtx/src/http/server_framework/state.rs
+++ b/wtx/src/http/server_framework/state.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::{Endpoint, ResFinalizer, RouteMatch},
     AutoStream, ReqResBuffer, ReqResDataMut, Request, StatusCode,
+    server_framework::{Endpoint, ResFinalizer, RouteMatch},
   },
   misc::{FnFut, FnFutWrapper},
 };
diff --git a/wtx/src/http/server_framework/tokio.rs b/wtx/src/http/server_framework/tokio.rs
index 5d021c7b..f96d4cab 100644
--- a/wtx/src/http/server_framework/tokio.rs
+++ b/wtx/src/http/server_framework/tokio.rs
@@ -1,9 +1,9 @@
 use crate::{
   http::{
+    ManualServerStreamTokio, ManualStream, OptionedServer, ReqResBuffer, Request,
     server_framework::{
       ConnAux, EndpointNode, Middleware, RouteMatch, Router, ServerFramework, StreamAux,
     },
-    ManualServerStreamTokio, ManualStream, OptionedServer, ReqResBuffer, Request,
   },
   http2::{Http2Buffer, Http2DataTokio, ServerStream},
   misc::{Arc, ArrayVector, Rng},
diff --git a/wtx/src/http/session/session_decoder.rs b/wtx/src/http/session/session_decoder.rs
index d2e88550..b42b3a24 100644
--- a/wtx/src/http/session/session_decoder.rs
+++ b/wtx/src/http/session/session_decoder.rs
@@ -1,9 +1,9 @@
 use crate::{
   http::{
-    cookie::{cookie_bytes::CookieBytes, decrypt},
-    server_framework::Middleware,
     KnownHeaderName, ReqResBuffer, Request, Response, SessionError, SessionManager,
     SessionManagerInner, SessionState, SessionStore, StatusCode,
+    cookie::{cookie_bytes::CookieBytes, decrypt},
+    server_framework::Middleware,
   },
   misc::{GenericTime, Lease, LeaseMut, Lock},
   pool::{Pool, ResourceManager},
@@ -13,9 +13,6 @@ use core::ops::ControlFlow;
 use serde::de::DeserializeOwned;
 
 /// Decodes cookies received from requests and manages them.
-///
-/// The use of this structure without [`Session`] or used after the applicability of [`Session`]
-/// is a NO-OP.
 #[derive(Debug)]
 pub struct SessionDecoder<SMI, SS> {
   session_manager: SessionManager<SMI>,
@@ -33,7 +30,7 @@ impl<SMI, SS> SessionDecoder<SMI, SS> {
 impl<CA, CS, E, RM, SMI, SS, SA> Middleware<CA, E, SA> for SessionDecoder<SMI, SS>
 where
   CA: LeaseMut<Option<SessionState<CS>>>,
-  CS: DeserializeOwned + PartialEq + core::fmt::Debug,
+  CS: DeserializeOwned + PartialEq,
   E: From<crate::Error>,
   SMI: Lock<Resource = SessionManagerInner<CS, E>>,
   SS: Pool<ResourceManager = RM>,
diff --git a/wtx/src/http/session/session_enforcer.rs b/wtx/src/http/session/session_enforcer.rs
index 51d73dcd..26e0f9bc 100644
--- a/wtx/src/http/session/session_enforcer.rs
+++ b/wtx/src/http/session/session_enforcer.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    server_framework::Middleware, ReqResBuffer, Request, Response, SessionError, SessionState,
-    StatusCode,
+    ReqResBuffer, Request, Response, SessionError, SessionState, StatusCode,
+    server_framework::Middleware,
   },
   misc::LeaseMut,
 };
diff --git a/wtx/src/http/session/session_manager.rs b/wtx/src/http/session/session_manager.rs
index a1b50b7f..6b6e2265 100644
--- a/wtx/src/http/session/session_manager.rs
+++ b/wtx/src/http/session/session_manager.rs
@@ -1,9 +1,9 @@
 use crate::{
   http::{
-    cookie::{cookie_generic::CookieGeneric, encrypt},
-    session::SessionKey,
     Header, Headers, KnownHeaderName, ReqResBuffer, ReqResDataMut, SessionManagerBuilder,
     SessionState, SessionStore,
+    cookie::{cookie_generic::CookieGeneric, encrypt},
+    session::SessionKey,
   },
   misc::{GenericTime, Lease, LeaseMut, Lock, Rng, Vector},
 };
diff --git a/wtx/src/http/session/session_manager_builder.rs b/wtx/src/http/session/session_manager_builder.rs
index 8d6584a4..dc4acee8 100644
--- a/wtx/src/http/session/session_manager_builder.rs
+++ b/wtx/src/http/session/session_manager_builder.rs
@@ -1,10 +1,10 @@
 use crate::{
   http::{
-    cookie::{cookie_generic::CookieGeneric, SameSite},
-    session::{SessionKey, SessionManagerInner},
     SessionManager, SessionStore,
+    cookie::{SameSite, cookie_generic::CookieGeneric},
+    session::{SessionKey, SessionManagerInner},
   },
-  misc::{sleep, Lock, Rng, Vector},
+  misc::{CryptoRng, Lock, Vector, sleep},
 };
 use chrono::{DateTime, Utc};
 use core::{future::Future, marker::PhantomData, time::Duration};
@@ -51,7 +51,7 @@ impl SessionManagerBuilder {
   ) -> (impl Future<Output = Result<(), E>> + use<CS, E, RNG, SMI, SS>, SessionManager<SMI>)
   where
     E: From<crate::Error>,
-    RNG: Rng,
+    RNG: CryptoRng,
     SMI: Lock<Resource = SessionManagerInner<CS, E>>,
     SS: Clone + SessionStore<CS, E>,
   {
diff --git a/wtx/src/http/session/session_store.rs b/wtx/src/http/session/session_store.rs
index 677e8847..add7eccc 100644
--- a/wtx/src/http/session/session_store.rs
+++ b/wtx/src/http/session/session_store.rs
@@ -1,4 +1,4 @@
-use crate::http::{session::SessionId, SessionState};
+use crate::http::{SessionState, session::SessionId};
 use core::future::Future;
 
 /// Abstraction for different session storages.
@@ -87,11 +87,11 @@ where
 #[cfg(feature = "pool")]
 mod pool {
   use crate::{
-    database::{client::postgres::Postgres, Decode, Encode},
+    Error,
+    database::client::postgres::Postgres,
     http::session::{SessionId, SessionState, SessionStore},
-    misc::Lock,
+    misc::{Decode, Encode, Lock},
     pool::{ResourceManager, SimplePool, SimplePoolResource},
-    Error,
   };
 
   impl<CS, E, R, RL, RM> SessionStore<CS, E> for SimplePool<RL, RM>
@@ -134,13 +134,13 @@ mod pool {
 #[cfg(feature = "postgres")]
 mod postgres {
   use crate::{
+    Error,
     database::{
-      client::postgres::{Executor, ExecutorBuffer, Postgres},
-      Decode, Encode, Executor as _, Record,
+      Executor as _, Record,
+      client::postgres::{ExecutorBuffer, Postgres, PostgresExecutor},
     },
     http::session::{SessionId, SessionState, SessionStore},
-    misc::{LeaseMut, Stream},
-    Error,
+    misc::{Decode, Encode, LeaseMut, Stream},
   };
 
   /// Expects the following SQL table definition in your database. Column names can be changed
@@ -156,7 +156,7 @@ mod postgres {
   ///
   /// Change `SOME_TY` to any type you want, just make sure that it implements [`Decode`] and
   /// [`Encode`] in the Rust side.
-  impl<CS, E, EB, S> SessionStore<CS, E> for Executor<E, EB, S>
+  impl<CS, E, EB, S> SessionStore<CS, E> for PostgresExecutor<E, EB, S>
   where
     CS: for<'de> Decode<'de, Postgres<E>> + Encode<Postgres<E>>,
     E: From<Error>,
@@ -182,7 +182,7 @@ mod postgres {
 
     #[inline]
     async fn delete_expired(&mut self) -> Result<(), E> {
-      self.execute("DELETE FROM session WHERE expires_at <= NOW()", |_| {}).await?;
+      self.execute("DELETE FROM session WHERE expires_at <= NOW()", |_| Ok(())).await?;
       Ok(())
     }
 
diff --git a/wtx/src/http2.rs b/wtx/src/http2.rs
index acae74e6..1d6a043b 100644
--- a/wtx/src/http2.rs
+++ b/wtx/src/http2.rs
@@ -58,15 +58,15 @@ use crate::{
     sorp_mut, write_array,
   },
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, Arc, AtomicWaker, ConnectionState, Either,
-    Lease, LeaseMut, Lock, RefCounter, SingleTypeStorage, StreamReader, StreamWriter, Usize,
-    NOOP_WAKER,
+    Arc, AtomicWaker, ConnectionState, Either, Lease, LeaseMut, Lock, NOOP_WAKER, RefCounter,
+    SingleTypeStorage, StreamReader, StreamWriter, Usize,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
   },
 };
 pub use client_stream::ClientStream;
 pub use common_stream::CommonStream;
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   mem,
   pin::pin,
   sync::atomic::{AtomicBool, Ordering},
diff --git a/wtx/src/http2/client_stream.rs b/wtx/src/http2/client_stream.rs
index 31e1cf13..d0c5a396 100644
--- a/wtx/src/http2/client_stream.rs
+++ b/wtx/src/http2/client_stream.rs
@@ -1,6 +1,7 @@
 use crate::{
   http::{ReqResBuffer, ReqResData, ReqUri, Request, StatusCode},
   http2::{
+    CommonStream, Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus,
     hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
     misc::{
       frame_reader_rslt, manage_initial_stream_receiving, manage_recurrent_stream_receiving,
@@ -11,12 +12,11 @@ use crate::{
     stream_state::StreamState,
     u31::U31,
     window::Windows,
-    CommonStream, Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus,
   },
-  misc::{facades::span::_Span, Arc, Lease, LeaseMut, Lock, RefCounter, StreamWriter},
+  misc::{Arc, Lease, LeaseMut, Lock, RefCounter, StreamWriter, facades::span::_Span},
 };
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   pin::pin,
   sync::atomic::AtomicBool,
   task::Poll,
diff --git a/wtx/src/http2/common_stream.rs b/wtx/src/http2/common_stream.rs
index c0c1a0fa..47a50ebd 100644
--- a/wtx/src/http2/common_stream.rs
+++ b/wtx/src/http2/common_stream.rs
@@ -1,6 +1,7 @@
 use crate::{
   http::{Headers, StatusCode},
   http2::{
+    Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus, SendDataMode,
     hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
     misc::{check_content_length, frame_reader_rslt, sorp_mut, status_recv, status_send},
     send_data_mode::SendDataModeBytes,
@@ -9,16 +10,15 @@ use crate::{
     },
     u31::U31,
     window::WindowsPair,
-    Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus, SendDataMode,
   },
-  misc::{facades::span::_Span, Arc, LeaseMut, Lock, RefCounter, StreamWriter, Vector},
+  misc::{Arc, LeaseMut, Lock, RefCounter, StreamWriter, Vector, facades::span::_Span},
 };
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   mem,
   pin::pin,
   sync::atomic::AtomicBool,
-  task::{ready, Poll},
+  task::{Poll, ready},
 };
 
 /// Groups common client and server operations as well as low level methods that deal with
diff --git a/wtx/src/http2/data_frame.rs b/wtx/src/http2/data_frame.rs
index d8968705..d4afe545 100644
--- a/wtx/src/http2/data_frame.rs
+++ b/wtx/src/http2/data_frame.rs
@@ -1,9 +1,9 @@
 use crate::http2::{
+  Http2Error,
   common_flags::CommonFlags,
   frame_init::{FrameInit, FrameInitTy},
   misc::{protocol_err, trim_frame_pad},
   u31::U31,
-  Http2Error,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/frame_reader.rs b/wtx/src/http2/frame_reader.rs
index 6f123a3e..04a0f3d4 100644
--- a/wtx/src/http2/frame_reader.rs
+++ b/wtx/src/http2/frame_reader.rs
@@ -20,6 +20,7 @@ macro_rules! prft {
 
 use crate::{
   http2::{
+    Http2Buffer, Http2Data, Http2Error,
     frame_init::{FrameInit, FrameInitTy},
     go_away_frame::GoAwayFrame,
     misc::{process_higher_operation_err, protocol_err, read_frame, send_go_away, write_array},
@@ -27,19 +28,18 @@ use crate::{
     process_receipt_frame_ty::ProcessReceiptFrameTy,
     settings_frame::SettingsFrame,
     window_update_frame::WindowUpdateFrame,
-    Http2Buffer, Http2Data, Http2Error,
   },
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, Arc, AtomicWaker, LeaseMut, Lock,
-    RefCounter, StreamReader, StreamWriter,
+    Arc, AtomicWaker, LeaseMut, Lock, RefCounter, StreamReader, StreamWriter,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
   },
 };
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   mem,
   pin::pin,
   sync::atomic::AtomicBool,
-  task::{ready, Poll},
+  task::{Poll, ready},
 };
 
 pub(crate) async fn frame_reader<HB, HD, SR, SW, const IS_CLIENT: bool>(
diff --git a/wtx/src/http2/go_away_frame.rs b/wtx/src/http2/go_away_frame.rs
index 566f7606..c32bb2ae 100644
--- a/wtx/src/http2/go_away_frame.rs
+++ b/wtx/src/http2/go_away_frame.rs
@@ -1,9 +1,9 @@
 use crate::http2::{
+  Http2Error, Http2ErrorCode,
   common_flags::CommonFlags,
   frame_init::{FrameInit, FrameInitTy},
   misc::protocol_err,
   u31::U31,
-  Http2Error, Http2ErrorCode,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/headers_frame.rs b/wtx/src/http2/headers_frame.rs
index 7795838b..4d1d8bec 100644
--- a/wtx/src/http2/headers_frame.rs
+++ b/wtx/src/http2/headers_frame.rs
@@ -1,6 +1,7 @@
 use crate::{
   http::{Header, KnownHeaderName, Method, ReqResBuffer},
   http2::{
+    Http2Error, Http2Params,
     common_flags::CommonFlags,
     frame_init::{FrameInit, FrameInitTy},
     hpack_decoder::HpackDecoder,
@@ -9,9 +10,8 @@ use crate::{
     misc::{protocol_err, trim_frame_pad},
     u31::U31,
     uri_buffer::UriBuffer,
-    Http2Error, Http2Params,
   },
-  misc::{from_utf8_basic, ArrayString, FromRadix10, LeaseMut, Usize},
+  misc::{ArrayString, FromRadix10, LeaseMut, Usize, from_utf8_basic},
 };
 
 // Some fields of `hsreqh` are only meant to be used locally for writing purposes.
diff --git a/wtx/src/http2/hpack_decoder.rs b/wtx/src/http2/hpack_decoder.rs
index 618dde1a..adb3d04f 100644
--- a/wtx/src/http2/hpack_decoder.rs
+++ b/wtx/src/http2/hpack_decoder.rs
@@ -1,11 +1,11 @@
 use crate::{
-  http::{HeaderName, KnownHeaderName, Method, StatusCode, _HeaderNameBuffer, _HeaderValueBuffer},
+  http::{_HeaderNameBuffer, _HeaderValueBuffer, HeaderName, KnownHeaderName, Method, StatusCode},
   http2::{
+    Http2Error, Http2ErrorCode,
     hpack_header::{HpackHeaderBasic, HpackHeaderName},
     hpack_headers::HpackHeaders,
     huffman::huffman_decode,
     misc::protocol_err,
-    Http2Error, Http2ErrorCode,
   },
   misc::{ArrayVector, Usize},
 };
@@ -204,11 +204,7 @@ impl HpackDecoder {
       (HpackHeaderName::new(buffer)?, &**buffer)
     } else {
       let hhn = HpackHeaderName::new(before)?;
-      if hhn.is_field() {
-        (hhn, before)
-      } else {
-        (hhn, &[][..])
-      }
+      if hhn.is_field() { (hhn, before) } else { (hhn, &[][..]) }
     };
     *data = after;
     Ok((hhn, HeaderName::from_bytes(bytes)?))
diff --git a/wtx/src/http2/hpack_encoder.rs b/wtx/src/http2/hpack_encoder.rs
index 997900c1..7b2c8750 100644
--- a/wtx/src/http2/hpack_encoder.rs
+++ b/wtx/src/http2/hpack_encoder.rs
@@ -11,10 +11,10 @@
 use crate::{
   http::{Header, KnownHeaderName, Method, StatusCode},
   http2::{
-    hpack_header::HpackHeaderBasic, hpack_headers::HpackHeaders, huffman::huffman_encode,
-    misc::protocol_err, Http2Error,
+    Http2Error, hpack_header::HpackHeaderBasic, hpack_headers::HpackHeaders,
+    huffman::huffman_encode, misc::protocol_err,
   },
-  misc::{Rng, Usize, Vector, _random_state, _unreachable, mem_transfer::_shift_copyable_chunks},
+  misc::{_random_state, _unreachable, Rng, Usize, Vector, mem_transfer::_shift_copyable_chunks},
 };
 use core::{
   hash::{BuildHasher, Hasher},
diff --git a/wtx/src/http2/hpack_header.rs b/wtx/src/http2/hpack_header.rs
index e1ccc168..a70106c5 100644
--- a/wtx/src/http2/hpack_header.rs
+++ b/wtx/src/http2/hpack_header.rs
@@ -1,6 +1,6 @@
 use crate::{
   http::{Method, Protocol, StatusCode},
-  http2::{misc::protocol_err, Http2Error},
+  http2::{Http2Error, misc::protocol_err},
 };
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/http2_buffer.rs b/wtx/src/http2/http2_buffer.rs
index e8041a02..6581db97 100644
--- a/wtx/src/http2/http2_buffer.rs
+++ b/wtx/src/http2/http2_buffer.rs
@@ -1,11 +1,11 @@
 use crate::{
   http2::{
-    hpack_decoder::HpackDecoder, hpack_encoder::HpackEncoder, index_map::IndexMap,
-    initial_server_header::InitialServerHeader, uri_buffer::UriBuffer, Scrp, Sorp,
+    Scrp, Sorp, hpack_decoder::HpackDecoder, hpack_encoder::HpackEncoder, index_map::IndexMap,
+    initial_server_header::InitialServerHeader, uri_buffer::UriBuffer,
   },
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, simple_seed, Arc, AtomicWaker, Lease,
-    LeaseMut, Rng, Vector,
+    Arc, AtomicWaker, Lease, LeaseMut, Rng, Vector,
+    partitioned_filled_buffer::PartitionedFilledBuffer, simple_seed,
   },
 };
 use alloc::boxed::Box;
diff --git a/wtx/src/http2/http2_data.rs b/wtx/src/http2/http2_data.rs
index 5638fc21..e681f80a 100644
--- a/wtx/src/http2/http2_data.rs
+++ b/wtx/src/http2/http2_data.rs
@@ -1,6 +1,6 @@
 use crate::{
   http2::{
-    http2_params_send::Http2ParamsSend, u31::U31, window::Windows, Http2Buffer, Http2Params,
+    Http2Buffer, Http2Params, http2_params_send::Http2ParamsSend, u31::U31, window::Windows,
   },
   misc::{Lease, LeaseMut, StreamWriter},
 };
diff --git a/wtx/src/http2/http2_params.rs b/wtx/src/http2/http2_params.rs
index 595c0911..5cedbcca 100644
--- a/wtx/src/http2/http2_params.rs
+++ b/wtx/src/http2/http2_params.rs
@@ -1,7 +1,7 @@
 use crate::http2::{
-  settings_frame::SettingsFrame, u31::U31, MAX_BODY_LEN, MAX_CONCURRENT_STREAMS_NUM, MAX_FRAME_LEN,
-  MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND, MAX_HEADERS_LEN, MAX_HPACK_LEN,
-  MAX_RECV_STREAMS_NUM, READ_BUFFER_LEN,
+  MAX_BODY_LEN, MAX_CONCURRENT_STREAMS_NUM, MAX_FRAME_LEN, MAX_FRAME_LEN_LOWER_BOUND,
+  MAX_FRAME_LEN_UPPER_BOUND, MAX_HEADERS_LEN, MAX_HPACK_LEN, MAX_RECV_STREAMS_NUM, READ_BUFFER_LEN,
+  settings_frame::SettingsFrame, u31::U31,
 };
 
 /// Indicates to a remote peer the receiving parameters of a connection as well as its streams.
diff --git a/wtx/src/http2/http2_params_send.rs b/wtx/src/http2/http2_params_send.rs
index 56b60a2a..4a9e173b 100644
--- a/wtx/src/http2/http2_params_send.rs
+++ b/wtx/src/http2/http2_params_send.rs
@@ -1,6 +1,6 @@
 use crate::http2::{
-  hpack_encoder::HpackEncoder, settings_frame::SettingsFrame, u31::U31, Scrp, Sorp, Window,
-  MAX_FRAME_LEN, MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND, MAX_HPACK_LEN,
+  MAX_FRAME_LEN, MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND, MAX_HPACK_LEN, Scrp, Sorp,
+  Window, hpack_encoder::HpackEncoder, settings_frame::SettingsFrame, u31::U31,
 };
 use core::cmp::Ordering;
 
diff --git a/wtx/src/http2/huffman.rs b/wtx/src/http2/huffman.rs
index 89ec3556..1b62b6f9 100644
--- a/wtx/src/http2/huffman.rs
+++ b/wtx/src/http2/huffman.rs
@@ -1,10 +1,10 @@
 use crate::{
   http2::{
-    huffman_tables::{DECODED, DECODE_TABLE, ENCODE_TABLE, END_OF_STRING, ERROR},
-    misc::protocol_err,
     Http2Error, Http2ErrorCode,
+    huffman_tables::{DECODE_TABLE, DECODED, ENCODE_TABLE, END_OF_STRING, ERROR},
+    misc::protocol_err,
   },
-  misc::{ArrayVector, Vector, _unreachable},
+  misc::{_unreachable, ArrayVector, Vector},
 };
 
 #[inline]
diff --git a/wtx/src/http2/misc.rs b/wtx/src/http2/misc.rs
index 3be71d05..82e93588 100644
--- a/wtx/src/http2/misc.rs
+++ b/wtx/src/http2/misc.rs
@@ -1,6 +1,8 @@
 use crate::{
   http::ReqResBuffer,
   http2::{
+    Http2Buffer, Http2Data, Http2Error, Http2ErrorCode, Http2Params, Http2RecvStatus,
+    Http2SendStatus, Scrp, Sorp,
     common_flags::CommonFlags,
     frame_init::{FrameInit, FrameInitTy},
     go_away_frame::GoAwayFrame,
@@ -12,19 +14,17 @@ use crate::{
     stream_state::StreamState,
     u31::U31,
     uri_buffer::UriBuffer,
-    Http2Buffer, Http2Data, Http2Error, Http2ErrorCode, Http2Params, Http2RecvStatus,
-    Http2SendStatus, Scrp, Sorp,
   },
   misc::{
-    AtomicWaker, LeaseMut, Lock, RefCounter, StreamReader, StreamWriter, Usize, _read_header,
-    _read_payload, partitioned_filled_buffer::PartitionedFilledBuffer,
+    _read_header, _read_payload, AtomicWaker, LeaseMut, Lock, RefCounter, StreamReader,
+    StreamWriter, Usize, partitioned_filled_buffer::PartitionedFilledBuffer,
   },
 };
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   pin::pin,
   sync::atomic::{AtomicBool, Ordering},
-  task::{ready, Context, Poll},
+  task::{Context, Poll, ready},
 };
 
 #[inline]
@@ -390,11 +390,7 @@ where
 
 #[inline]
 pub(crate) fn server_header_stream_state(has_eos: bool) -> StreamState {
-  if has_eos {
-    StreamState::HalfClosedRemote
-  } else {
-    StreamState::Open
-  }
+  if has_eos { StreamState::HalfClosedRemote } else { StreamState::Open }
 }
 
 #[inline]
diff --git a/wtx/src/http2/ping_frame.rs b/wtx/src/http2/ping_frame.rs
index 338208d9..93127696 100644
--- a/wtx/src/http2/ping_frame.rs
+++ b/wtx/src/http2/ping_frame.rs
@@ -1,8 +1,8 @@
 use crate::http2::{
+  Http2Error, Http2ErrorCode,
   common_flags::CommonFlags,
   frame_init::{FrameInit, FrameInitTy},
   u31::U31,
-  Http2Error, Http2ErrorCode,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/process_receipt_frame_ty.rs b/wtx/src/http2/process_receipt_frame_ty.rs
index 043ad904..279fc383 100644
--- a/wtx/src/http2/process_receipt_frame_ty.rs
+++ b/wtx/src/http2/process_receipt_frame_ty.rs
@@ -1,6 +1,7 @@
 use crate::{
   http::{HttpError, StatusCode},
   http2::{
+    Http2Error, Http2ErrorCode, Http2Params, Scrp, Sorp,
     data_frame::DataFrame,
     frame_init::FrameInit,
     hpack_decoder::HpackDecoder,
@@ -17,11 +18,10 @@ use crate::{
     uri_buffer::UriBuffer,
     window::{Windows, WindowsPair},
     window_update_frame::WindowUpdateFrame,
-    Http2Error, Http2ErrorCode, Http2Params, Scrp, Sorp,
   },
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, AtomicWaker, StreamReader, StreamWriter,
-    NOOP_WAKER,
+    AtomicWaker, NOOP_WAKER, StreamReader, StreamWriter,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
   },
 };
 use core::{mem, sync::atomic::AtomicBool, task::Waker};
diff --git a/wtx/src/http2/reset_stream_frame.rs b/wtx/src/http2/reset_stream_frame.rs
index b927e1ef..fccb95fe 100644
--- a/wtx/src/http2/reset_stream_frame.rs
+++ b/wtx/src/http2/reset_stream_frame.rs
@@ -1,9 +1,9 @@
 use crate::http2::{
+  Http2Error, Http2ErrorCode,
   common_flags::CommonFlags,
   frame_init::{FrameInit, FrameInitTy},
   misc::protocol_err,
   u31::U31,
-  Http2Error, Http2ErrorCode,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/send_msg.rs b/wtx/src/http2/send_msg.rs
index 56824718..285eaf4f 100644
--- a/wtx/src/http2/send_msg.rs
+++ b/wtx/src/http2/send_msg.rs
@@ -28,6 +28,7 @@ macro_rules! init {
 use crate::{
   http::{Headers, Trailers},
   http2::{
+    Http2Buffer, Http2Data, Http2Error, Http2SendStatus, SendDataMode,
     continuation_frame::ContinuationFrame,
     data_frame::DataFrame,
     headers_frame::HeadersFrame,
@@ -39,12 +40,11 @@ use crate::{
     stream_state::StreamState,
     u31::U31,
     window::WindowsPair,
-    Http2Buffer, Http2Data, Http2Error, Http2SendStatus, SendDataMode,
   },
   misc::{LeaseMut, Lock, RefCounter, StreamWriter, Usize, Vector},
 };
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   pin::pin,
   sync::atomic::{AtomicBool, Ordering},
   task::{Poll, Waker},
diff --git a/wtx/src/http2/server_stream.rs b/wtx/src/http2/server_stream.rs
index aab60d81..9fdea51d 100644
--- a/wtx/src/http2/server_stream.rs
+++ b/wtx/src/http2/server_stream.rs
@@ -1,19 +1,19 @@
 use crate::{
   http::{Method, Protocol, ReqResBuffer, ReqResData, Response},
   http2::{
+    CommonStream, Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus,
     hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
     misc::{manage_recurrent_stream_receiving, process_higher_operation_err},
     send_msg::send_msg,
     stream_receiver::StreamControlRecvParams,
     u31::U31,
-    CommonStream, Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus,
   },
   misc::{
-    facades::span::_Span, Arc, Lease, LeaseMut, Lock, RefCounter, SingleTypeStorage, StreamWriter,
+    Arc, Lease, LeaseMut, Lock, RefCounter, SingleTypeStorage, StreamWriter, facades::span::_Span,
   },
 };
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   pin::pin,
   sync::atomic::AtomicBool,
 };
diff --git a/wtx/src/http2/settings_frame.rs b/wtx/src/http2/settings_frame.rs
index 4eb74bb8..053d0fbe 100644
--- a/wtx/src/http2/settings_frame.rs
+++ b/wtx/src/http2/settings_frame.rs
@@ -1,10 +1,10 @@
 use crate::{
   http2::{
+    Http2Error, Http2ErrorCode, MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND,
     common_flags::CommonFlags,
     frame_init::{FrameInit, FrameInitTy},
     misc::protocol_err,
     u31::U31,
-    Http2Error, Http2ErrorCode, MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND,
   },
   misc::ArrayChunks,
 };
diff --git a/wtx/src/http2/web_socket_over_stream.rs b/wtx/src/http2/web_socket_over_stream.rs
index 4d9ff82a..e02db114 100644
--- a/wtx/src/http2/web_socket_over_stream.rs
+++ b/wtx/src/http2/web_socket_over_stream.rs
@@ -8,6 +8,7 @@ use crate::{
     Xorshift64,
   },
   web_socket::{
+    Frame, FrameMut, OpCode, ReadFrameInfo,
     web_socket_reader::{
       manage_auto_reply, manage_op_code_of_continuation_frames,
       manage_op_code_of_first_continuation_frame, manage_op_code_of_first_final_frame,
@@ -15,7 +16,6 @@ use crate::{
       unmask_nb,
     },
     web_socket_writer::manage_normal_frame,
-    Frame, FrameMut, OpCode, ReadFrameInfo,
   },
 };
 
diff --git a/wtx/src/http2/window.rs b/wtx/src/http2/window.rs
index 83d08b52..e3b4a097 100644
--- a/wtx/src/http2/window.rs
+++ b/wtx/src/http2/window.rs
@@ -1,7 +1,7 @@
 use crate::{
   http2::{
-    http2_params_send::Http2ParamsSend, misc::write_array, u31::U31,
-    window_update_frame::WindowUpdateFrame, Http2Error, Http2ErrorCode, Http2Params,
+    Http2Error, Http2ErrorCode, Http2Params, http2_params_send::Http2ParamsSend, misc::write_array,
+    u31::U31, window_update_frame::WindowUpdateFrame,
   },
   misc::StreamWriter,
 };
diff --git a/wtx/src/http2/window_update_frame.rs b/wtx/src/http2/window_update_frame.rs
index e89aad8d..d08ccb40 100644
--- a/wtx/src/http2/window_update_frame.rs
+++ b/wtx/src/http2/window_update_frame.rs
@@ -1,9 +1,9 @@
 use crate::http2::{
+  Http2Error, Http2ErrorCode,
   common_flags::CommonFlags,
   frame_init::{FrameInit, FrameInitTy},
   misc::protocol_err,
   u31::U31,
-  Http2Error, Http2ErrorCode,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/macros.rs b/wtx/src/macros.rs
index efb9bd6b..09b049e7 100644
--- a/wtx/src/macros.rs
+++ b/wtx/src/macros.rs
@@ -26,7 +26,7 @@ macro_rules! create_enum {
       #[inline]
       /// The total number of variants
       $v const fn len() -> usize {
-        const { 0 $( + { let _ = $variant_n_fixed; 1 })* }
+        const { 0 $( + { let _: $n = $variant_n_fixed; 1 })* }
       }
 
       /// See [`$crate::misc::EnumVarStrings`].
@@ -37,7 +37,7 @@ macro_rules! create_enum {
         $({
           #[allow(unused_mut, reason = "repetition can be empty")]
           let mut local_n = 0;
-          let _ = $variant_n_fixed;
+          let _: $n = $variant_n_fixed;
           $({ let _ = $variant_str_fixed; local_n += 1; })?
           $({ let _ = $variant_str_fixed_n; local_n += 1; })*
           #[allow(unused_assignments, reason = "repetition can be empty")]
diff --git a/wtx/src/misc.rs b/wtx/src/misc.rs
index c6cdfcba..85638d4c 100644
--- a/wtx/src/misc.rs
+++ b/wtx/src/misc.rs
@@ -6,13 +6,17 @@ mod array_vector;
 mod blocks_deque;
 mod buffer_mode;
 mod bytes_fmt;
+mod clear;
 mod connection_state;
+pub(crate) mod counter_writer;
+mod decode;
+mod decontroller;
 mod deque;
 mod either;
+mod encode;
 mod enum_var_strings;
 pub(crate) mod facades;
-pub(crate) mod filled_buffer;
-mod filled_buffer_writer;
+mod filled_buffer;
 mod fn_fut;
 mod from_radix_10;
 mod fun;
@@ -25,12 +29,14 @@ pub(crate) mod mem_transfer;
 mod noop_waker;
 mod optimization;
 pub(crate) mod partitioned_filled_buffer;
+mod percent_encoding;
 mod query_writer;
 mod ref_counter;
 mod rng;
 mod role;
 mod single_type_storage;
 mod stream;
+mod suffix_writer;
 mod sync;
 #[cfg(feature = "tokio-rustls")]
 mod tokio_rustls;
@@ -51,27 +57,32 @@ pub use buffer_mode::BufferMode;
 pub use bytes_fmt::BytesFmt;
 pub use connection_state::ConnectionState;
 use core::{any::type_name, fmt::Write as _, ops::Range, time::Duration};
+pub use decode::{Decode, DecodeSeq};
+pub use decontroller::DEController;
 pub use deque::{Deque, DequeueError};
 pub use either::Either;
+pub use encode::Encode;
 pub use enum_var_strings::EnumVarStrings;
 pub use facades::arc::Arc;
-pub use filled_buffer_writer::FilledBufferWriter;
+pub use filled_buffer::{FilledBuffer, FilledBufferVectorMut};
 pub use fn_fut::*;
 pub use from_radix_10::{FromRadix10, FromRadix10Error};
 pub use fun::Fun;
-pub use generic_time::{GenericTime, GenericTimeProvider};
+pub use generic_time::GenericTime;
 pub use incomplete_utf8_char::{CompletionErr, IncompleteUtf8Char};
 pub use interspace::Intersperse;
 pub use lease::{Lease, LeaseMut};
 pub use lock::Lock;
 pub use noop_waker::NOOP_WAKER;
 pub use optimization::*;
+pub use percent_encoding::{AsciiSet, PercentDecode, PercentEncode};
 pub use query_writer::QueryWriter;
 pub use ref_counter::RefCounter;
 pub use rng::*;
 pub use role::Role;
 pub use single_type_storage::SingleTypeStorage;
 pub use stream::{BytesStream, Stream, StreamReader, StreamWithTls, StreamWriter};
+pub use suffix_writer::{SuffixWriter, SuffixWriterFbvm, SuffixWriterMut};
 pub use sync::*;
 pub use uri::{Uri, UriArrayString, UriCow, UriRef, UriString};
 pub use usize::Usize;
@@ -79,6 +90,8 @@ pub use utf8_errors::{BasicUtf8Error, ExtUtf8Error, StdUtf8Error};
 pub use vector::{Vector, VectorError};
 pub use wrapper::Wrapper;
 
+pub(crate) type U64Array = ArrayVector<u8, 20>;
+
 /// Hashes a password using the `argon2` algorithm.
 #[cfg(feature = "argon2")]
 #[inline]
@@ -118,33 +131,20 @@ pub fn into_rslt<T>(opt: Option<T>) -> crate::Result<T> {
 /// Similar to `collect_seq` of `serde` but expects a `Result`.
 #[cfg(feature = "serde")]
 #[inline]
-pub fn serde_collect_seq_rslt<E, I, S, T>(ser: S, into_iter: I) -> Result<(), E>
+pub fn serde_collect_seq_rslt<E, I, S, T>(ser: S, into_iter: I) -> Result<S::Ok, S::Error>
 where
-  E: From<S::Error>,
+  E: core::fmt::Display,
   I: IntoIterator<Item = Result<T, E>>,
-  S: serde::Serializer<Ok = ()>,
+  S: serde::Serializer,
   T: serde::Serialize,
 {
-  use serde::ser::SerializeSeq;
+  use serde::ser::{Error, SerializeSeq};
   let iter = into_iter.into_iter();
   let mut sq = ser.serialize_seq(_conservative_size_hint_len(iter.size_hint()))?;
   for elem in iter {
-    sq.serialize_element(&elem?)?;
+    sq.serialize_element(&elem.map_err(S::Error::custom)?)?;
   }
-  sq.end()?;
-  Ok(())
-}
-
-/// Serializes an iterator that implements `Clone`.
-#[cfg(feature = "serde")]
-#[inline]
-pub fn serde_serialize_iter<I, S>(iter: I, serializer: S) -> Result<S::Ok, S::Error>
-where
-  I: Clone + Iterator,
-  I::Item: serde::Serialize,
-  S: serde::Serializer,
-{
-  serializer.collect_seq(iter.clone())
+  sq.end()
 }
 
 /// Sleeps for the specified amount of time.
@@ -177,7 +177,7 @@ pub fn tracing_tree_init(
   fallback_opt: Option<&str>,
 ) -> Result<(), tracing_subscriber::util::TryInitError> {
   use tracing_subscriber::{
-    prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter,
+    EnvFilter, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt,
   };
   let fallback = fallback_opt.unwrap_or("debug");
   let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(fallback));
@@ -207,12 +207,28 @@ pub fn u32_array_string(n: u32) -> ArrayString<10> {
   str
 }
 
-/// Transforms an `u64` into a [`ArrayString`].
+/// Fills an `u64` into a [`U64Array`].
 #[inline]
-pub fn u64_array_string(n: u64) -> ArrayString<20> {
-  let mut str = ArrayString::new();
-  let _rslt = str.write_fmt(format_args!("{n}"));
-  str
+pub fn u64_array(data: &mut U64Array, mut value: u64) -> &str {
+  let mut idx: u8 = 20;
+  let mut buffer = [0u8; 20];
+  for local_idx in 1..=20 {
+    idx = 20u8.wrapping_sub(local_idx);
+    let Some(elem) = buffer.get_mut(usize::from(idx)) else {
+      break;
+    };
+    *elem = u8::try_from(value % 10).unwrap_or_default().wrapping_add(48);
+    value /= 10;
+    if value == 0 {
+      break;
+    }
+  }
+  *data = U64Array::from_array([0; 20]);
+  let len = 20u16.wrapping_sub(idx.into());
+  let slice = data.get_mut(..usize::from(len)).unwrap_or_default();
+  slice.copy_from_slice(buffer.get(usize::from(idx)..).unwrap_or_default());
+  // SAFETY: Numbers are ASCII
+  unsafe { core::str::from_utf8_unchecked(slice) }
 }
 
 #[expect(clippy::as_conversions, reason = "`match` correctly handles conversions")]
@@ -308,7 +324,7 @@ where
 #[inline]
 pub(crate) async fn _read_payload<SR>(
   (header_len, payload_len): (usize, usize),
-  network_buffer: &mut partitioned_filled_buffer::PartitionedFilledBuffer,
+  pfb: &mut partitioned_filled_buffer::PartitionedFilledBuffer,
   read: &mut usize,
   stream: &mut SR,
 ) -> crate::Result<()>
@@ -316,20 +332,20 @@ where
   SR: StreamReader,
 {
   let frame_len = header_len.wrapping_add(payload_len);
-  network_buffer._reserve(frame_len)?;
+  pfb._reserve(frame_len)?;
   loop {
     if *read >= frame_len {
       break;
     }
-    let local_buffer = network_buffer._following_rest_mut().get_mut(*read..).unwrap_or_default();
+    let local_buffer = pfb._following_rest_mut().get_mut(*read..).unwrap_or_default();
     let local_read = stream.read(local_buffer).await?;
     if local_read == 0 {
       return Err(crate::Error::ClosedConnection);
     }
     *read = read.wrapping_add(local_read);
   }
-  network_buffer._set_indices(
-    network_buffer._current_end_idx().wrapping_add(header_len),
+  pfb._set_indices(
+    pfb._current_end_idx().wrapping_add(header_len),
     payload_len,
     read.wrapping_sub(frame_len),
   )?;
@@ -371,3 +387,17 @@ pub(crate) const fn _unreachable() -> ! {
 pub(crate) fn _usize_range_from_u32_range(range: Range<u32>) -> Range<usize> {
   *Usize::from(range.start)..*Usize::from(range.end)
 }
+
+#[cfg(test)]
+pub(crate) mod tests {
+  use crate::misc::{ArrayVector, u64_array};
+
+  #[test]
+  fn has_correct_stmt_number() {
+    let mut data = ArrayVector::new();
+    assert_eq!(u64_array(&mut data, 0), "0");
+    assert_eq!(u64_array(&mut data, 12), "12");
+    assert_eq!(u64_array(&mut data, 1844674407370955161), "1844674407370955161");
+    assert_eq!(u64_array(&mut data, 18446744073709551615), "18446744073709551615");
+  }
+}
diff --git a/wtx/src/misc/array_string.rs b/wtx/src/misc/array_string.rs
index a04fdee1..601b407d 100644
--- a/wtx/src/misc/array_string.rs
+++ b/wtx/src/misc/array_string.rs
@@ -1,4 +1,4 @@
-use crate::misc::{char_slice, from_utf8_basic, BasicUtf8Error, Lease, Usize};
+use crate::misc::{BasicUtf8Error, Lease, Usize, char_slice, from_utf8_basic};
 use core::{
   borrow::Borrow,
   cmp::Ordering,
@@ -262,6 +262,17 @@ impl<'args, const N: usize> TryFrom<Arguments<'args>> for ArrayString<N> {
   }
 }
 
+impl<const N: usize> TryFrom<&[u8]> for ArrayString<N> {
+  type Error = crate::Error;
+
+  #[inline]
+  fn try_from(from: &[u8]) -> Result<Self, Self::Error> {
+    let mut this = Self::default();
+    this.push_str(from_utf8_basic(from)?)?;
+    Ok(this)
+  }
+}
+
 impl<const N: usize> TryFrom<&str> for ArrayString<N> {
   type Error = crate::Error;
 
@@ -312,11 +323,11 @@ mod arbitrary {
 
 #[cfg(feature = "serde")]
 mod serde {
-  use crate::misc::{from_utf8_basic, ArrayString};
+  use crate::misc::{ArrayString, from_utf8_basic};
   use core::{fmt::Formatter, marker::PhantomData};
   use serde::{
-    de::{self, Visitor},
     Deserialize, Deserializer, Serialize, Serializer,
+    de::{self, Visitor},
   };
 
   impl<'de, const N: usize> Deserialize<'de> for ArrayString<N> {
diff --git a/wtx/src/misc/array_vector.rs b/wtx/src/misc/array_vector.rs
index 536b60e6..f873721a 100644
--- a/wtx/src/misc/array_vector.rs
+++ b/wtx/src/misc/array_vector.rs
@@ -1,10 +1,10 @@
 #![expect(clippy::mem_forget, reason = "out-of-bounds elements are manually dropped")]
 
-use crate::misc::{char_slice, Lease, LeaseMut, Usize};
+use crate::misc::{Lease, LeaseMut, Usize, Wrapper, char_slice};
 use core::{
   cmp::Ordering,
   fmt::{self, Debug, Formatter},
-  mem::{self, needs_drop, MaybeUninit},
+  mem::{self, MaybeUninit, needs_drop},
   ops::{Deref, DerefMut},
   ptr, slice,
 };
@@ -87,7 +87,7 @@ impl<T, const N: usize> ArrayVector<T, N> {
         unsafe {
           drop_elements(diff, actual_len, data.as_mut_ptr());
         }
-      };
+      }
     }
     mem::forget(data);
     this
@@ -340,6 +340,16 @@ impl<T, const N: usize> Drop for ArrayVector<T, N> {
 
 impl<T, const N: usize> Eq for ArrayVector<T, N> where T: Eq {}
 
+impl<T, const N: usize> FromIterator<T> for Wrapper<crate::Result<ArrayVector<T, N>>> {
+  #[inline]
+  fn from_iter<I>(iter: I) -> Self
+  where
+    I: IntoIterator<Item = T>,
+  {
+    Wrapper(ArrayVector::from_iter(iter))
+  }
+}
+
 impl<T, const N: usize> IntoIterator for ArrayVector<T, N> {
   type IntoIter = IntoIter<T, N>;
   type Item = T;
@@ -457,6 +467,20 @@ impl<T, const N: usize> From<[T; N]> for ArrayVector<T, N> {
   }
 }
 
+impl<T, const N: usize> TryFrom<&[T]> for ArrayVector<T, N>
+where
+  T: Clone,
+{
+  type Error = crate::Error;
+
+  #[inline]
+  fn try_from(from: &[T]) -> Result<Self, Self::Error> {
+    let mut this = Self::new();
+    this.extend_from_cloneable_slice(from)?;
+    Ok(this)
+  }
+}
+
 impl<const N: usize> fmt::Write for ArrayVector<u8, N> {
   #[inline]
   fn write_char(&mut self, c: char) -> fmt::Result {
@@ -590,9 +614,9 @@ mod serde {
   use crate::misc::ArrayVector;
   use core::{fmt::Formatter, marker::PhantomData};
   use serde::{
+    Deserialize, Deserializer, Serialize, Serializer,
     de::{self, SeqAccess, Visitor},
     ser::SerializeTuple,
-    Deserialize, Deserializer, Serialize, Serializer,
   };
 
   impl<'de, T, const N: usize> Deserialize<'de> for ArrayVector<T, N>
diff --git a/wtx/src/misc/blocks_deque/blocks_deque_builder.rs b/wtx/src/misc/blocks_deque/blocks_deque_builder.rs
index 8063e1a9..7066386f 100644
--- a/wtx/src/misc/blocks_deque/blocks_deque_builder.rs
+++ b/wtx/src/misc/blocks_deque/blocks_deque_builder.rs
@@ -1,6 +1,6 @@
 use core::slice;
 
-use crate::misc::{blocks_deque::metadata::Metadata, BlocksDeque, BlocksDequeError, BufferMode};
+use crate::misc::{BlocksDeque, BlocksDequeError, BufferMode, blocks_deque::metadata::Metadata};
 
 /// Allows the construction of a single block through the insertion of indivial elements.
 #[derive(Debug)]
diff --git a/wtx/src/misc/clear.rs b/wtx/src/misc/clear.rs
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/wtx/src/misc/clear.rs
@@ -0,0 +1,1 @@
+
diff --git a/wtx/src/misc/connection_state.rs b/wtx/src/misc/connection_state.rs
index 986b10d9..329e256f 100644
--- a/wtx/src/misc/connection_state.rs
+++ b/wtx/src/misc/connection_state.rs
@@ -40,11 +40,7 @@ impl LeaseMut<ConnectionState> for ConnectionState {
 impl From<bool> for ConnectionState {
   #[inline]
   fn from(from: bool) -> Self {
-    if from {
-      Self::Open
-    } else {
-      Self::Closed
-    }
+    if from { Self::Open } else { Self::Closed }
   }
 }
 
diff --git a/wtx/src/misc/counter_writer.rs b/wtx/src/misc/counter_writer.rs
new file mode 100644
index 00000000..a6db360b
--- /dev/null
+++ b/wtx/src/misc/counter_writer.rs
@@ -0,0 +1,151 @@
+#![allow(dead_code, reason = "feature selection")]
+
+use crate::misc::{LeaseMut, SuffixWriter, Vector};
+use core::marker::PhantomData;
+
+pub(crate) trait CounterWriter<E, V>
+where
+  E: From<crate::Error>,
+  V: LeaseMut<Vector<u8>>,
+{
+  fn write(
+    &self,
+    sw: &mut SuffixWriter<V>,
+    include_len: bool,
+    prefix: Option<u8>,
+    cb: impl FnOnce(&mut SuffixWriter<V>) -> Result<(), E>,
+  ) -> Result<(), E>;
+
+  fn write_iter<T>(
+    &self,
+    sw: &mut SuffixWriter<V>,
+    iter: impl IntoIterator<Item = T>,
+    prefix: Option<u8>,
+    cb: impl FnMut(T, &mut SuffixWriter<V>) -> Result<(), E>,
+  ) -> Result<(), E>;
+}
+
+#[inline]
+fn write<E, V, const N: usize>(
+  sw: &mut SuffixWriter<V>,
+  include_len: bool,
+  prefix: Option<u8>,
+  sw_cb: impl FnOnce(&mut SuffixWriter<V>) -> Result<(), E>,
+  value_cb: impl FnOnce(&mut SuffixWriter<V>, usize) -> Result<[u8; N], E>,
+) -> Result<(), E>
+where
+  E: From<crate::Error>,
+  V: LeaseMut<Vector<u8>>,
+{
+  let after_prefix = write_init::<_, _, N>(sw, prefix)?;
+  let len_before = if include_len { after_prefix } else { sw._len() };
+  sw_cb(sw)?;
+  let value = value_cb(sw, len_before)?;
+  write_prefix(after_prefix, sw, value);
+  Ok(())
+}
+
+#[inline]
+fn write_init<E, V, const N: usize>(
+  sw: &mut SuffixWriter<V>,
+  prefix: Option<u8>,
+) -> Result<usize, E>
+where
+  E: From<crate::Error>,
+  V: LeaseMut<Vector<u8>>,
+{
+  if let Some(elem) = prefix {
+    sw._extend_from_byte(elem)?;
+  }
+  let after_prefix = sw._len();
+  sw.extend_from_slice(&[0; N])?;
+  Ok(after_prefix)
+}
+
+#[inline]
+fn write_iter<E, T, V, const N: usize>(
+  sw: &mut SuffixWriter<V>,
+  iter: impl IntoIterator<Item = T>,
+  prefix: Option<u8>,
+  mut sw_cb: impl FnMut(T, &mut SuffixWriter<V>) -> Result<(), E>,
+  value_cb: impl FnOnce(usize) -> Result<[u8; N], E>,
+) -> Result<(), E>
+where
+  E: From<crate::Error>,
+  V: LeaseMut<Vector<u8>>,
+{
+  let start = write_init::<_, _, N>(sw, prefix)?;
+  let mut counter: usize = 0;
+  for elem in iter.into_iter().take(u16::MAX.into()) {
+    sw_cb(elem, sw)?;
+    counter = counter.wrapping_add(1);
+  }
+  let value = value_cb(counter)?;
+  write_prefix(start, sw, value);
+  Ok(())
+}
+
+#[inline]
+fn write_prefix<V, const N: usize>(start: usize, sw: &mut SuffixWriter<V>, value: [u8; N])
+where
+  V: LeaseMut<Vector<u8>>,
+{
+  let end = start.wrapping_add(value.len());
+  if let Some(elem) = sw._curr_bytes_mut().get_mut(start..end) {
+    elem.copy_from_slice(&value);
+  }
+}
+
+macro_rules! impl_trait {
+  (
+    $name:ident,
+    $ty:ident
+  ) => {
+    #[derive(Debug)]
+    pub(crate) struct $name<E, V>(PhantomData<(E, V)>);
+
+    impl<E, V> CounterWriter<E, V> for $name<E, V>
+    where
+      E: From<crate::Error>,
+      V: LeaseMut<Vector<u8>>,
+    {
+      #[inline]
+      fn write(
+        &self,
+        sw: &mut SuffixWriter<V>,
+        include_len: bool,
+        prefix: Option<u8>,
+        cb: impl FnOnce(&mut SuffixWriter<V>) -> Result<(), E>,
+      ) -> Result<(), E> {
+        write(sw, include_len, prefix, cb, |local_sw, len_before| {
+          let diff = local_sw._len().wrapping_sub(len_before);
+          Ok($ty::try_from(diff).map_err(Into::into)?.to_be_bytes())
+        })
+      }
+
+      #[inline]
+      fn write_iter<T>(
+        &self,
+        sw: &mut SuffixWriter<V>,
+        iter: impl IntoIterator<Item = T>,
+        prefix: Option<u8>,
+        cb: impl FnMut(T, &mut SuffixWriter<V>) -> Result<(), E>,
+      ) -> Result<(), E> {
+        write_iter(sw, iter, prefix, cb, |counter| {
+          Ok($ty::try_from(counter).map_err(Into::into)?.to_be_bytes())
+        })
+      }
+    }
+
+    impl<E, V> Default for $name<E, V> {
+      #[inline]
+      fn default() -> Self {
+        Self(PhantomData)
+      }
+    }
+  };
+}
+
+impl_trait!(I16Counter, i16);
+impl_trait!(U16Counter, u16);
+impl_trait!(I32Counter, i32);
diff --git a/wtx/src/misc/decode.rs b/wtx/src/misc/decode.rs
new file mode 100644
index 00000000..c39c73da
--- /dev/null
+++ b/wtx/src/misc/decode.rs
@@ -0,0 +1,65 @@
+use crate::misc::{Vector, decontroller::DEController};
+
+/// A data structure that can be deserialized from a data format.
+pub trait Decode<'de, DEC>: Sized
+where
+  DEC: DEController,
+{
+  /// Performs the conversion.
+  fn decode(aux: &mut DEC::Aux, dw: &mut DEC::DecodeWrapper<'de, '_>) -> Result<Self, DEC::Error>;
+}
+
+impl Decode<'_, ()> for &str {
+  #[inline]
+  fn decode(_: &mut (), _: &mut ()) -> Result<Self, crate::Error> {
+    Ok("")
+  }
+}
+
+impl Decode<'_, ()> for u32 {
+  #[inline]
+  fn decode(_: &mut (), _: &mut ()) -> Result<Self, crate::Error> {
+    Ok(0)
+  }
+}
+
+impl Decode<'_, ()> for u64 {
+  #[inline]
+  fn decode(_: &mut (), _: &mut ()) -> Result<Self, crate::Error> {
+    Ok(0)
+  }
+}
+
+/// Decode sequence
+pub trait DecodeSeq<'de, DEC>: Decode<'de, DEC>
+where
+  DEC: DEController,
+{
+  /// Decodes a sequence of itself into a buffer
+  fn decode_seq(
+    aux: &mut DEC::Aux,
+    buffer: &mut Vector<Self>,
+    dw: &mut DEC::DecodeWrapper<'de, '_>,
+  ) -> Result<(), DEC::Error>;
+}
+
+impl DecodeSeq<'_, ()> for &str {
+  #[inline]
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut ()) -> crate::Result<()> {
+    Ok(())
+  }
+}
+
+impl DecodeSeq<'_, ()> for u32 {
+  #[inline]
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut ()) -> crate::Result<()> {
+    Ok(())
+  }
+}
+
+impl DecodeSeq<'_, ()> for u64 {
+  #[inline]
+  fn decode_seq(_: &mut (), _: &mut Vector<Self>, _: &mut ()) -> crate::Result<()> {
+    Ok(())
+  }
+}
diff --git a/wtx/src/misc/decontroller.rs b/wtx/src/misc/decontroller.rs
new file mode 100644
index 00000000..5742b20f
--- /dev/null
+++ b/wtx/src/misc/decontroller.rs
@@ -0,0 +1,62 @@
+use crate::misc::Lease;
+
+/// Decode/Encode Controller
+pub trait DEController {
+  /// Auxiliary structure
+  type Aux;
+  /// Decode wrapper
+  type DecodeWrapper<'inner, 'outer>: Lease<[u8]>
+  where
+    'inner: 'outer;
+  /// Error
+  type Error: From<crate::Error>;
+  /// Encode wrapper
+  type EncodeWrapper<'inner, 'outer>: Lease<[u8]>
+  where
+    'inner: 'outer;
+}
+
+impl DEController for () {
+  type Aux = ();
+  type DecodeWrapper<'inner, 'outer>
+    = ()
+  where
+    'inner: 'outer;
+  type Error = crate::Error;
+  type EncodeWrapper<'inner, 'outer>
+    = ()
+  where
+    'inner: 'outer;
+}
+
+impl<T> DEController for &T
+where
+  T: DEController,
+{
+  type Aux = T::Aux;
+  type DecodeWrapper<'inner, 'outer>
+    = T::DecodeWrapper<'inner, 'outer>
+  where
+    'inner: 'outer;
+  type Error = T::Error;
+  type EncodeWrapper<'inner, 'outer>
+    = T::EncodeWrapper<'inner, 'outer>
+  where
+    'inner: 'outer;
+}
+
+impl<T> DEController for &mut T
+where
+  T: DEController,
+{
+  type Aux = T::Aux;
+  type DecodeWrapper<'inner, 'outer>
+    = T::DecodeWrapper<'inner, 'outer>
+  where
+    'inner: 'outer;
+  type Error = T::Error;
+  type EncodeWrapper<'inner, 'outer>
+    = T::EncodeWrapper<'inner, 'outer>
+  where
+    'inner: 'outer;
+}
diff --git a/wtx/src/misc/deque.rs b/wtx/src/misc/deque.rs
index d6d34e52..c16211df 100644
--- a/wtx/src/misc/deque.rs
+++ b/wtx/src/misc/deque.rs
@@ -797,11 +797,7 @@ unsafe fn drop_elements<T>(len: usize, offset: usize, ptr: *mut T) {
 /// ```
 #[inline]
 fn is_wrapping(head: usize, len: usize, tail: usize) -> bool {
-  if tail > head {
-    false
-  } else {
-    len > 0
-  }
+  if tail > head { false } else { len > 0 }
 }
 
 /// Allocates `additional` capacity for the contiguous insertion of back or front elements. This
diff --git a/wtx/src/misc/encode.rs b/wtx/src/misc/encode.rs
new file mode 100644
index 00000000..38c360f4
--- /dev/null
+++ b/wtx/src/misc/encode.rs
@@ -0,0 +1,123 @@
+use crate::misc::{DEController, Either};
+
+/// Encodes itself into a data format.
+pub trait Encode<DEC>
+where
+  DEC: DEController,
+{
+  /// Performs the conversion.
+  fn encode(
+    &self,
+    aux: &mut DEC::Aux,
+    ew: &mut DEC::EncodeWrapper<'_, '_>,
+  ) -> Result<(), DEC::Error>;
+
+  /// If this instance can be desired nullable.
+  #[inline]
+  fn is_null(&self) -> bool {
+    false
+  }
+}
+
+impl Encode<()> for u32 {
+  #[inline]
+  fn encode(&self, _: &mut (), _: &mut ()) -> Result<(), crate::Error> {
+    Ok(())
+  }
+}
+
+impl Encode<()> for &str {
+  #[inline]
+  fn encode(&self, _: &mut (), _: &mut ()) -> Result<(), crate::Error> {
+    Ok(())
+  }
+}
+
+impl<DEC, T> Encode<DEC> for &T
+where
+  DEC: DEController,
+  T: Encode<DEC>,
+{
+  #[inline]
+  fn encode(
+    &self,
+    aux: &mut DEC::Aux,
+    ew: &mut DEC::EncodeWrapper<'_, '_>,
+  ) -> Result<(), DEC::Error> {
+    (**self).encode(aux, ew)
+  }
+
+  #[inline]
+  fn is_null(&self) -> bool {
+    (**self).is_null()
+  }
+}
+
+impl<DEC, L, R> Encode<DEC> for Either<L, R>
+where
+  DEC: DEController,
+  L: Encode<DEC>,
+  R: Encode<DEC>,
+{
+  #[inline]
+  fn encode(
+    &self,
+    aux: &mut DEC::Aux,
+    ew: &mut DEC::EncodeWrapper<'_, '_>,
+  ) -> Result<(), DEC::Error> {
+    match self {
+      Self::Left(left) => left.encode(aux, ew),
+      Self::Right(right) => right.encode(aux, ew),
+    }
+  }
+
+  #[inline]
+  fn is_null(&self) -> bool {
+    match self {
+      Self::Left(left) => left.is_null(),
+      Self::Right(right) => right.is_null(),
+    }
+  }
+}
+
+impl<DEC> Encode<DEC> for &dyn Encode<DEC>
+where
+  DEC: DEController,
+{
+  #[inline]
+  fn encode(
+    &self,
+    aux: &mut DEC::Aux,
+    ew: &mut DEC::EncodeWrapper<'_, '_>,
+  ) -> Result<(), DEC::Error> {
+    (**self).encode(aux, ew)
+  }
+
+  #[inline]
+  fn is_null(&self) -> bool {
+    (**self).is_null()
+  }
+}
+
+impl<DEC, T> Encode<DEC> for Option<T>
+where
+  DEC: DEController,
+  T: Encode<DEC>,
+{
+  #[inline]
+  fn encode(
+    &self,
+    aux: &mut DEC::Aux,
+    ew: &mut DEC::EncodeWrapper<'_, '_>,
+  ) -> Result<(), DEC::Error> {
+    match self {
+      None => Ok(()),
+      Some(elem) => elem.encode(aux, ew),
+    }
+  }
+
+  #[inline]
+  fn is_null(&self) -> bool {
+    self.is_none()
+  }
+}
diff --git a/wtx/src/misc/filled_buffer.rs b/wtx/src/misc/filled_buffer.rs
index c95e3879..263c71ce 100644
--- a/wtx/src/misc/filled_buffer.rs
+++ b/wtx/src/misc/filled_buffer.rs
@@ -1,4 +1,4 @@
-use crate::misc::{BufferMode, Vector};
+use crate::misc::{BufferMode, Lease, LeaseMut, Vector};
 use core::{
   fmt::Debug,
   ops::{Deref, DerefMut},
@@ -7,19 +7,19 @@ use core::{
 
 /// A buffer that is always filled with initialized bytes.
 #[derive(Debug, Default)]
-pub(crate) struct FilledBuffer {
+pub struct FilledBuffer {
   data: Vector<u8>,
 }
 
 impl FilledBuffer {
   #[inline]
-  pub(crate) fn _from_vector(vector: Vector<u8>) -> Self {
-    let mut this = Self { data: vector };
-    // SAFETY: Zero input is always safe.
+  pub(crate) fn _from_vector(mut vector: Vector<u8>) -> Self {
+    let prev_init = vector.len();
+    // SAFETY: Elements up to `len` are always initialized
     unsafe {
-      this._fill_remaining_capacity(0);
+      _fill_remaining_capacity(&mut vector, prev_init);
     }
-    this
+    Self { data: vector }
   }
 
   #[inline]
@@ -91,22 +91,22 @@ impl FilledBuffer {
     I: IntoIterator<Item = &'iter [u8]>,
     I::IntoIter: Clone,
   {
-    let prev_cap = self.data.capacity();
+    let prev_init = self.data.capacity();
     let len = self.data.extend_from_copyable_slices(others)?;
-    // SAFETY: memory have been allocated
+    // SAFETY: Inner elements up to `capacity` are always initialized
     unsafe {
-      self._fill_remaining_capacity(prev_cap);
+      _fill_remaining_capacity(&mut self.data, prev_init);
     }
     Ok(len)
   }
 
   #[inline(always)]
   pub(crate) fn _reserve(&mut self, additional: usize) -> crate::Result<()> {
-    let prev_cap = self.data.capacity();
+    let prev_init = self.data.capacity();
     self.data.reserve(additional)?;
-    // SAFETY: memory have been allocated
+    // SAFETY: Inner elements up to `capacity` are always initialized
     unsafe {
-      self._fill_remaining_capacity(prev_cap);
+      _fill_remaining_capacity(&mut self.data, prev_init);
     }
     Ok(())
   }
@@ -124,17 +124,8 @@ impl FilledBuffer {
   }
 
   #[inline]
-  unsafe fn _fill_remaining_capacity(&mut self, prev_cap: usize) {
-    let count = self.data.len().max(prev_cap);
-    let Some(diff @ 1..=usize::MAX) = self.data.capacity().checked_sub(count) else {
-      return;
-    };
-    // SAFETY: caller must ensure `prev_cap` elements
-    let ptr = unsafe { self.data.as_ptr_mut().add(count) };
-    // SAFETY: caller must ensure allocated memory
-    unsafe {
-      slice::from_raw_parts_mut(ptr, diff).fill(0);
-    }
+  pub(crate) fn _vector_mut(&mut self) -> FilledBufferVectorMut<'_> {
+    FilledBufferVectorMut { prev_init: self.data.capacity(), vector: &mut self.data }
   }
 }
 
@@ -164,12 +155,7 @@ impl From<FilledBuffer> for Vector<u8> {
 impl From<Vector<u8>> for FilledBuffer {
   #[inline]
   fn from(from: Vector<u8>) -> Self {
-    let mut this = Self { data: from };
-    // SAFETY: Zero input is always safe.
-    unsafe {
-      this._fill_remaining_capacity(0);
-    }
-    this
+    Self::_from_vector(from)
   }
 }
 
@@ -186,6 +172,51 @@ impl std::io::Write for FilledBuffer {
   }
 }
 
+/// A wrapper that allows the direct usage of [Vector].
+#[derive(Debug)]
+pub struct FilledBufferVectorMut<'fb> {
+  prev_init: usize,
+  vector: &'fb mut Vector<u8>,
+}
+
+impl Lease<Vector<u8>> for FilledBufferVectorMut<'_> {
+  #[inline]
+  fn lease(&self) -> &Vector<u8> {
+    self.vector
+  }
+}
+
+impl LeaseMut<Vector<u8>> for FilledBufferVectorMut<'_> {
+  #[inline]
+  fn lease_mut(&mut self) -> &mut Vector<u8> {
+    self.vector
+  }
+}
+
+impl Drop for FilledBufferVectorMut<'_> {
+  #[inline]
+  fn drop(&mut self) {
+    // SAFETY: Inner elements up to `capacity` are always initialized
+    unsafe {
+      _fill_remaining_capacity(self.vector, self.prev_init);
+    }
+  }
+}
+
+#[inline]
+unsafe fn _fill_remaining_capacity(data: &mut Vector<u8>, prev_init: usize) {
+  let count = data.len().max(prev_init);
+  let Some(diff @ 1..=usize::MAX) = data.capacity().checked_sub(count) else {
+    return;
+  };
+  // SAFETY: caller must ensure `prev_init` elements
+  let ptr = unsafe { data.as_ptr_mut().add(count) };
+  // SAFETY: caller must ensure allocated memory
+  unsafe {
+    slice::from_raw_parts_mut(ptr, diff).fill(0);
+  }
+}
+
 #[cfg(kani)]
 mod kani {
   use crate::misc::filled_buffer::FilledBuffer;
@@ -206,7 +237,7 @@ mod kani {
 
 #[cfg(test)]
 mod tests {
-  use crate::misc::filled_buffer::FilledBuffer;
+  use crate::misc::FilledBuffer;
 
   #[test]
   fn extend_from_slices_with_increasing_cap() {
diff --git a/wtx/src/misc/from_radix_10.rs b/wtx/src/misc/from_radix_10.rs
index dd5a1a8c..75b52df5 100644
--- a/wtx/src/misc/from_radix_10.rs
+++ b/wtx/src/misc/from_radix_10.rs
@@ -155,7 +155,7 @@ where
     return Err(FromRadix10Error::VeryLargeBytesLen.into());
   }
   let mut rslt = Wrapping(zero);
-  for byte in bytes.iter().copied().take(max_positive_digits.into()) {
+  for byte in bytes.iter().copied() {
     let digit = cb(byte)?;
     rslt = rslt.mul(Wrapping(ten));
     rslt = rslt.add(Wrapping(digit));
diff --git a/wtx/src/misc/generic_time.rs b/wtx/src/misc/generic_time.rs
index 450e8d31..03d98dd7 100644
--- a/wtx/src/misc/generic_time.rs
+++ b/wtx/src/misc/generic_time.rs
@@ -104,15 +104,3 @@ impl GenericTime {
     return Err(crate::Error::GenericTimeNeedsBackend);
   }
 }
-
-/// Provides the current time
-#[derive(Debug)]
-pub struct GenericTimeProvider;
-
-#[cfg(feature = "rustls")]
-impl rustls::time_provider::TimeProvider for GenericTimeProvider {
-  #[inline]
-  fn current_time(&self) -> Option<rustls_pki_types::UnixTime> {
-    Some(rustls_pki_types::UnixTime::since_unix_epoch(GenericTime::timestamp().ok()?))
-  }
-}
diff --git a/wtx/src/misc/optimization.rs b/wtx/src/misc/optimization.rs
index a2dae00a..ed14c35c 100644
--- a/wtx/src/misc/optimization.rs
+++ b/wtx/src/misc/optimization.rs
@@ -2,6 +2,15 @@
 
 use crate::misc::{BasicUtf8Error, ExtUtf8Error, IncompleteUtf8Char, Lease, StdUtf8Error};
 
+/// Internally uses `memchr` if the feature is active.
+#[inline]
+pub fn bytes_pos_any(bytes: &[u8], elem: &[u8]) -> Option<usize> {
+  #[cfg(feature = "memchr")]
+  return memchr::memmem::find_iter(bytes, elem).next();
+  #[cfg(not(feature = "memchr"))]
+  return bytes.windows(elem.len()).enumerate().find(|(_, w)| *w == elem).map(|(idx, _)| idx);
+}
+
 /// Internally uses `memchr` if the feature is active.
 #[inline]
 pub fn bytes_pos1<B>(bytes: B, elem: u8) -> Option<usize>
@@ -65,6 +74,16 @@ pub fn bytes_split_once1(bytes: &[u8], elem: u8) -> Option<(&[u8], &[u8])> {
   Some((bytes.get(..idx)?, bytes.get(idx.wrapping_add(1)..)?))
 }
 
+/// Internally uses `memchr` if the feature is active.
+#[inline]
+pub fn bytes_split_once_any<'bytes>(
+  bytes: &'bytes [u8],
+  elem: &[u8],
+) -> Option<(&'bytes [u8], &'bytes [u8])> {
+  let idx = bytes_pos_any(bytes, elem)?;
+  Some((bytes.get(..idx)?, bytes.get(idx.wrapping_add(elem.len())..)?))
+}
+
 /// Internally uses `simdutf8` if the feature is active.
 #[inline]
 pub fn from_utf8_basic(bytes: &[u8]) -> Result<&str, BasicUtf8Error> {
diff --git a/wtx/src/misc/partitioned_filled_buffer.rs b/wtx/src/misc/partitioned_filled_buffer.rs
index 7e280735..f3d94e45 100644
--- a/wtx/src/misc/partitioned_filled_buffer.rs
+++ b/wtx/src/misc/partitioned_filled_buffer.rs
@@ -1,4 +1,4 @@
-use crate::misc::{filled_buffer::FilledBuffer, FilledBufferWriter, Lease, LeaseMut};
+use crate::misc::{FilledBuffer, Lease, LeaseMut, SuffixWriter, suffix_writer::SuffixWriterFbvm};
 use core::ops::Range;
 
 // ```
@@ -14,7 +14,7 @@ use core::ops::Range;
 //                |           |             |            |
 //                |           |             |            |--> _buffer.capacity()
 //                |           |             |
-//                |           |             |---------------> _buffer.len()
+//                |           |             |---------------> _following_end_idx (_buffer.len())
 //                |           |
 //                |           |-----------------------------> _current_end_idx
 //                |
@@ -162,6 +162,11 @@ impl PartitionedFilledBuffer {
     Ok(())
   }
 
+  #[inline]
+  pub(crate) fn _suffix_writer(&mut self) -> SuffixWriterFbvm<'_> {
+    SuffixWriter::_new(self._following_end_idx(), self._buffer._vector_mut())
+  }
+
   #[inline]
   fn _indcs_from_lengths(
     antecedent_len: usize,
@@ -194,10 +199,3 @@ impl Default for PartitionedFilledBuffer {
     Self::new()
   }
 }
-
-impl<'pfb> From<&'pfb mut PartitionedFilledBuffer> for FilledBufferWriter<'pfb> {
-  #[inline]
-  fn from(from: &'pfb mut PartitionedFilledBuffer) -> Self {
-    FilledBufferWriter::new(from._following_end_idx(), &mut from._buffer)
-  }
-}
diff --git a/wtx/src/http/percent_encoding.rs b/wtx/src/misc/percent_encoding.rs
similarity index 93%
rename from wtx/src/http/percent_encoding.rs
rename to wtx/src/misc/percent_encoding.rs
index 15f9162c..0310a98b 100644
--- a/wtx/src/http/percent_encoding.rs
+++ b/wtx/src/misc/percent_encoding.rs
@@ -36,7 +36,7 @@ impl AsciiSet {
     Self { mask }
   }
 
-  /// Adds a character from the set.
+  /// Removes a character from the set.
   #[inline]
   #[must_use]
   pub fn remove(self, byte: u8) -> Self {
@@ -68,13 +68,13 @@ impl AsciiSet {
 #[derive(Clone, Copy, Debug)]
 pub struct PercentEncode<'bytes> {
   bytes: &'bytes [u8],
-  ascii_set: &'static AsciiSet,
+  ascii_set: AsciiSet,
 }
 
 impl<'bytes> PercentEncode<'bytes> {
-  /// New instance.
+  /// New instance that will use `ascii_set` to guide which elements should be encoded.
   #[inline]
-  pub const fn new(bytes: &'bytes [u8], ascii_set: &'static AsciiSet) -> Self {
+  pub const fn new(bytes: &'bytes [u8], ascii_set: AsciiSet) -> Self {
     Self { bytes, ascii_set }
   }
 }
@@ -104,11 +104,7 @@ impl<'bytes> Iterator for PercentEncode<'bytes> {
 
   #[inline]
   fn size_hint(&self) -> (usize, Option<usize>) {
-    if self.bytes.is_empty() {
-      (0, Some(0))
-    } else {
-      (1, Some(self.bytes.len()))
-    }
+    if self.bytes.is_empty() { (0, Some(0)) } else { (1, Some(self.bytes.len())) }
   }
 }
 
@@ -199,10 +195,7 @@ fn percent_encode_str(byte: u8) -> &'static str {
 
 #[cfg(test)]
 mod tests {
-  use crate::{
-    http::{AsciiSet, PercentDecode, PercentEncode},
-    misc::Vector,
-  };
+  use crate::misc::{AsciiSet, PercentDecode, PercentEncode, Vector};
 
   #[test]
   fn decode() {
@@ -216,7 +209,7 @@ mod tests {
   #[test]
   fn encode() {
     let mut buffer = Vector::new();
-    for elem in PercentEncode::new(b"hello world?", &AsciiSet::NON_ALPHANUMERIC) {
+    for elem in PercentEncode::new(b"hello world?", AsciiSet::NON_ALPHANUMERIC) {
       buffer.extend_from_copyable_slice(elem).unwrap();
     }
     assert_eq!(buffer.as_ref(), b"hello%20world%3F");
diff --git a/wtx/src/misc/query_writer.rs b/wtx/src/misc/query_writer.rs
index 580e20b9..38efa06d 100644
--- a/wtx/src/misc/query_writer.rs
+++ b/wtx/src/misc/query_writer.rs
@@ -37,10 +37,6 @@ where
     T: Display,
     U: Lease<Option<T>>,
   {
-    if let Some(value) = opt.lease() {
-      self.write(param, value)
-    } else {
-      Ok(self)
-    }
+    if let Some(value) = opt.lease() { self.write(param, value) } else { Ok(self) }
   }
 }
diff --git a/wtx/src/misc/rng.rs b/wtx/src/misc/rng.rs
index d4bf9ba9..bee7298a 100644
--- a/wtx/src/misc/rng.rs
+++ b/wtx/src/misc/rng.rs
@@ -1,51 +1,23 @@
 //! Random Number Generators
 
+mod crypto_rng;
 #[cfg(feature = "fastrand")]
 mod fastrand;
+mod from_rng;
 #[cfg(feature = "rand_chacha")]
 mod rand_chacha;
 mod seed;
 mod xorshift;
 
-use crate::misc::Usize;
 use core::{
   cell::Cell,
   ops::{Bound, RangeBounds},
 };
+pub use crypto_rng::CryptoRng;
+pub use from_rng::FromRng;
 pub use seed::*;
 pub use xorshift::*;
 
-/// Allows the creation of random instances.
-pub trait FromRng<RNG>
-where
-  RNG: Rng,
-{
-  /// Creates a new instance based on `rng`.
-  fn from_rng(rng: &mut RNG) -> Self;
-}
-
-impl<RNG> FromRng<RNG> for u8
-where
-  RNG: Rng,
-{
-  #[inline]
-  fn from_rng(rng: &mut RNG) -> Self {
-    rng.u8()
-  }
-}
-
-impl<RNG> FromRng<RNG> for usize
-where
-  RNG: Rng,
-{
-  #[inline]
-  fn from_rng(rng: &mut RNG) -> Self {
-    Usize::from_u64(u64::from_be_bytes(rng.u8_8()))
-      .unwrap_or_else(|| Usize::from_u32(u32::from_be_bytes(rng.u8_4())))
-      .into_usize()
-  }
-}
-
 /// Abstraction tailored for the needs of this project. Each implementation should manage how
 /// seeds are retrieved as well as how numbers are generated.
 pub trait Rng
diff --git a/wtx/src/misc/rng/crypto_rng.rs b/wtx/src/misc/rng/crypto_rng.rs
new file mode 100644
index 00000000..c9fbf523
--- /dev/null
+++ b/wtx/src/misc/rng/crypto_rng.rs
@@ -0,0 +1,11 @@
+use crate::misc::Rng;
+
+/// Marker trait used to indicate that an [`Rng`] implementation is supposed to be
+/// cryptographically secure.
+#[cfg(feature = "rand-compat")]
+pub trait CryptoRng: rand_core::CryptoRng + Rng {}
+
+/// Marker trait used to indicate that an [`Rng`] implementation is supposed to be
+/// cryptographically secure.
+#[cfg(not(feature = "rand-compat"))]
+pub trait CryptoRng: Rng {}
diff --git a/wtx/src/misc/rng/from_rng.rs b/wtx/src/misc/rng/from_rng.rs
new file mode 100644
index 00000000..5f66cc2d
--- /dev/null
+++ b/wtx/src/misc/rng/from_rng.rs
@@ -0,0 +1,32 @@
+use crate::misc::{Rng, Usize};
+
+/// Allows the creation of random instances.
+pub trait FromRng<RNG>
+where
+  RNG: Rng,
+{
+  /// Creates a new instance based on `rng`.
+  fn from_rng(rng: &mut RNG) -> Self;
+}
+
+impl<RNG> FromRng<RNG> for u8
+where
+  RNG: Rng,
+{
+  #[inline]
+  fn from_rng(rng: &mut RNG) -> Self {
+    rng.u8()
+  }
+}
+
+impl<RNG> FromRng<RNG> for usize
+where
+  RNG: Rng,
+{
+  #[inline]
+  fn from_rng(rng: &mut RNG) -> Self {
+    Usize::from_u64(u64::from_be_bytes(rng.u8_8()))
+      .unwrap_or_else(|| Usize::from_u32(u32::from_be_bytes(rng.u8_4())))
+      .into_usize()
+  }
+}
diff --git a/wtx/src/misc/rng/rand_chacha.rs b/wtx/src/misc/rng/rand_chacha.rs
index 0f0eaf2b..98c399eb 100644
--- a/wtx/src/misc/rng/rand_chacha.rs
+++ b/wtx/src/misc/rng/rand_chacha.rs
@@ -2,7 +2,9 @@ use rand_chacha::rand_core::RngCore;
 
 macro_rules! implement {
   ($struct:ty) => {
-    impl crate::misc::rng::Rng for $struct {
+    impl crate::misc::CryptoRng for $struct {}
+
+    impl crate::misc::Rng for $struct {
       #[inline]
       fn u8(&mut self) -> u8 {
         let [a, ..] = self.next_u32().to_be_bytes();
diff --git a/wtx/src/misc/rng/seed.rs b/wtx/src/misc/rng/seed.rs
index f6b080cc..da0fb87f 100644
--- a/wtx/src/misc/rng/seed.rs
+++ b/wtx/src/misc/rng/seed.rs
@@ -1,4 +1,4 @@
-use crate::misc::{facades::atomic_u64::AtomicU64, Usize};
+use crate::misc::{Usize, facades::atomic_u64::AtomicU64};
 use alloc::boxed::Box;
 use core::{panic::Location, ptr, sync::atomic::Ordering};
 
diff --git a/wtx/src/misc/rng/xorshift.rs b/wtx/src/misc/rng/xorshift.rs
index 9374492d..b0b1e263 100644
--- a/wtx/src/misc/rng/xorshift.rs
+++ b/wtx/src/misc/rng/xorshift.rs
@@ -1,4 +1,4 @@
-use crate::misc::{facades::atomic_u64::AtomicU64, Lease, LeaseMut, Rng};
+use crate::misc::{Lease, LeaseMut, Rng, facades::atomic_u64::AtomicU64};
 use core::sync::atomic::Ordering;
 
 /// Xorshift that deals with 64 bits numbers.
diff --git a/wtx/src/misc/role.rs b/wtx/src/misc/role.rs
index 85229ef0..81001f70 100644
--- a/wtx/src/misc/role.rs
+++ b/wtx/src/misc/role.rs
@@ -11,11 +11,7 @@ impl Role {
   /// Instance shortcut.
   #[inline]
   pub fn from_is_client(is_client: bool) -> Self {
-    if is_client {
-      Self::Client
-    } else {
-      Self::Server
-    }
+    if is_client { Self::Client } else { Self::Server }
   }
 }
 
diff --git a/wtx/src/misc/stream.rs b/wtx/src/misc/stream.rs
index 7e475817..f19bfad3 100644
--- a/wtx/src/misc/stream.rs
+++ b/wtx/src/misc/stream.rs
@@ -31,8 +31,6 @@ macro_rules! _local_write_all_vectored {
 mod bytes_stream;
 #[cfg(feature = "embassy-net")]
 mod embassy_net;
-#[cfg(feature = "embedded-tls")]
-mod embedded_tls;
 #[cfg(feature = "std")]
 mod std;
 mod stream_reader;
diff --git a/wtx/src/misc/stream/embedded_tls.rs b/wtx/src/misc/stream/embedded_tls.rs
deleted file mode 100644
index b5244cc4..00000000
--- a/wtx/src/misc/stream/embedded_tls.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use crate::misc::{StreamReader, StreamWithTls, StreamWriter};
-use embedded_io_async::{Read, Write};
-use embedded_tls::{TlsCipherSuite, TlsConnection};
-
-impl<'any, S, C> StreamReader for TlsConnection<'any, S, C>
-where
-  C: TlsCipherSuite + 'static,
-  S: Read + Write + 'any,
-{
-  #[inline]
-  async fn read(&mut self, bytes: &mut [u8]) -> crate::Result<usize> {
-    Ok(<Self as Read>::read(self, bytes).await?)
-  }
-}
-
-impl<'any, S, C> StreamWriter for TlsConnection<'any, S, C>
-where
-  C: TlsCipherSuite + 'static,
-  S: Read + Write + 'any,
-{
-  #[inline]
-  async fn write_all(&mut self, bytes: &[u8]) -> crate::Result<()> {
-    <Self as Write>::write_all(self, bytes).await?;
-    self.flush().await?;
-    Ok(())
-  }
-
-  #[inline]
-  async fn write_all_vectored(&mut self, bytes: &[&[u8]]) -> crate::Result<()> {
-    for elem in bytes {
-      <Self as StreamWriter>::write_all(self, elem).await?;
-    }
-    Ok(())
-  }
-}
-
-impl<'any, S, C> StreamWithTls for TlsConnection<'any, S, C>
-where
-  C: TlsCipherSuite + 'static,
-  S: Read + Write + 'any,
-{
-  type TlsServerEndPoint = [u8; 0];
-
-  #[inline]
-  fn tls_server_end_point(&self) -> crate::Result<Option<Self::TlsServerEndPoint>> {
-    Ok(None)
-  }
-}
diff --git a/wtx/src/misc/stream/tokio.rs b/wtx/src/misc/stream/tokio.rs
index cbd5138b..aa268e47 100644
--- a/wtx/src/misc/stream/tokio.rs
+++ b/wtx/src/misc/stream/tokio.rs
@@ -2,8 +2,8 @@ use crate::misc::{StreamReader, StreamWriter};
 use tokio::{
   io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadHalf, WriteHalf},
   net::{
-    tcp::{OwnedReadHalf, OwnedWriteHalf},
     TcpStream,
+    tcp::{OwnedReadHalf, OwnedWriteHalf},
   },
 };
 
diff --git a/wtx/src/misc/filled_buffer_writer.rs b/wtx/src/misc/suffix_writer.rs
similarity index 56%
rename from wtx/src/misc/filled_buffer_writer.rs
rename to wtx/src/misc/suffix_writer.rs
index db0295b7..195a94a8 100644
--- a/wtx/src/misc/filled_buffer_writer.rs
+++ b/wtx/src/misc/suffix_writer.rs
@@ -1,16 +1,27 @@
-use crate::misc::{filled_buffer::FilledBuffer, BufferMode, Lease, LeaseMut};
+use crate::misc::{BufferMode, FilledBufferVectorMut, Lease, LeaseMut, Vector};
 
-/// Helper that manages the copy of initialized bytes.
+/// Helper that appends data into a [`FilledBufferVectorMut`].
+pub type SuffixWriterFbvm<'fb> = SuffixWriter<FilledBufferVectorMut<'fb>>;
+/// Helper that appends data into a mutable vector.
+pub type SuffixWriterMut<'vec> = SuffixWriter<&'vec mut Vector<u8>>;
+
+/// Helper that appends data
 #[derive(Debug)]
-pub struct FilledBufferWriter<'vec> {
+pub struct SuffixWriter<V>
+where
+  V: LeaseMut<Vector<u8>>,
+{
   _curr_idx: usize,
   _initial_idx: usize,
-  _vec: &'vec mut FilledBuffer,
+  _vec: V,
 }
 
-impl<'vec> FilledBufferWriter<'vec> {
+impl<V> SuffixWriter<V>
+where
+  V: LeaseMut<Vector<u8>>,
+{
   #[inline]
-  pub(crate) fn new(start: usize, vec: &'vec mut FilledBuffer) -> Self {
+  pub(crate) fn _new(start: usize, vec: V) -> Self {
     Self { _curr_idx: start, _initial_idx: start, _vec: vec }
   }
 
@@ -21,14 +32,28 @@ impl<'vec> FilledBufferWriter<'vec> {
     self._extend_from_slices([other])
   }
 
+  #[inline]
+  pub(crate) fn _create_buffer(
+    &mut self,
+    n: usize,
+    cb: impl FnOnce(&mut [u8]) -> crate::Result<usize>,
+  ) -> crate::Result<()> {
+    let prev_len = self._vec.lease().len();
+    self._vec.lease_mut().expand(BufferMode::Additional(n), 0)?;
+    let written = cb(self._vec.lease_mut().get_mut(self._curr_idx..).unwrap_or_default())?;
+    self._curr_idx = self._curr_idx.wrapping_add(written);
+    self._vec.lease_mut().truncate(prev_len.wrapping_add(written));
+    Ok(())
+  }
+
   #[inline]
   pub(crate) fn _curr_bytes(&self) -> &[u8] {
-    self._vec.get(self._initial_idx..self._curr_idx).unwrap_or_default()
+    self._vec.lease().get(self._initial_idx..self._curr_idx).unwrap_or_default()
   }
 
   #[inline]
   pub(crate) fn _curr_bytes_mut(&mut self) -> &mut [u8] {
-    self._vec.get_mut(self._initial_idx..self._curr_idx).unwrap_or_default()
+    self._vec.lease_mut().get_mut(self._initial_idx..self._curr_idx).unwrap_or_default()
   }
 
   #[inline]
@@ -47,7 +72,7 @@ impl<'vec> FilledBufferWriter<'vec> {
     I: IntoIterator<Item = &'iter [u8]>,
     I::IntoIter: Clone,
   {
-    let sum = self._vec._extend_from_slices(slices)?;
+    let sum = self._vec.lease_mut().extend_from_copyable_slices(slices)?;
     self._curr_idx = self._curr_idx.wrapping_add(sum);
     Ok(())
   }
@@ -75,44 +100,53 @@ impl<'vec> FilledBufferWriter<'vec> {
   pub(crate) fn _extend_from_slices_group_rn(&mut self, slices: &[&[u8]]) -> crate::Result<()> {
     self._extend_from_slices(slices.iter().copied().chain(["\r\n".as_bytes()]))
   }
+}
 
+impl<V> Lease<SuffixWriter<V>> for SuffixWriter<V>
+where
+  V: LeaseMut<Vector<u8>>,
+{
   #[inline]
-  pub(crate) fn _remaining_bytes_mut(&mut self) -> &mut [u8] {
-    self._vec._all_mut().get_mut(self._curr_idx..).unwrap_or_default()
-  }
-
-  #[inline]
-  pub(crate) fn _shift_idx(&mut self, n: usize) -> crate::Result<()> {
-    let new_len = self._curr_idx.wrapping_add(n);
-    self._vec._expand(BufferMode::Len(new_len))?;
-    self._curr_idx = new_len;
-    Ok(())
+  fn lease(&self) -> &SuffixWriter<V> {
+    self
   }
 }
 
-impl<'vec> Lease<FilledBufferWriter<'vec>> for FilledBufferWriter<'vec> {
+impl<V> Lease<[u8]> for SuffixWriter<V>
+where
+  V: LeaseMut<Vector<u8>>,
+{
   #[inline]
-  fn lease(&self) -> &FilledBufferWriter<'vec> {
-    self
+  fn lease(&self) -> &[u8] {
+    self._vec.lease()
   }
 }
 
-impl<'vec> LeaseMut<FilledBufferWriter<'vec>> for FilledBufferWriter<'vec> {
+impl<V> LeaseMut<SuffixWriter<V>> for SuffixWriter<V>
+where
+  V: LeaseMut<Vector<u8>>,
+{
   #[inline]
-  fn lease_mut(&mut self) -> &mut FilledBufferWriter<'vec> {
+  fn lease_mut(&mut self) -> &mut SuffixWriter<V> {
     self
   }
 }
 
-impl Drop for FilledBufferWriter<'_> {
+impl<V> Drop for SuffixWriter<V>
+where
+  V: LeaseMut<Vector<u8>>,
+{
   #[inline]
   fn drop(&mut self) {
-    self._vec._truncate(self._initial_idx);
+    self._vec.lease_mut().truncate(self._initial_idx);
   }
 }
 
 #[cfg(feature = "std")]
-impl std::io::Write for FilledBufferWriter<'_> {
+impl<V> std::io::Write for SuffixWriter<V>
+where
+  V: LeaseMut<Vector<u8>>,
+{
   #[inline]
   fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
     self.extend_from_slice(buf).map_err(std::io::Error::other)?;
@@ -121,6 +155,6 @@ impl std::io::Write for FilledBufferWriter<'_> {
 
   #[inline]
   fn flush(&mut self) -> std::io::Result<()> {
-    self._vec.flush()
+    self._vec.lease_mut().flush()
   }
 }
diff --git a/wtx/src/misc/sync/atomic_cell.rs b/wtx/src/misc/sync/atomic_cell.rs
index 60ab7a9d..aae4569e 100644
--- a/wtx/src/misc/sync/atomic_cell.rs
+++ b/wtx/src/misc/sync/atomic_cell.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::as_conversions, reason = "address is only used as an heuristic to retrieve locks")]
 
-use crate::misc::{sync::seq_lock::SeqLock, CachePadded};
+use crate::misc::{CachePadded, sync::seq_lock::SeqLock};
 use core::{
   cell::UnsafeCell,
   fmt::{Debug, Formatter},
diff --git a/wtx/src/misc/sync/seq_lock.rs b/wtx/src/misc/sync/seq_lock.rs
index 50766d61..558afc9b 100644
--- a/wtx/src/misc/sync/seq_lock.rs
+++ b/wtx/src/misc/sync/seq_lock.rs
@@ -1,7 +1,7 @@
-use crate::misc::{facades::atomic_usize::AtomicUsize, Backoff};
+use crate::misc::{Backoff, facades::atomic_usize::AtomicUsize};
 use core::{
   mem,
-  sync::atomic::{fence, Ordering},
+  sync::atomic::{Ordering, fence},
 };
 
 pub(crate) struct SeqLock {
@@ -17,11 +17,7 @@ impl SeqLock {
   #[inline]
   pub(crate) fn optimistic_read(&self) -> Option<usize> {
     let state = self.state.load(Ordering::Acquire);
-    if state == 1 {
-      None
-    } else {
-      Some(state)
-    }
+    if state == 1 { None } else { Some(state) }
   }
 
   /// Returns `true` if the current stamp is equal to `stamp`.
diff --git a/wtx/src/misc/tokio_rustls.rs b/wtx/src/misc/tokio_rustls.rs
index 8413501c..d967e2fb 100644
--- a/wtx/src/misc/tokio_rustls.rs
+++ b/wtx/src/misc/tokio_rustls.rs
@@ -2,12 +2,12 @@ use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
 use rustls_pki_types::ServerName;
 use tokio::io::{AsyncRead, AsyncWrite};
 use tokio_rustls::{
+  TlsAcceptor, TlsConnector,
   client::TlsStream,
   rustls::{
-    client::WantsClientCert, server::WantsServerCert, ClientConfig, ConfigBuilder, RootCertStore,
-    ServerConfig,
+    ClientConfig, ConfigBuilder, RootCertStore, ServerConfig, client::WantsClientCert,
+    server::WantsServerCert,
   },
-  TlsAcceptor, TlsConnector,
 };
 
 /// TLS client using `tokio-rustls` and associated crates.
diff --git a/wtx/src/misc/tuple_impls.rs b/wtx/src/misc/tuple_impls.rs
index 00d34afa..20326da9 100644
--- a/wtx/src/misc/tuple_impls.rs
+++ b/wtx/src/misc/tuple_impls.rs
@@ -4,28 +4,29 @@ macro_rules! impl_tuples {
   ($( [$($T:ident($N:tt))*] )+) => {
     #[cfg(feature = "database")]
     mod database {
-      use crate::database::{Database, Encode, RecordValues, record_values::encode};
+      use crate::database::{Database, RecordValues, record_values::encode};
+      use crate::misc::Encode;
 
       $(
         impl<DB, $($T,)*> RecordValues<DB> for ($( $T, )*)
         where
-          DB: Database,
+          DB: Database<Aux = ()>,
           $($T: Encode<DB>,)*
         {
           #[inline]
           fn encode_values<'buffer, 'tmp, AUX>(
-            &mut self,
+            &self,
             _aux: &mut AUX,
-            _ev: &mut DB::EncodeValue<'buffer, 'tmp>,
-            mut _prefix_cb: impl FnMut(&mut AUX, &mut DB::EncodeValue<'buffer, 'tmp>) -> usize,
-            mut _suffix_cb: impl FnMut(&mut AUX, &mut DB::EncodeValue<'buffer, 'tmp>, bool, usize) -> usize,
+            _ew: &mut DB::EncodeWrapper<'buffer, 'tmp>,
+            mut _prefix_cb: impl FnMut(&mut AUX, &mut DB::EncodeWrapper<'buffer, 'tmp>) -> usize,
+            mut _suffix_cb: impl FnMut(&mut AUX, &mut DB::EncodeWrapper<'buffer, 'tmp>, bool, usize) -> usize,
           ) -> Result<usize, DB::Error> {
             let mut _n: usize = 0;
             $(
               encode(
                 _aux,
                 &self.$N,
-                _ev,
+                _ew,
                 &mut _n,
                 &mut _prefix_cb,
                 &mut _suffix_cb
@@ -34,6 +35,13 @@ macro_rules! impl_tuples {
             Ok(_n)
           }
 
+          #[allow(unused_mut, reason = "0-arity tuple")]
+          #[inline]
+          fn is_null(&self, mut _cb: impl FnMut(bool) -> Result<(), DB::Error>) -> Result<(), DB::Error> {
+            $( _cb(self.$N.is_null())?; )*
+            Ok(())
+          }
+
           #[inline]
           fn len(&self) -> usize {
             const { 0 $(+ { const $T: usize = 1; $T })* }
@@ -257,9 +265,11 @@ macro_rules! impl_tuples {
 
     #[cfg(feature = "postgres")]
     mod postgres {
-      use crate::database::{
-        Decode, Encode, Typed,
-        client::postgres::{DecodeValue, EncodeValue, Postgres, StructDecoder, StructEncoder}
+      use crate::{
+        database::{
+          Typed, client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, StructDecoder, StructEncoder},
+        },
+        misc::{Decode, Encode}
       };
 
       $(
@@ -269,8 +279,8 @@ macro_rules! impl_tuples {
           ERR: From<crate::Error>,
         {
           #[inline]
-          fn decode(dv: &DecodeValue<'de>) -> Result<Self, ERR> {
-            let mut _sd = StructDecoder::<ERR>::new(dv);
+          fn decode(_: &mut (), dw: &mut DecodeWrapper<'de>) -> Result<Self, ERR> {
+            let mut _sd = StructDecoder::<ERR>::new(dw);
             Ok((
               $( _sd.decode::<$T>()?, )*
             ))
@@ -283,8 +293,8 @@ macro_rules! impl_tuples {
           ERR: From<crate::Error>,
         {
           #[inline]
-          fn encode(&self, _ev: &mut EncodeValue<'_, '_>) -> Result<(), ERR> {
-            let mut _ev = StructEncoder::<ERR>::new(_ev)?;
+          fn encode(&self, _: &mut (), _ew: &mut EncodeWrapper<'_, '_>) -> Result<(), ERR> {
+            let mut _ev = StructEncoder::<ERR>::new(_ew)?;
             $(
               _ev = _ev.encode(&self.$N)?;
             )*
diff --git a/wtx/src/misc/uri.rs b/wtx/src/misc/uri.rs
index d6d76171..895df535 100644
--- a/wtx/src/misc/uri.rs
+++ b/wtx/src/misc/uri.rs
@@ -1,6 +1,6 @@
 use crate::misc::{
-  ArrayString, FromRadix10 as _, Lease, QueryWriter, _unlikely_dflt, bytes_pos1, bytes_rpos1,
-  str_split_once1,
+  _unlikely_dflt, ArrayString, FromRadix10 as _, Lease, LeaseMut, QueryWriter, bytes_pos1,
+  bytes_rpos1, str_split_once1,
 };
 use alloc::string::String;
 use core::fmt::{Arguments, Debug, Display, Formatter, Write as _};
@@ -88,11 +88,7 @@ where
   #[inline]
   pub fn host(&self) -> &str {
     let authority = self.authority();
-    if let Some(elem) = str_split_once1(authority, b'@') {
-      elem.1
-    } else {
-      authority
-    }
+    if let Some(elem) = str_split_once1(authority, b'@') { elem.1 } else { authority }
   }
 
   /// <https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2>
@@ -139,11 +135,7 @@ where
   /// ```
   #[inline]
   pub fn password(&self) -> &str {
-    if let Some(elem) = str_split_once1(self.userinfo(), b':') {
-      elem.1
-    } else {
-      ""
-    }
+    if let Some(elem) = str_split_once1(self.userinfo(), b':') { elem.1 } else { "" }
   }
 
   /// <https://datatracker.ietf.org/doc/html/rfc3986#section-3.3>
@@ -206,11 +198,7 @@ where
   #[inline]
   pub fn relative_reference_slash(&self) -> &str {
     let relative_reference = self.relative_reference();
-    if relative_reference.is_empty() {
-      "/"
-    } else {
-      relative_reference
-    }
+    if relative_reference.is_empty() { "/" } else { relative_reference }
   }
 
   /// <https://datatracker.ietf.org/doc/html/rfc3986#section-3.1>
@@ -260,11 +248,7 @@ where
   /// ```
   #[inline]
   pub fn user(&self) -> &str {
-    if let Some(elem) = str_split_once1(self.userinfo(), b':') {
-      elem.0
-    } else {
-      ""
-    }
+    if let Some(elem) = str_split_once1(self.userinfo(), b':') { elem.0 } else { "" }
   }
 
   /// ```rust
@@ -273,11 +257,7 @@ where
   /// ```
   #[inline]
   pub fn userinfo(&self) -> &str {
-    if let Some(elem) = str_split_once1(self.authority(), b'@') {
-      elem.0
-    } else {
-      ""
-    }
+    if let Some(elem) = str_split_once1(self.authority(), b'@') { elem.0 } else { "" }
   }
 
   fn parts(uri: &str) -> (u16, u8, u8, u16) {
@@ -314,6 +294,7 @@ where
     self.port = match uri {
       [b'h', b't', b't', b'p', b's', ..] | [b'w', b's', b's', ..] => Some(443),
       [b'h', b't', b't', b'p', ..] | [b'w', b's', ..] => Some(80),
+      [b'm', b'y', b's', b'q', b'l', ..] => Some(3306),
       [b'p', b'o', b's', b't', b'g', b'r', b'e', b's', b'q', b'l', ..]
       | [b'p', b'o', b's', b't', b'g', b'r', b'e', b's', ..] => Some(5432),
       _ => return,
@@ -375,6 +356,32 @@ impl UriString {
     self.uri.truncate(self.initial_len.into());
     self.query_start = self.query_start.min(self.initial_len);
   }
+
+  #[inline]
+  pub(crate) fn _buffer(
+    &mut self,
+    cb: impl FnOnce(&mut String) -> crate::Result<()>,
+  ) -> crate::Result<()> {
+    let idx = self.uri.len();
+    let rslt = cb(&mut self.uri);
+    self.uri.truncate(idx);
+    rslt?;
+    Ok(())
+  }
+}
+
+impl<S> Lease<Uri<S>> for Uri<S> {
+  #[inline]
+  fn lease(&self) -> &Uri<S> {
+    self
+  }
+}
+
+impl<S> LeaseMut<Uri<S>> for Uri<S> {
+  #[inline]
+  fn lease_mut(&mut self) -> &mut Uri<S> {
+    self
+  }
 }
 
 impl<S> Debug for Uri<S>
diff --git a/wtx/src/misc/usize.rs b/wtx/src/misc/usize.rs
index b6b42063..be994802 100644
--- a/wtx/src/misc/usize.rs
+++ b/wtx/src/misc/usize.rs
@@ -117,3 +117,21 @@ impl From<Usize> for u128 {
     from.0 as u128
   }
 }
+
+impl TryFrom<u64> for Usize {
+  type Error = crate::Error;
+
+  #[inline]
+  fn try_from(from: u64) -> Result<Self, Self::Error> {
+    Self::from_u64(from).ok_or(crate::Error::UsizeConversionOverflow)
+  }
+}
+
+impl TryFrom<Usize> for u32 {
+  type Error = crate::Error;
+
+  #[inline]
+  fn try_from(from: Usize) -> Result<Self, Self::Error> {
+    from.into_u32().ok_or(crate::Error::UsizeConversionOverflow)
+  }
+}
diff --git a/wtx/src/misc/vector.rs b/wtx/src/misc/vector.rs
index 1d6746e1..2eb26639 100644
--- a/wtx/src/misc/vector.rs
+++ b/wtx/src/misc/vector.rs
@@ -1,4 +1,4 @@
-use crate::misc::{BufferMode, Lease, LeaseMut, Wrapper, _unlikely_elem};
+use crate::misc::{_unlikely_elem, BufferMode, Lease, LeaseMut, Wrapper};
 use alloc::vec::{Drain, IntoIter, Vec};
 use core::{
   borrow::{Borrow, BorrowMut},
@@ -6,7 +6,8 @@ use core::{
   fmt::{Debug, Display, Formatter},
   hint::assert_unchecked,
   ops::{Deref, DerefMut, RangeBounds},
-  ptr, slice,
+  ptr,
+  slice::{self, Iter, IterMut},
 };
 
 /// Errors of [Vector].
@@ -642,7 +643,7 @@ impl<T> FromIterator<T> for Wrapper<crate::Result<Vector<T>>> {
   where
     I: IntoIterator<Item = T>,
   {
-    Wrapper(Vector::from_iter(iter).map_err(crate::Error::into))
+    Wrapper(Vector::from_iter(iter))
   }
 }
 
@@ -658,6 +659,26 @@ impl<T> IntoIterator for Vector<T> {
   }
 }
 
+impl<'any, T> IntoIterator for &'any Vector<T> {
+  type Item = &'any T;
+  type IntoIter = Iter<'any, T>;
+
+  #[inline]
+  fn into_iter(self) -> Self::IntoIter {
+    self.data.iter()
+  }
+}
+
+impl<'any, T> IntoIterator for &'any mut Vector<T> {
+  type Item = &'any mut T;
+  type IntoIter = IterMut<'any, T>;
+
+  #[inline]
+  fn into_iter(self) -> Self::IntoIter {
+    self.data.iter_mut()
+  }
+}
+
 impl<T> PartialEq for Vector<T>
 where
   T: PartialEq,
diff --git a/wtx/src/misc/wrapper.rs b/wtx/src/misc/wrapper.rs
index 0eedd24e..eb32453b 100644
--- a/wtx/src/misc/wrapper.rs
+++ b/wtx/src/misc/wrapper.rs
@@ -14,17 +14,17 @@ impl<T> Lease<T> for Wrapper<T> {
   }
 }
 
-impl<T> LeaseMut<T> for Wrapper<T> {
+impl<T> Lease<Wrapper<T>> for Wrapper<T> {
   #[inline]
-  fn lease_mut(&mut self) -> &mut T {
-    &mut self.0
+  fn lease(&self) -> &Wrapper<T> {
+    self
   }
 }
 
-impl<T> Lease<Wrapper<T>> for Wrapper<T> {
+impl<T> LeaseMut<T> for Wrapper<T> {
   #[inline]
-  fn lease(&self) -> &Wrapper<T> {
-    self
+  fn lease_mut(&mut self) -> &mut T {
+    &mut self.0
   }
 }
 
@@ -34,3 +34,25 @@ impl<T> LeaseMut<Wrapper<T>> for Wrapper<T> {
     self
   }
 }
+
+#[cfg(feature = "serde")]
+mod serde {
+  use crate::misc::{Wrapper, serde_collect_seq_rslt};
+  use core::fmt::Display;
+  use serde::{Serialize, Serializer};
+
+  impl<ELEM, ERR, T> Serialize for Wrapper<T>
+  where
+    ERR: Display,
+    T: Clone + Iterator<Item = Result<ELEM, ERR>>,
+    ELEM: Serialize,
+  {
+    #[inline]
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+      S: Serializer,
+    {
+      serde_collect_seq_rslt(serializer, self.0.clone())
+    }
+  }
+}
diff --git a/wtx/src/pool/resource_manager.rs b/wtx/src/pool/resource_manager.rs
index e643e27a..287c776d 100644
--- a/wtx/src/pool/resource_manager.rs
+++ b/wtx/src/pool/resource_manager.rs
@@ -121,10 +121,10 @@ pub(crate) mod database {
   mod tokio {
     use crate::{
       database::{
-        client::postgres::{Executor, ExecutorBuffer},
-        Executor as _, DEFAULT_MAX_STMTS,
+        DEFAULT_MAX_STMTS, Executor as _,
+        client::postgres::{ExecutorBuffer, PostgresExecutor},
       },
-      misc::{simple_seed, Xorshift64Sync},
+      misc::{Xorshift64Sync, simple_seed},
       pool::{PostgresRM, ResourceManager},
     };
     use alloc::string::String;
@@ -153,13 +153,13 @@ pub(crate) mod database {
       type CreateAux = ();
       type Error = E;
       type RecycleAux = ();
-      type Resource = Executor<E, ExecutorBuffer, TcpStream>;
+      type Resource = PostgresExecutor<E, ExecutorBuffer, TcpStream>;
 
       #[inline]
       async fn create(&self, _: &Self::CreateAux) -> Result<Self::Resource, Self::Error> {
         let mut rng = &self._rng;
         _executor!(&self._uri, |config, uri| {
-          Executor::connect(
+          PostgresExecutor::connect(
             &config,
             ExecutorBuffer::new(self._max_stmts, &mut rng),
             &mut rng,
@@ -183,7 +183,7 @@ pub(crate) mod database {
         let mut buffer = ExecutorBuffer::new(self._max_stmts, &mut rng);
         mem::swap(&mut buffer, &mut resource.eb);
         *resource = _executor!(&self._uri, |config, uri| {
-          Executor::connect(
+          PostgresExecutor::connect(
             &config,
             buffer,
             &mut rng,
@@ -199,10 +199,10 @@ pub(crate) mod database {
   mod tokio_rustls {
     use crate::{
       database::{
-        client::postgres::{Executor, ExecutorBuffer},
-        Executor as _, DEFAULT_MAX_STMTS,
+        DEFAULT_MAX_STMTS, Executor as _,
+        client::postgres::{ExecutorBuffer, PostgresExecutor},
       },
-      misc::{simple_seed, TokioRustlsConnector, Xorshift64Sync},
+      misc::{TokioRustlsConnector, Xorshift64Sync, simple_seed},
       pool::{PostgresRM, ResourceManager},
     };
     use alloc::string::String;
@@ -232,13 +232,13 @@ pub(crate) mod database {
       type CreateAux = ();
       type Error = E;
       type RecycleAux = ();
-      type Resource = Executor<E, ExecutorBuffer, TlsStream<TcpStream>>;
+      type Resource = PostgresExecutor<E, ExecutorBuffer, TlsStream<TcpStream>>;
 
       #[inline]
       async fn create(&self, _: &Self::CreateAux) -> Result<Self::Resource, Self::Error> {
         let mut rng = &self._rng;
         _executor!(&self._uri, |config, uri| {
-          Executor::connect_encrypted(
+          PostgresExecutor::connect_encrypted(
             &config,
             ExecutorBuffer::new(self._max_stmts, &mut rng),
             &mut rng,
@@ -269,7 +269,7 @@ pub(crate) mod database {
         let mut buffer = ExecutorBuffer::new(self._max_stmts, &mut rng);
         mem::swap(&mut buffer, &mut resource.eb);
         *resource = _executor!(&self._uri, |config, uri| {
-          Executor::connect_encrypted(
+          PostgresExecutor::connect_encrypted(
             &config,
             buffer,
             &mut rng,
diff --git a/wtx/src/pool/simple_pool.rs b/wtx/src/pool/simple_pool.rs
index b5851f23..5145bb35 100644
--- a/wtx/src/pool/simple_pool.rs
+++ b/wtx/src/pool/simple_pool.rs
@@ -4,7 +4,7 @@ use crate::{
 };
 use alloc::vec::Vec;
 use core::{
-  future::{poll_fn, Future},
+  future::{Future, poll_fn},
   ops::{Deref, DerefMut},
   task::{Poll, Waker},
 };
@@ -258,7 +258,7 @@ mod _tokio {
 
 #[cfg(all(feature = "_async-tests", test))]
 mod tests {
-  use crate::pool::{simple_pool::SimplePoolTokio, SimpleRM};
+  use crate::pool::{SimpleRM, simple_pool::SimplePoolTokio};
 
   #[tokio::test]
   async fn held_lock_is_not_modified() {
diff --git a/wtx/src/web_socket.rs b/wtx/src/web_socket.rs
index 5c59d005..c31ff72a 100644
--- a/wtx/src/web_socket.rs
+++ b/wtx/src/web_socket.rs
@@ -24,6 +24,7 @@ pub(crate) mod web_socket_reader;
 pub(crate) mod web_socket_writer;
 
 use crate::{
+  _MAX_PAYLOAD_LEN,
   misc::{ConnectionState, LeaseMut, Lock, Stream, Xorshift64},
   web_socket::{
     compression::NegotiatedCompression,
@@ -31,7 +32,6 @@ use crate::{
       WebSocketCommonPart, WebSocketReaderPart, WebSocketWriterPart,
     },
   },
-  _MAX_PAYLOAD_LEN,
 };
 pub use close_code::CloseCode;
 pub use compression::{Compression, CompressionLevel, DeflateConfig};
diff --git a/wtx/src/web_socket/compression.rs b/wtx/src/web_socket/compression.rs
index 94ce60ae..26948ce3 100644
--- a/wtx/src/web_socket/compression.rs
+++ b/wtx/src/web_socket/compression.rs
@@ -8,7 +8,7 @@ mod window_bits;
 
 #[cfg(feature = "flate2")]
 pub use self::flate2::{Flate2, NegotiatedFlate2};
-use crate::{http::GenericHeader, misc::FilledBufferWriter};
+use crate::{http::GenericHeader, misc::SuffixWriterFbvm};
 pub use compression_level::CompressionLevel;
 pub use deflate_config::DeflateConfig;
 pub use window_bits::WindowBits;
@@ -26,7 +26,7 @@ pub trait Compression<const IS_CLIENT: bool> {
   ) -> crate::Result<Self::NegotiatedCompression>;
 
   /// Writes headers bytes that will be sent to the server.
-  fn write_req_headers(&self, fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()>;
+  fn write_req_headers(&self, sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()>;
 }
 
 impl<const IS_CLIENT: bool> Compression<IS_CLIENT> for () {
@@ -41,7 +41,7 @@ impl<const IS_CLIENT: bool> Compression<IS_CLIENT> for () {
   }
 
   #[inline]
-  fn write_req_headers(&self, _: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
+  fn write_req_headers(&self, _: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
     Ok(())
   }
 }
@@ -73,7 +73,7 @@ pub trait NegotiatedCompression {
   fn rsv1(&self) -> u8;
 
   /// Write response headers
-  fn write_res_headers(&self, fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()>;
+  fn write_res_headers(&self, sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()>;
 }
 
 impl<T> NegotiatedCompression for &mut T
@@ -110,8 +110,8 @@ where
   }
 
   #[inline]
-  fn write_res_headers(&self, fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
-    (**self).write_res_headers(fbw)
+  fn write_res_headers(&self, sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
+    (**self).write_res_headers(sw)
   }
 }
 
@@ -146,7 +146,7 @@ impl NegotiatedCompression for () {
   }
 
   #[inline]
-  fn write_res_headers(&self, _: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
+  fn write_res_headers(&self, _: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
     Ok(())
   }
 }
@@ -194,10 +194,10 @@ where
   }
 
   #[inline]
-  fn write_res_headers(&self, fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
+  fn write_res_headers(&self, sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
     match self {
-      Some(el) => el.write_res_headers(fbw),
-      None => ().write_res_headers(fbw),
+      Some(el) => el.write_res_headers(sw),
+      None => ().write_res_headers(sw),
     }
   }
 }
diff --git a/wtx/src/web_socket/compression/flate2.rs b/wtx/src/web_socket/compression/flate2.rs
index 95e33c32..1637a195 100644
--- a/wtx/src/web_socket/compression/flate2.rs
+++ b/wtx/src/web_socket/compression/flate2.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{GenericHeader, KnownHeaderName},
-  misc::{bytes_split1, FilledBufferWriter, FromRadix10},
-  web_socket::{compression::NegotiatedCompression, Compression, DeflateConfig, WebSocketError},
+  misc::{FromRadix10, SuffixWriterFbvm, bytes_split1},
+  web_socket::{Compression, DeflateConfig, WebSocketError, compression::NegotiatedCompression},
 };
 use flate2::{Compress, Decompress, FlushCompress, FlushDecompress};
 
@@ -93,8 +93,8 @@ impl<const IS_CLIENT: bool> Compression<IS_CLIENT> for Flate2 {
   }
 
   #[inline]
-  fn write_req_headers(&self, fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
-    write_headers(&self.dc, fbw)
+  fn write_req_headers(&self, sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
+    write_headers(&self.dc, sw)
   }
 }
 
@@ -170,8 +170,8 @@ impl NegotiatedCompression for NegotiatedFlate2 {
   }
 
   #[inline]
-  fn write_res_headers(&self, fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
-    write_headers(&self.dc, fbw)
+  fn write_res_headers(&self, sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
+    write_headers(&self.dc, sw)
   }
 }
 
@@ -241,8 +241,8 @@ fn _manage_header_uniqueness(
 }
 
 #[inline]
-fn write_headers(dc: &DeflateConfig, fbw: &mut FilledBufferWriter<'_>) -> crate::Result<()> {
-  fbw._extend_from_slices_group_rn(&[
+fn write_headers(dc: &DeflateConfig, sw: &mut SuffixWriterFbvm<'_>) -> crate::Result<()> {
+  sw._extend_from_slices_group_rn(&[
     b"Sec-Websocket-Extensions: ",
     b"permessage-deflate; ",
     b"client_max_window_bits=",
diff --git a/wtx/src/web_socket/frame.rs b/wtx/src/web_socket/frame.rs
index 70c8020a..a0a1ff18 100644
--- a/wtx/src/web_socket/frame.rs
+++ b/wtx/src/web_socket/frame.rs
@@ -1,8 +1,8 @@
 use crate::{
   misc::{Lease, Vector},
   web_socket::{
+    MASK_MASK, MAX_CONTROL_PAYLOAD_LEN, MAX_HEADER_LEN_USIZE, OpCode,
     misc::{fill_header_from_params, has_masked_frame},
-    OpCode, MASK_MASK, MAX_CONTROL_PAYLOAD_LEN, MAX_HEADER_LEN_USIZE,
   },
 };
 use core::str;
diff --git a/wtx/src/web_socket/handshake.rs b/wtx/src/web_socket/handshake.rs
index f8392b70..ac23a284 100644
--- a/wtx/src/web_socket/handshake.rs
+++ b/wtx/src/web_socket/handshake.rs
@@ -19,14 +19,14 @@ macro_rules! check_headers {
 
 use crate::{
   http::{GenericHeader as _, GenericRequest as _, HttpError, KnownHeaderName, Method},
-  misc::{bytes_split1, FilledBufferWriter, LeaseMut, Rng, Stream, UriRef},
+  misc::{LeaseMut, Rng, Stream, SuffixWriterFbvm, UriRef, bytes_split1},
   web_socket::{
-    compression::NegotiatedCompression, Compression, WebSocket, WebSocketAcceptor, WebSocketBuffer,
-    WebSocketConnector, WebSocketError,
+    Compression, WebSocket, WebSocketAcceptor, WebSocketBuffer, WebSocketConnector, WebSocketError,
+    compression::NegotiatedCompression,
   },
 };
-use base64::{engine::general_purpose::STANDARD, Engine};
-use httparse::{Header, Request, Response, Status, EMPTY_HEADER};
+use base64::{Engine, engine::general_purpose::STANDARD};
+use httparse::{EMPTY_HEADER, Header, Request, Response, Status};
 use sha1::{Digest, Sha1};
 
 const MAX_READ_HEADER_LEN: usize = 64;
@@ -93,9 +93,9 @@ where
           res.code = Some(101);
           res.version = Some(req.version().into());
           {
-            let mut fbw = nb.into();
-            build_res(&mut fbw, res.headers, &nc, self.no_masking)?;
-            stream.write_all(fbw._curr_bytes()).await?;
+            let mut sw = nb._suffix_writer();
+            build_res(&mut sw, res.headers, &nc, self.no_masking)?;
+            stream.write_all(sw._curr_bytes()).await?;
           }
           nb._clear();
           return Ok(WebSocket::new(nc, self.no_masking, self.rng, stream, self.wsb)?);
@@ -130,17 +130,17 @@ where
       let nb = &mut self.wsb.lease_mut().network_buffer;
       nb._reserve(MAX_READ_LEN)?;
       {
-        let fbw = &mut nb.into();
+        let mut sw = nb._suffix_writer();
         let key = build_req(
           &self.compression,
-          fbw,
+          &mut sw,
           self.headers,
           key_buffer,
           self.no_masking,
           &mut self.rng,
           uri,
         )?;
-        stream.write_all(fbw._curr_bytes()).await?;
+        stream.write_all(sw._curr_bytes()).await?;
         key
       }
     };
@@ -193,7 +193,7 @@ fn base64_from_array<'output, const I: usize, const O: usize>(
 #[inline]
 fn build_req<'headers, 'kb, C>(
   compression: &C,
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
   headers: impl IntoIterator<Item = (&'headers [u8], &'headers [u8])>,
   key_buffer: &'kb mut [u8; 26],
   no_masking: bool,
@@ -204,36 +204,36 @@ where
   C: Compression<true>,
 {
   let key = gen_key(key_buffer, rng);
-  fbw._extend_from_slices_group_rn(&[
+  sw._extend_from_slices_group_rn(&[
     b"GET ",
     uri.relative_reference_slash().as_bytes(),
     b" HTTP/1.1",
   ])?;
   for (name, value) in headers {
-    fbw._extend_from_slices_group_rn(&[name, b": ", value])?;
+    sw._extend_from_slices_group_rn(&[name, b": ", value])?;
   }
-  fbw._extend_from_slice_rn(b"Connection: Upgrade")?;
+  sw._extend_from_slice_rn(b"Connection: Upgrade")?;
   match uri.port() {
     Some(80 | 443) => {
-      fbw._extend_from_slices_group_rn(&[b"Host: ", uri.hostname().as_bytes()])?;
+      sw._extend_from_slices_group_rn(&[b"Host: ", uri.hostname().as_bytes()])?;
     }
-    _ => fbw._extend_from_slices_group_rn(&[b"Host: ", uri.host().as_bytes()])?,
+    _ => sw._extend_from_slices_group_rn(&[b"Host: ", uri.host().as_bytes()])?,
   }
-  fbw._extend_from_slices_group_rn(&[b"Sec-WebSocket-Key: ", key])?;
+  sw._extend_from_slices_group_rn(&[b"Sec-WebSocket-Key: ", key])?;
   if no_masking {
-    fbw._extend_from_slice_rn(b"Sec-WebSocket-Extensions: no-masking")?;
+    sw._extend_from_slice_rn(b"Sec-WebSocket-Extensions: no-masking")?;
   }
-  fbw._extend_from_slice_rn(b"Sec-WebSocket-Version: 13")?;
-  fbw._extend_from_slice_rn(b"Upgrade: websocket")?;
-  compression.write_req_headers(fbw)?;
-  fbw._extend_from_slice_rn(b"")?;
+  sw._extend_from_slice_rn(b"Sec-WebSocket-Version: 13")?;
+  sw._extend_from_slice_rn(b"Upgrade: websocket")?;
+  compression.write_req_headers(sw)?;
+  sw._extend_from_slice_rn(b"")?;
   Ok(key)
 }
 
 /// Server response
 #[inline]
 fn build_res<NC>(
-  fbw: &mut FilledBufferWriter<'_>,
+  sw: &mut SuffixWriterFbvm<'_>,
   headers: &[Header<'_>],
   nc: &NC,
   no_masking: bool,
@@ -241,19 +241,19 @@ fn build_res<NC>(
 where
   NC: NegotiatedCompression,
 {
-  fbw._extend_from_slice_rn(b"HTTP/1.1 101 Switching Protocols")?;
+  sw._extend_from_slice_rn(b"HTTP/1.1 101 Switching Protocols")?;
   for header in headers {
-    fbw._extend_from_slices_group_rn(&[header.name(), b": ", header.value()])?;
+    sw._extend_from_slices_group_rn(&[header.name(), b": ", header.value()])?;
   }
   if no_masking {
-    fbw._extend_from_slices_group_rn(&[
+    sw._extend_from_slices_group_rn(&[
       KnownHeaderName::SecWebsocketExtensions.into(),
       b": ",
       NO_MASKING.as_bytes(),
     ])?;
   }
-  nc.write_res_headers(fbw)?;
-  fbw._extend_from_slice_rn(b"")?;
+  nc.write_res_headers(sw)?;
+  sw._extend_from_slice_rn(b"")?;
   Ok(())
 }
 
diff --git a/wtx/src/web_socket/misc.rs b/wtx/src/web_socket/misc.rs
index 12599a50..3ab13f32 100644
--- a/wtx/src/web_socket/misc.rs
+++ b/wtx/src/web_socket/misc.rs
@@ -1,4 +1,4 @@
-use crate::web_socket::{CloseCode, OpCode, MASK_MASK, MAX_HEADER_LEN_USIZE, OP_CODE_MASK};
+use crate::web_socket::{CloseCode, MASK_MASK, MAX_HEADER_LEN_USIZE, OP_CODE_MASK, OpCode};
 use core::ops::Range;
 
 /// The first two bytes of `payload` are filled with `code`. Does nothing if `payload` is
diff --git a/wtx/src/web_socket/read_frame_info.rs b/wtx/src/web_socket/read_frame_info.rs
index 44d68fdd..91403118 100644
--- a/wtx/src/web_socket/read_frame_info.rs
+++ b/wtx/src/web_socket/read_frame_info.rs
@@ -1,9 +1,9 @@
 use crate::{
-  misc::{StreamReader, _read_header, partitioned_filled_buffer::PartitionedFilledBuffer},
+  misc::{_read_header, StreamReader, partitioned_filled_buffer::PartitionedFilledBuffer},
   web_socket::{
+    FIN_MASK, MAX_CONTROL_PAYLOAD_LEN, OpCode, PAYLOAD_MASK, RSV1_MASK, RSV2_MASK, RSV3_MASK,
+    WebSocketError,
     misc::{has_masked_frame, op_code},
-    OpCode, WebSocketError, FIN_MASK, MAX_CONTROL_PAYLOAD_LEN, PAYLOAD_MASK, RSV1_MASK, RSV2_MASK,
-    RSV3_MASK,
   },
 };
 
diff --git a/wtx/src/web_socket/web_socket_acceptor.rs b/wtx/src/web_socket/web_socket_acceptor.rs
index f5e43dc8..aff7bee9 100644
--- a/wtx/src/web_socket/web_socket_acceptor.rs
+++ b/wtx/src/web_socket/web_socket_acceptor.rs
@@ -1,5 +1,5 @@
 use crate::{
-  misc::{simple_seed, Xorshift64},
+  misc::{Xorshift64, simple_seed},
   web_socket::WebSocketBuffer,
 };
 use httparse::Request;
diff --git a/wtx/src/web_socket/web_socket_buffer.rs b/wtx/src/web_socket/web_socket_buffer.rs
index 2c808ac5..121e15fc 100644
--- a/wtx/src/web_socket/web_socket_buffer.rs
+++ b/wtx/src/web_socket/web_socket_buffer.rs
@@ -1,4 +1,4 @@
-use crate::misc::{partitioned_filled_buffer::PartitionedFilledBuffer, Lease, LeaseMut, Vector};
+use crate::misc::{Lease, LeaseMut, Vector, partitioned_filled_buffer::PartitionedFilledBuffer};
 
 #[derive(Debug)]
 #[doc = _internal_buffer_doc!()]
diff --git a/wtx/src/web_socket/web_socket_connector.rs b/wtx/src/web_socket/web_socket_connector.rs
index 57f7f204..c4917ff9 100644
--- a/wtx/src/web_socket/web_socket_connector.rs
+++ b/wtx/src/web_socket/web_socket_connector.rs
@@ -1,5 +1,5 @@
 use crate::{
-  misc::{simple_seed, Xorshift64},
+  misc::{Xorshift64, simple_seed},
   web_socket::WebSocketBuffer,
 };
 use core::array::IntoIter;
diff --git a/wtx/src/web_socket/web_socket_parts/web_socket_part.rs b/wtx/src/web_socket/web_socket_parts/web_socket_part.rs
index eb54c227..77310852 100644
--- a/wtx/src/web_socket/web_socket_parts/web_socket_part.rs
+++ b/wtx/src/web_socket/web_socket_parts/web_socket_part.rs
@@ -1,12 +1,11 @@
 use crate::{
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, ConnectionState, LeaseMut, Lock, Stream,
-    StreamReader, StreamWriter, Vector, Xorshift64,
+    ConnectionState, LeaseMut, Lock, Stream, StreamReader, StreamWriter, Vector, Xorshift64,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
   },
   web_socket::{
-    compression::NegotiatedCompression,
-    web_socket_parts::web_socket_part_owned::WebSocketCommonPartOwned, web_socket_writer, Frame,
-    FrameMut,
+    Frame, FrameMut, compression::NegotiatedCompression,
+    web_socket_parts::web_socket_part_owned::WebSocketCommonPartOwned, web_socket_writer,
   },
 };
 
diff --git a/wtx/src/web_socket/web_socket_parts/web_socket_part_mut.rs b/wtx/src/web_socket/web_socket_parts/web_socket_part_mut.rs
index 3a9e8b26..d3173b28 100644
--- a/wtx/src/web_socket/web_socket_parts/web_socket_part_mut.rs
+++ b/wtx/src/web_socket/web_socket_parts/web_socket_part_mut.rs
@@ -1,14 +1,14 @@
 use crate::{
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, ConnectionState, LeaseMut, Stream, Vector,
-    Xorshift64,
+    ConnectionState, LeaseMut, Stream, Vector, Xorshift64,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
   },
   web_socket::{
+    Frame, FrameMut,
     compression::NegotiatedCompression,
     web_socket_parts::web_socket_part::{
       WebSocketCommonPart, WebSocketReaderPart, WebSocketWriterPart,
     },
-    Frame, FrameMut,
   },
 };
 use core::marker::PhantomData;
diff --git a/wtx/src/web_socket/web_socket_parts/web_socket_part_owned.rs b/wtx/src/web_socket/web_socket_parts/web_socket_part_owned.rs
index c341dbab..2ee2503e 100644
--- a/wtx/src/web_socket/web_socket_parts/web_socket_part_owned.rs
+++ b/wtx/src/web_socket/web_socket_parts/web_socket_part_owned.rs
@@ -1,14 +1,14 @@
 use crate::{
   misc::{
-    partitioned_filled_buffer::PartitionedFilledBuffer, ConnectionState, LeaseMut, Lock,
-    StreamReader, StreamWriter, Vector, Xorshift64,
+    ConnectionState, LeaseMut, Lock, StreamReader, StreamWriter, Vector, Xorshift64,
+    partitioned_filled_buffer::PartitionedFilledBuffer,
   },
   web_socket::{
+    Frame, FrameMut,
     compression::NegotiatedCompression,
     web_socket_parts::web_socket_part::{
       WebSocketCommonPart, WebSocketReaderPart, WebSocketWriterPart,
     },
-    Frame, FrameMut,
   },
 };
 use core::marker::PhantomData;
diff --git a/wtx/src/web_socket/web_socket_reader.rs b/wtx/src/web_socket/web_socket_reader.rs
index 7b63c925..4f793fd3 100644
--- a/wtx/src/web_socket/web_socket_reader.rs
+++ b/wtx/src/web_socket/web_socket_reader.rs
@@ -7,14 +7,14 @@
 
 use crate::{
   misc::{
-    BufferMode, CompletionErr, ConnectionState, ExtUtf8Error, FnMutFut, IncompleteUtf8Char,
-    LeaseMut, Rng, StreamReader, StreamWriter, Vector, _read_payload, from_utf8_basic,
+    _read_payload, BufferMode, CompletionErr, ConnectionState, ExtUtf8Error, FnMutFut,
+    IncompleteUtf8Char, LeaseMut, Rng, StreamReader, StreamWriter, Vector, from_utf8_basic,
     from_utf8_ext, partitioned_filled_buffer::PartitionedFilledBuffer,
   },
   web_socket::{
+    CloseCode, Frame, MAX_CONTROL_PAYLOAD_LEN, MAX_HEADER_LEN_USIZE, OpCode, WebSocketError,
     compression::NegotiatedCompression, fill_with_close_code, read_frame_info::ReadFrameInfo,
-    unmask::unmask, web_socket_writer::manage_normal_frame, CloseCode, Frame, OpCode,
-    WebSocketError, MAX_CONTROL_PAYLOAD_LEN, MAX_HEADER_LEN_USIZE,
+    unmask::unmask, web_socket_writer::manage_normal_frame,
   },
 };
 
@@ -274,7 +274,7 @@ pub(crate) fn manage_text_of_first_continuation_frame(
 ) -> crate::Result<Option<IncompleteUtf8Char>> {
   Ok(match from_utf8_ext(payload) {
     Err(ExtUtf8Error::Incomplete { incomplete_ending_char, .. }) => Some(incomplete_ending_char),
-    Err(ExtUtf8Error::Invalid { .. }) => {
+    Err(ExtUtf8Error::Invalid) => {
       return Err(crate::Error::InvalidUTF8);
     }
     Ok(_) => None,
@@ -305,7 +305,7 @@ pub(crate) fn manage_text_of_recurrent_continuation_frames(
     Err(ExtUtf8Error::Incomplete { incomplete_ending_char, .. }) => {
       *iuc = Some(incomplete_ending_char);
     }
-    Err(ExtUtf8Error::Invalid { .. }) => {
+    Err(ExtUtf8Error::Invalid) => {
       return Err(crate::Error::InvalidUTF8);
     }
     Ok(_) => {}
diff --git a/wtx/src/web_socket/web_socket_writer.rs b/wtx/src/web_socket/web_socket_writer.rs
index 4f68eff2..5a4b4d1b 100644
--- a/wtx/src/web_socket/web_socket_writer.rs
+++ b/wtx/src/web_socket/web_socket_writer.rs
@@ -3,8 +3,8 @@
 use crate::{
   misc::{BufferMode, ConnectionState, Lease, LeaseMut, Rng, StreamWriter, Vector, Xorshift64},
   web_socket::{
-    compression::NegotiatedCompression, misc::has_masked_frame, unmask::unmask, Frame, FrameMut,
-    OpCode,
+    Frame, FrameMut, OpCode, compression::NegotiatedCompression, misc::has_masked_frame,
+    unmask::unmask,
   },
 };
 


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 8de35735..90d8edea 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -15,7 +15,7 @@ jobs:
         with:
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: Swatinem/rust-cache@v2
       - run: .scripts/autobahn-fuzzingclient.sh ci
 
@@ -27,7 +27,7 @@ jobs:
         with:
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: Swatinem/rust-cache@v2
       - run: .scripts/autobahn-fuzzingserver.sh ci
 
@@ -39,7 +39,7 @@ jobs:
         with:
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: actions-rs/install@v0.1
         with:
           crate: cargo-fuzz
@@ -54,7 +54,7 @@ jobs:
         with:
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: Swatinem/rust-cache@v2
       - run: .scripts/h2spec.sh high ci
 
@@ -66,25 +66,30 @@ jobs:
         with:
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: Swatinem/rust-cache@v2
       - run: .scripts/h2spec.sh low ci
 
   integration-tests:
     runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        scripts: [
+          "integration-tests",
+          "integration-tests-mysql",
+        ]
     steps:
       - uses: actions/checkout@v4
       - uses: actions-rs/toolchain@v1
         with:
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: Swatinem/rust-cache@v2
       - run: sudo apt install docker-compose -y
       - run: docker-compose -f .test-utils/docker-compose.yml up -d
       - run: sleep 30
-      - run: .scripts/integration-tests.sh
-
+      - run: .scripts/${{ matrix.scripts }}.sh
 
   internal-tests-0:
     runs-on: ubuntu-latest
@@ -99,7 +104,7 @@ jobs:
           components: clippy, rustfmt
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: Swatinem/rust-cache@v2
       - run: .scripts/internal-tests-0.sh
 
@@ -116,6 +121,6 @@ jobs:
           components: clippy, rustfmt
           override: true
           profile: minimal
-          toolchain: nightly-2024-11-22
+          toolchain: nightly-2025-02-23
       - uses: Swatinem/rust-cache@v2
       - run: .scripts/internal-tests-1.sh
diff --git a/.scripts/integration-tests-mysql.sh b/.scripts/integration-tests-mysql.sh
new file mode 100755
index 00000000..94bc3b98
--- /dev/null
+++ b/.scripts/integration-tests-mysql.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+export DATABASE_URI_MYSQL='mysql://wtx:wtx@localhost:3307/wtx'
+
+cargo test --features mysql,_integration-tests --release -- --test-threads=1
+
+export DATABASE_URI_MYSQL='mysql://wtx:wtx@localhost:3308/wtx'
+
+cargo test --features mysql,_integration-tests --release -- --test-threads=1
diff --git a/.scripts/integration-tests.sh b/.scripts/integration-tests.sh
index d7214141..88eba125 100755
--- a/.scripts/integration-tests.sh
+++ b/.scripts/integration-tests.sh
@@ -1,6 +1,7 @@
 #!/usr/bin/env bash
 
-export DATABASE_URI='postgres://wtx_scram:wtx@localhost:5432/wtx'
+export DATABASE_URI_MYSQL='mysql://wtx:wtx@localhost:3306/wtx'
+export DATABASE_URI_POSTGRESQL='postgres://wtx_scram:wtx@localhost:5432/wtx'
 
 cargo test --all-features --release -- --test-threads=1
 
diff --git a/.scripts/internal-tests-0.sh b/.scripts/internal-tests-0.sh
index 4fb972f2..815073fb 100755
--- a/.scripts/internal-tests-0.sh
+++ b/.scripts/internal-tests-0.sh
@@ -3,9 +3,9 @@
 . "$(dirname "$0")/common.sh" --source-only
 
 $rt rustfmt
-$rt clippy -Aclippy::little-endian-bytes,-Aclippy::panic-in-result-fn,-Aclippy::used_underscore_items,-Aclippy::arbitrary_source_item_ordering
+$rt clippy -Aclippy::arbitrary_source_item_ordering,-Aclippy::doc-include-without-cfg,-Aclippy::little-endian-bytes,-Aclippy::panic-in-result-fn,-Aclippy::used_underscore_items
 
-cargo miri test --features http2,postgres,web-socket -p wtx two_sta
+#cargo miri test --features http2,postgres,web-socket -p wtx
 
 # WTX
 
@@ -38,6 +38,7 @@ $rt test-with-features wtx http2
 $rt test-with-features wtx httparse
 $rt test-with-features wtx matchit
 $rt test-with-features wtx memchr
+$rt test-with-features wtx mysql
 $rt test-with-features wtx pool
 $rt test-with-features wtx postgres
 $rt test-with-features wtx quick-protobuf
diff --git a/.scripts/internal-tests-1.sh b/.scripts/internal-tests-1.sh
index f52c629d..368aa4e7 100755
--- a/.scripts/internal-tests-1.sh
+++ b/.scripts/internal-tests-1.sh
@@ -6,7 +6,7 @@ cargo check --all-features --all-targets
 
 # WTX Docs
 
-rustup default nightly-2024-11-22
+rustup default nightly-2025-02-23
 cargo clean --target-dir mdbook-target
 cargo build --all-features --target-dir mdbook-target
 mdbook test -L mdbook-target/debug/deps wtx-docs
diff --git a/.test-utils/docker-compose.yml b/.test-utils/docker-compose.yml
index b92e3c80..c1946395 100644
--- a/.test-utils/docker-compose.yml
+++ b/.test-utils/docker-compose.yml
@@ -1,6 +1,41 @@
 version: "3"
 
 services:
+    # MySQL
+
+    mariadb_11:
+        environment:
+            MYSQL_DATABASE: wtx
+            MYSQL_PASSWORD: wtx
+            MYSQL_ROOT_PASSWORD: wtx
+            MYSQL_USER: wtx
+        image: mariadb:11
+        ports:
+            - 3306:3306
+
+    mysql_9:
+        environment:
+            MYSQL_DATABASE: wtx
+            MYSQL_PASSWORD: wtx
+            MYSQL_ROOT_HOST: '%'
+            MYSQL_ROOT_PASSWORD: wtx
+            MYSQL_USER: wtx
+        image: mysql:9
+        ports:
+            - 3307:3306
+
+    percona_9:
+        environment:
+            MYSQL_DATABASE: wtx
+            MYSQL_PASSWORD: wtx
+            MYSQL_ROOT_PASSWORD: wtx
+            MYSQL_USER: wtx
+        image: percona:8
+        ports:
+            - 3308:3306
+
+    # PostgreSQL
+
     postgres_scram:
         environment:
             POSTGRES_DB: wtx
@@ -9,4 +44,4 @@ services:
         ports:
             - 5432:5432
         volumes:
-            - ./../.test-utils/postgres.sh:/docker-entrypoint-initdb.d/setup.sh
\ No newline at end of file
+            - ./../.test-utils/postgres.sh:/docker-entrypoint-initdb.d/setup.sh
diff --git a/wtx-macros/tests/ui/pass/custom_transport.rs b/wtx-macros/tests/ui/pass/custom_transport.rs
index f0dfb795..4dda7545 100644
--- a/wtx-macros/tests/ui/pass/custom_transport.rs
+++ b/wtx-macros/tests/ui/pass/custom_transport.rs
@@ -26,8 +26,18 @@ impl RecievingTransport<CustomTransportParams> for CustomTransport {
 }
 
 impl SendingTransport<CustomTransportParams> for CustomTransport {
-  #[inline]
-  async fn send<A, DRSR, P>(
+  async fn send_bytes<A>(
+    &mut self,
+    _: &[u8],
+    _: &mut PkgsAux<A, (), CustomTransportParams>,
+  ) -> Result<(), A::Error>
+  where
+    A: Api
+  {
+    Ok(())
+  }
+
+  async fn send_pkg<A, DRSR, P>(
     &mut self,
     _: &mut P,
     _: &mut PkgsAux<A, DRSR, CustomTransportParams>,
@@ -45,26 +55,18 @@ impl Transport<CustomTransportParams> for CustomTransport {
   type Inner = Self;
 }
 
-struct CustomTransportParams(());
+struct CustomTransportParams((), ());
 
 impl TransportParams for CustomTransportParams {
   type ExternalRequestParams = ();
   type ExternalResponseParams = ();
 
-  fn ext_req_params(&self) -> &Self::ExternalRequestParams {
-    &self.0
-  }
-
-  fn ext_req_params_mut(&mut self) -> &mut Self::ExternalRequestParams {
-    &mut self.0
-  }
-
-  fn ext_res_params(&self) -> &Self::ExternalResponseParams {
-    &self.0
+  fn ext_params(&self) -> (&Self::ExternalRequestParams, &Self::ExternalResponseParams) {
+    (&self.0, &self.1)
   }
 
-  fn ext_res_params_mut(&mut self) -> &mut Self::ExternalResponseParams {
-    &mut self.0
+  fn ext_params_mut(&mut self) -> (&mut Self::ExternalRequestParams, &mut Self::ExternalResponseParams) {
+    (&mut self.0, &mut self.1)
   }
 
   fn reset(&mut self) {}
diff --git a/wtx-macros/tests/ui/pass/mutable_references.rs b/wtx-macros/tests/ui/pass/mutable_references.rs
index 8f6ea113..08aedcfe 100644
--- a/wtx-macros/tests/ui/pass/mutable_references.rs
+++ b/wtx-macros/tests/ui/pass/mutable_references.rs
@@ -26,9 +26,9 @@ mod pkg {
 
 fn main() {
   let mut api = ();
-  let mut drsr = ();
+  let drsr = ();
   let mut tp = ();
   let mut trans = ();
-  let mut pkgs_aux = PkgsAux::from_minimum(&mut api, &mut drsr, &mut tp);
-  let _ = trans.send(&mut pkgs_aux.foo().build(), &mut pkgs_aux);
+  let mut pkgs_aux = PkgsAux::from_minimum(&mut api, drsr, &mut tp);
+  let _ = trans.send_pkg(&mut pkgs_aux.foo().build(), &mut pkgs_aux);
 }
diff --git a/wtx/src/data_transformation/dnsn/tests.rs b/wtx/src/data_transformation/dnsn/tests.rs
index 37000ab9..888d7ccf 100644
--- a/wtx/src/data_transformation/dnsn/tests.rs
+++ b/wtx/src/data_transformation/dnsn/tests.rs
@@ -2,7 +2,8 @@
 
 use crate::{
   client_api_framework::pkg::Package,
-  data_transformation::dnsn::{Deserialize, Serialize},
+  data_transformation::dnsn::De,
+  misc::{DecodeSeq, Encode},
 };
 use alloc::string::String;
 use core::marker::PhantomData;
@@ -18,8 +19,8 @@ impl<EREQC, ERESC> FooBar<EREQC, ERESC> {
 
 impl<DRSR, EREQC, ERESC, T> Package<(), DRSR, T, ()> for FooBar<EREQC, ERESC>
 where
-  EREQC: Serialize<DRSR>,
-  ERESC: for<'de> Deserialize<'de, DRSR>,
+  EREQC: Encode<De<DRSR>>,
+  ERESC: for<'de> DecodeSeq<'de, De<DRSR>>,
 {
   type ExternalRequestContent = EREQC;
   type ExternalResponseContent<'de> = ERESC;
@@ -86,7 +87,7 @@ macro_rules! _create_dnsn_test {
         trans.push_response($raw_der);
         assert_eq!(
           trans
-            .send_recv_decode_contained(&mut FooBar::<_, $res<Bar>>::_new($fmt_ser), pkgs_aux)
+            .send_pkg_recv_decode_contained(&mut FooBar::<_, $res<Bar>>::_new($fmt_ser), pkgs_aux)
             .await
             .unwrap(),
           $fmt_der
diff --git a/wtx/src/database/client/postgres/integration_tests.rs b/wtx/src/database/client/postgres/integration_tests.rs
index f2459f47..cd7bc8d3 100644
--- a/wtx/src/database/client/postgres/integration_tests.rs
+++ b/wtx/src/database/client/postgres/integration_tests.rs
@@ -1,12 +1,12 @@
 use crate::{
   database::{
+    Executor as _, Record, Records as _,
     client::postgres::{
-      Config, DecodeValue, EncodeValue, Executor, ExecutorBuffer, Postgres, PostgresError,
-      StructDecoder, StructEncoder, Ty,
+      Config, DecodeWrapper, EncodeWrapper, ExecutorBuffer, Postgres, PostgresError,
+      PostgresExecutor, StructDecoder, StructEncoder, Ty,
     },
-    Decode, Encode, Executor as _, Record, Records as _,
   },
-  misc::{simple_seed, UriRef, Xorshift64},
+  misc::{Decode, Encode, UriRef, Xorshift64, simple_seed},
 };
 use alloc::string::String;
 use tokio::net::TcpStream;
@@ -18,7 +18,7 @@ const SCRAM: &str = "postgres://wtx_scram:wtx@localhost/wtx";
 async fn conn_scram_tls() {
   let uri = UriRef::new(SCRAM);
   let mut rng = Xorshift64::from(simple_seed());
-  let _executor = Executor::<crate::Error, _, _>::connect_encrypted(
+  let _executor = PostgresExecutor::<crate::Error, _, _>::connect_encrypted(
     &Config::from_uri(&uri).unwrap(),
     ExecutorBuffer::new(usize::MAX, &mut rng),
     &mut rng,
@@ -45,15 +45,15 @@ async fn custom_composite_type() {
   struct CustomCompositeType(u32, String);
 
   impl Decode<'_, Postgres<crate::Error>> for CustomCompositeType {
-    fn decode(input: &DecodeValue<'_>) -> Result<Self, crate::Error> {
-      let mut sd = StructDecoder::<crate::Error>::new(input);
+    fn decode(_: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, crate::Error> {
+      let mut sd = StructDecoder::<crate::Error>::new(dw);
       Ok(Self(sd.decode()?, sd.decode()?))
     }
   }
 
   impl Encode<Postgres<crate::Error>> for CustomCompositeType {
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), crate::Error> {
-      let _ev = StructEncoder::<crate::Error>::new(ev)?
+    fn encode(&self, _: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), crate::Error> {
+      let _ev = StructEncoder::<crate::Error>::new(ew)?
         .encode(self.0)?
         .encode_with_ty(&self.1, Ty::Varchar)?;
       Ok(())
@@ -69,7 +69,7 @@ async fn custom_composite_type() {
         CREATE TYPE custom_composite_type AS (int_value INT, varchar_value VARCHAR);
         CREATE TABLE custom_composite_table (id INT, type custom_composite_type);
       ",
-      |_| {},
+      |_| Ok(()),
     )
     .await
     .unwrap();
@@ -94,14 +94,14 @@ async fn custom_domain() {
   struct CustomDomain(String);
 
   impl Decode<'_, Postgres<crate::Error>> for CustomDomain {
-    fn decode(input: &DecodeValue<'_>) -> Result<Self, crate::Error> {
-      Ok(Self(<_ as Decode<Postgres<crate::Error>>>::decode(input)?))
+    fn decode(aux: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, crate::Error> {
+      Ok(Self(<_ as Decode<Postgres<crate::Error>>>::decode(aux, dw)?))
     }
   }
 
   impl Encode<Postgres<crate::Error>> for CustomDomain {
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), crate::Error> {
-      <_ as Encode<Postgres<crate::Error>>>::encode(&self.0, ev)?;
+    fn encode(&self, aux: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), crate::Error> {
+      <_ as Encode<Postgres<crate::Error>>>::encode(&self.0, aux, ew)?;
       Ok(())
     }
   }
@@ -115,7 +115,7 @@ async fn custom_domain() {
         CREATE DOMAIN custom_domain AS VARCHAR(64);
         CREATE TABLE custom_domain_table (id INT, domain custom_domain);
       ",
-      |_| {},
+      |_| Ok(()),
     )
     .await
     .unwrap();
@@ -140,8 +140,8 @@ async fn custom_enum() {
   }
 
   impl Decode<'_, Postgres<crate::Error>> for Enum {
-    fn decode(input: &DecodeValue<'_>) -> Result<Self, crate::Error> {
-      let s = <&str as Decode<Postgres<crate::Error>>>::decode(input)?;
+    fn decode(aux: &mut (), dw: &mut DecodeWrapper<'_>) -> Result<Self, crate::Error> {
+      let s = <&str as Decode<Postgres<crate::Error>>>::decode(aux, dw)?;
       Ok(match s {
         "foo" => Self::Foo,
         "bar" => Self::Bar,
@@ -152,13 +152,13 @@ async fn custom_enum() {
   }
 
   impl Encode<Postgres<crate::Error>> for Enum {
-    fn encode(&self, ev: &mut EncodeValue<'_, '_>) -> Result<(), crate::Error> {
+    fn encode(&self, aux: &mut (), ew: &mut EncodeWrapper<'_, '_>) -> Result<(), crate::Error> {
       let s = match self {
         Enum::Foo => "foo",
         Enum::Bar => "bar",
         Enum::Baz => "baz",
       };
-      <_ as Encode<Postgres<crate::Error>>>::encode(&s, ev)?;
+      <_ as Encode<Postgres<crate::Error>>>::encode(&s, aux, ew)?;
       Ok(())
     }
   }
@@ -172,7 +172,7 @@ async fn custom_enum() {
         CREATE TYPE custom_enum AS ENUM ('foo', 'bar', 'baz');
         CREATE TABLE custom_enum_table (id INT, domain custom_enum);
       ",
-      |_| {},
+      |_| Ok(()),
     )
     .await
     .unwrap();
@@ -421,7 +421,10 @@ async fn serde_json() {
     c: String,
   }
   let mut exec = executor::<crate::Error>().await;
-  exec.execute("CREATE TABLE IF NOT EXISTS serde_json (col JSONB NOT NULL)", |_| {}).await.unwrap();
+  exec
+    .execute("CREATE TABLE IF NOT EXISTS serde_json (col JSONB NOT NULL)", |_| Ok(()))
+    .await
+    .unwrap();
   let col = (1u32, 2i64);
   let _ = exec
     .execute_with_stmt("INSERT INTO serde_json VALUES ($1::jsonb)", (Json(&col),))
@@ -431,10 +434,10 @@ async fn serde_json() {
   assert_eq!(record.decode::<_, Json<(u32, i64)>>(0).unwrap(), Json(col));
 }
 
-async fn executor<E>() -> Executor<E, ExecutorBuffer, TcpStream> {
+async fn executor<E>() -> PostgresExecutor<E, ExecutorBuffer, TcpStream> {
   let uri = UriRef::new(SCRAM);
   let mut rng = Xorshift64::from(simple_seed());
-  Executor::connect(
+  PostgresExecutor::connect(
     &Config::from_uri(&uri).unwrap(),
     ExecutorBuffer::new(usize::MAX, &mut rng),
     &mut rng,
diff --git a/wtx/src/database/schema_manager/integration_tests.rs b/wtx/src/database/schema_manager/integration_tests.rs
index 5ab4ddce..c922c47b 100644
--- a/wtx/src/database/schema_manager/integration_tests.rs
+++ b/wtx/src/database/schema_manager/integration_tests.rs
@@ -5,16 +5,16 @@ mod schema;
 
 use crate::{
   database::{
+    Executor, Identifier,
     schema_manager::{
-      doc_tests::{migration, migration_group},
       Commands, DbMigration, MigrationGroup, SchemaManagement,
+      doc_tests::{migration, migration_group},
     },
-    Identifier, DEFAULT_URI_VAR,
   },
-  misc::{Vector, Xorshift64},
+  misc::{DEController, Vector},
 };
 use alloc::string::String;
-use core::fmt::Write;
+use core::fmt::{Debug, Write};
 use tokio::net::TcpStream;
 
 macro_rules! create_integration_test {
@@ -31,6 +31,7 @@ macro_rules! create_integration_test {
 macro_rules! create_integration_tests {
   (
     $fn_name:ident,
+    mysql: $($mysql:path),*;
     postgres: $($postgres:path),*;
   ) => {
     pub(crate) async fn $fn_name() {
@@ -38,14 +39,34 @@ macro_rules! create_integration_tests {
       let mut _buffer_db_migrations = Vector::<DbMigration>::new();
       let mut _buffer_idents = Vector::<Identifier>::new();
 
+      #[cfg(feature = "mysql")]
       create_integration_test!(
         {
-          let uri = std::env::var(DEFAULT_URI_VAR).unwrap();
-          let uri = crate::misc::UriRef::new(&uri);
+          let uri_string = std::env::var("DATABASE_URI_MYSQL").unwrap();
+          let uri = crate::misc::UriRef::new(&uri_string);
+          let config = crate::database::client::mysql::Config::from_uri(&uri).unwrap();
+          let stream = TcpStream::connect(uri.hostname_with_implied_port()).await.unwrap();
+          let mut rng = crate::misc::Xorshift64::from(crate::misc::simple_seed());
+          crate::database::client::mysql::MysqlExecutor::connect(
+            &config,
+            crate::database::client::mysql::ExecutorBuffer::new(usize::MAX, &mut rng),
+            stream,
+          ).await.unwrap()
+        },
+        (&mut _buffer_cmd, &mut _buffer_db_migrations, &mut _buffer_idents),
+        _generic_schema(),
+        $($mysql),*
+      );
+
+      #[cfg(feature = "postgres")]
+      create_integration_test!(
+        {
+          let uri_string = std::env::var("DATABASE_URI_POSTGRESQL").unwrap();
+          let uri = crate::misc::UriRef::new(&uri_string);
           let config = crate::database::client::postgres::Config::from_uri(&uri).unwrap();
           let stream = TcpStream::connect(uri.hostname_with_implied_port()).await.unwrap();
-          let mut rng = Xorshift64::from(crate::misc::simple_seed());
-          crate::database::client::postgres::Executor::connect(
+          let mut rng = crate::misc::Xorshift64::from(crate::misc::simple_seed());
+          crate::database::client::postgres::PostgresExecutor::connect(
             &config,
             crate::database::client::postgres::ExecutorBuffer::new(usize::MAX, &mut rng),
             &mut rng,
@@ -62,6 +83,7 @@ macro_rules! create_integration_tests {
 
 macro_rules! create_all_integration_tests {
   (
+    mysql: $($mysql:path),*;
     postgres: $($postgres:path),*;
 
     generic: $($fun:path),*;
@@ -71,16 +93,19 @@ macro_rules! create_all_integration_tests {
   ) => {
     create_integration_tests!(
       integration_tests_db,
+      mysql: $($mysql),*;
       postgres: $($postgres),*;
     );
 
     create_integration_tests!(
       integration_tests_generic,
+      mysql: $($fun),*;
       postgres: $($fun),*;
     );
 
     create_integration_tests!(
       integration_tests_schema,
+      mysql: $($without_schema),*;
       postgres: $($with_schema),*;
     );
 
@@ -96,6 +121,8 @@ macro_rules! create_all_integration_tests {
 create_all_integration_tests!(
   // Database
 
+  mysql:
+    db::mysql::_clean_drops_all_objs;
   postgres:
     db::postgres::_clean_drops_all_objs;
 
@@ -128,9 +155,10 @@ pub(crate) async fn create_foo_table<E>(
   schema_prefix: &str,
 ) where
   E: SchemaManagement,
+  <<E as Executor>::Database as DEController>::Error: Debug,
 {
-  buffer_cmd.write_fmt(format_args!("CREATE TABLE {}foo(id INT)", schema_prefix)).unwrap();
-  c.executor.execute(buffer_cmd.as_str(), |_| {}).await.unwrap();
+  buffer_cmd.write_fmt(format_args!("CREATE TABLE {schema_prefix}foo(id INT)")).unwrap();
+  c.executor.execute(buffer_cmd.as_str(), |_| Ok(())).await.unwrap();
   buffer_cmd.clear();
 }
 
@@ -156,11 +184,6 @@ where
   mg
 }
 
-#[inline]
-pub(crate) fn _mssql_schema() -> AuxTestParams {
-  AuxTestParams { default_schema: "dbo", wtx_schema: "_wtx", schema_regulator: 0 }
-}
-
 #[inline]
 pub(crate) fn _pg_schema() -> AuxTestParams {
   AuxTestParams { default_schema: "public", wtx_schema: "_wtx", schema_regulator: 0 }
diff --git a/wtx/src/database/schema_manager/integration_tests/backend.rs b/wtx/src/database/schema_manager/integration_tests/backend.rs
index 378851df..91e2a431 100644
--- a/wtx/src/database/schema_manager/integration_tests/backend.rs
+++ b/wtx/src/database/schema_manager/integration_tests/backend.rs
@@ -1,10 +1,10 @@
 use crate::{
   database::{
+    Identifier,
     schema_manager::{
-      integration_tests::{AuxTestParams, _migrate_doc_test},
       Commands, DbMigration, SchemaManagement,
+      integration_tests::{_migrate_doc_test, AuxTestParams},
     },
-    Identifier,
   },
   misc::Vector,
 };
diff --git a/wtx/src/database/schema_manager/integration_tests/db.rs b/wtx/src/database/schema_manager/integration_tests/db.rs
index 2acb9f25..58cb5e91 100644
--- a/wtx/src/database/schema_manager/integration_tests/db.rs
+++ b/wtx/src/database/schema_manager/integration_tests/db.rs
@@ -1,1 +1,2 @@
+pub(crate) mod mysql;
 pub(crate) mod postgres;
diff --git a/wtx/src/database/schema_manager/integration_tests/db/mysql.rs b/wtx/src/database/schema_manager/integration_tests/db/mysql.rs
new file mode 100644
index 00000000..67f9ff96
--- /dev/null
+++ b/wtx/src/database/schema_manager/integration_tests/db/mysql.rs
@@ -0,0 +1,29 @@
+#[cfg(feature = "schema-manager-dev")]
+use {
+  crate::database::{
+    FromRecord, Identifier, client::mysql::Mysql, schema_manager::Commands,
+    schema_manager::DbMigration, schema_manager::SchemaManagement,
+    schema_manager::integration_tests,
+  },
+  crate::misc::Vector,
+  alloc::string::String,
+};
+
+#[cfg(feature = "schema-manager-dev")]
+pub(crate) async fn _clean_drops_all_objs<E>(
+  (buffer_cmd, _, buffer_idents): (&mut String, &mut Vector<DbMigration>, &mut Vector<Identifier>),
+  c: &mut Commands<E>,
+  _: integration_tests::AuxTestParams,
+) where
+  E: SchemaManagement<Database = Mysql<crate::Error>>,
+  Identifier: FromRecord<Mysql<crate::Error>>,
+{
+  integration_tests::create_foo_table(buffer_cmd, c, "").await;
+  c.executor.table_names(buffer_cmd, buffer_idents, "").await.unwrap();
+  assert_eq!(buffer_idents.len(), 1);
+
+  c.clear((buffer_cmd, buffer_idents)).await.unwrap();
+
+  c.executor.table_names(buffer_cmd, buffer_idents, "").await.unwrap();
+  assert_eq!(buffer_idents.len(), 0);
+}
diff --git a/wtx/src/database/schema_manager/integration_tests/db/postgres.rs b/wtx/src/database/schema_manager/integration_tests/db/postgres.rs
index d6792088..c1efcab5 100644
--- a/wtx/src/database/schema_manager/integration_tests/db/postgres.rs
+++ b/wtx/src/database/schema_manager/integration_tests/db/postgres.rs
@@ -1,9 +1,9 @@
 #[cfg(feature = "schema-manager-dev")]
 use {
   crate::database::{
-    client::postgres::Postgres, schema_manager::fixed_sql_commands::postgres,
-    schema_manager::integration_tests, schema_manager::Commands, schema_manager::DbMigration,
-    schema_manager::SchemaManagement, FromRecord, Identifier,
+    FromRecord, Identifier, client::postgres::Postgres, schema_manager::Commands,
+    schema_manager::DbMigration, schema_manager::SchemaManagement,
+    schema_manager::fixed_sql_commands::postgres, schema_manager::integration_tests,
   },
   crate::misc::Vector,
   alloc::string::String,
@@ -19,15 +19,21 @@ pub(crate) async fn _clean_drops_all_objs<E>(
   Identifier: FromRecord<Postgres<crate::Error>>,
 {
   integration_tests::create_foo_table(buffer_cmd, c, "public.").await;
-  c.executor.execute("CREATE SCHEMA bar", |_| {}).await.unwrap();
+  c.executor.execute("CREATE SCHEMA bar", |_| Ok(())).await.unwrap();
   integration_tests::create_foo_table(buffer_cmd, c, "bar.").await;
-  c.executor.execute("CREATE DOMAIN integer0 AS INTEGER CONSTRAINT must_be_greater_than_or_equal_to_zero_chk CHECK(VALUE >= 0)", |_| {}).await.unwrap();
-  c.executor.execute("CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS 'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE", |_| {}).await.unwrap();
-  c.executor.execute("CREATE PROCEDURE something() LANGUAGE SQL AS $$ $$", |_| {}).await.unwrap();
-  c.executor.execute("CREATE SEQUENCE serial START 101", |_| {}).await.unwrap();
-  c.executor.execute("CREATE TYPE a_type AS (field INTEGER[31])", |_| {}).await.unwrap();
-  c.executor.execute("CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')", |_| {}).await.unwrap();
-  c.executor.execute("CREATE VIEW view AS SELECT * FROM foo WHERE id = 1", |_| {}).await.unwrap();
+  c.executor.execute("CREATE DOMAIN integer0 AS INTEGER CONSTRAINT must_be_greater_than_or_equal_to_zero_chk CHECK(VALUE >= 0)", |_| Ok(())).await.unwrap();
+  c.executor.execute("CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS 'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE", |_| Ok(())).await.unwrap();
+  c.executor
+    .execute("CREATE PROCEDURE something() LANGUAGE SQL AS $$ $$", |_| Ok(()))
+    .await
+    .unwrap();
+  c.executor.execute("CREATE SEQUENCE serial START 101", |_| Ok(())).await.unwrap();
+  c.executor.execute("CREATE TYPE a_type AS (field INTEGER[31])", |_| Ok(())).await.unwrap();
+  c.executor.execute("CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')", |_| Ok(())).await.unwrap();
+  c.executor
+    .execute("CREATE VIEW view AS SELECT * FROM foo WHERE id = 1", |_| Ok(()))
+    .await
+    .unwrap();
 
   c.executor.table_names(buffer_cmd, buffer_idents, "public").await.unwrap();
   assert_eq!(buffer_idents.len(), 1);
diff --git a/wtx/src/database/schema_manager/integration_tests/generic.rs b/wtx/src/database/schema_manager/integration_tests/generic.rs
index 50848239..20f447c3 100644
--- a/wtx/src/database/schema_manager/integration_tests/generic.rs
+++ b/wtx/src/database/schema_manager/integration_tests/generic.rs
@@ -1,11 +1,11 @@
 use crate::{
   database::{
+    Executor, Identifier,
     schema_manager::{
-      integration_tests::AuxTestParams, Commands, DbMigration, MigrationGroup, SchemaManagement,
+      Commands, DbMigration, MigrationGroup, SchemaManagement, integration_tests::AuxTestParams,
     },
-    Database, Identifier,
   },
-  misc::Vector,
+  misc::{DEController, Vector},
 };
 use alloc::string::String;
 use core::fmt::Debug;
@@ -17,8 +17,9 @@ pub(crate) async fn all_tables_returns_the_number_of_tables_of_the_default_schem
   aux: AuxTestParams,
 ) where
   E: SchemaManagement,
+  <<E as Executor>::Database as DEController>::Error: Debug,
 {
-  c.executor.execute("CREATE TABLE IF NOT EXISTS foo(id INT)", |_| {}).await.unwrap();
+  c.executor.execute("CREATE TABLE IF NOT EXISTS foo(id INT)", |_| Ok(())).await.unwrap();
   c.executor.table_names(buffer_cmd, buffer_idents, aux.default_schema).await.unwrap();
   assert_eq!(buffer_idents.len(), 1);
   buffer_idents.clear();
@@ -34,7 +35,7 @@ pub(crate) async fn rollback_works<E>(
   aux: AuxTestParams,
 ) where
   E: SchemaManagement,
-  <E::Database as Database>::Error: Debug,
+  <E::Database as DEController>::Error: Debug,
 {
   let path = Path::new("../.test-utils/migrations.toml");
   c.migrate_from_toml_path((buffer_cmd, buffer_db_migrations), path).await.unwrap();
diff --git a/wtx/src/database/schema_manager/integration_tests/schema.rs b/wtx/src/database/schema_manager/integration_tests/schema.rs
index e296b60c..d0d2dedf 100644
--- a/wtx/src/database/schema_manager/integration_tests/schema.rs
+++ b/wtx/src/database/schema_manager/integration_tests/schema.rs
@@ -3,7 +3,7 @@ pub(crate) mod without_schema;
 
 use crate::{
   database::schema_manager::{
-    integration_tests::AuxTestParams, Commands, MigrationGroup, SchemaManagement,
+    Commands, MigrationGroup, SchemaManagement, integration_tests::AuxTestParams,
   },
   misc::Vector,
 };
diff --git a/wtx/src/database/schema_manager/integration_tests/schema/with_schema.rs b/wtx/src/database/schema_manager/integration_tests/schema/with_schema.rs
index 9eb53889..2a324a7a 100644
--- a/wtx/src/database/schema_manager/integration_tests/schema/with_schema.rs
+++ b/wtx/src/database/schema_manager/integration_tests/schema/with_schema.rs
@@ -1,10 +1,10 @@
 use crate::{
   database::{
+    Identifier,
     schema_manager::{
-      integration_tests::{AuxTestParams, _migrate_doc_test},
       Commands, DbMigration, SchemaManagement,
+      integration_tests::{_migrate_doc_test, AuxTestParams},
     },
-    Identifier,
   },
   misc::Vector,
 };
diff --git a/wtx/src/database/schema_manager/integration_tests/schema/without_schema.rs b/wtx/src/database/schema_manager/integration_tests/schema/without_schema.rs
index 3ff7ee85..433fc300 100644
--- a/wtx/src/database/schema_manager/integration_tests/schema/without_schema.rs
+++ b/wtx/src/database/schema_manager/integration_tests/schema/without_schema.rs
@@ -1,7 +1,7 @@
 use crate::{
   database::{
-    schema_manager::{integration_tests::AuxTestParams, Commands, DbMigration, SchemaManagement},
     Identifier,
+    schema_manager::{Commands, DbMigration, SchemaManagement, integration_tests::AuxTestParams},
   },
   misc::Vector,
 };
diff --git a/wtx/src/http/client_pool/integration_tests.rs b/wtx/src/http/client_pool/integration_tests.rs
index bd51c6e1..c3238735 100644
--- a/wtx/src/http/client_pool/integration_tests.rs
+++ b/wtx/src/http/client_pool/integration_tests.rs
@@ -1,25 +1,40 @@
 use crate::{
-  http::{client_pool::ClientPoolBuilder, ReqBuilder, ReqResBuffer},
+  http::{HttpClient, Method, ReqResBuffer, client_pool::ClientPoolBuilder},
   misc::Uri,
 };
 
 #[tokio::test]
 async fn popular_sites() {
   let uri = Uri::new("https://github.com");
-  let _res = ReqBuilder::get(ReqResBuffer::empty())
-    .send(&mut ClientPoolBuilder::tokio_rustls(1).build().lock(&uri).await.unwrap().client, &uri)
+  let _res = ClientPoolBuilder::tokio_rustls(1)
+    .build()
+    .lock(&uri)
+    .await
+    .unwrap()
+    .client
+    .send_recv_single(Method::Get, &uri, ReqResBuffer::empty())
     .await
     .unwrap();
 
   let uri = Uri::new("https://duckduckgo.com");
-  let _res = ReqBuilder::get(ReqResBuffer::empty())
-    .send(&mut ClientPoolBuilder::tokio_rustls(1).build().lock(&uri).await.unwrap().client, &uri)
+  let _res = ClientPoolBuilder::tokio_rustls(1)
+    .build()
+    .lock(&uri)
+    .await
+    .unwrap()
+    .client
+    .send_recv_single(Method::Get, &uri, ReqResBuffer::empty())
     .await
     .unwrap();
 
   let uri = Uri::new("https://www.google.com");
-  let _res = ReqBuilder::get(ReqResBuffer::empty())
-    .send(&mut ClientPoolBuilder::tokio_rustls(1).build().lock(&uri).await.unwrap().client, &uri)
+  let _res = ClientPoolBuilder::tokio_rustls(1)
+    .build()
+    .lock(&uri)
+    .await
+    .unwrap()
+    .client
+    .send_recv_single(Method::Get, &uri, ReqResBuffer::empty())
     .await
     .unwrap();
 }
diff --git a/wtx/src/http/server_framework/tests.rs b/wtx/src/http/server_framework/tests.rs
index f72a8a8a..9549c407 100644
--- a/wtx/src/http/server_framework/tests.rs
+++ b/wtx/src/http/server_framework/tests.rs
@@ -1,9 +1,9 @@
 use crate::http::{
+  AutoStream, ManualStream, Method, ReqResBuffer, Request, Response, StatusCode,
   server_framework::{
-    endpoint::Endpoint, get, ConnAux, Middleware, Router, ServerFramework, ServerFrameworkBuilder,
-    StateClean, StreamAux,
+    ConnAux, Middleware, Router, ServerFramework, ServerFrameworkBuilder, StateClean, StreamAux,
+    endpoint::Endpoint, get,
   },
-  AutoStream, ManualStream, Method, ReqResBuffer, Request, Response, StatusCode,
 };
 use core::{
   net::{IpAddr, Ipv4Addr},
@@ -99,17 +99,37 @@ async fn nested_middlewares() {
   async fn add11(
     state: StateClean<'_, Counter, Counter, ReqResBuffer>,
   ) -> crate::Result<StatusCode> {
+    assert_eq!(state.conn_aux.0, 6);
+    assert_eq!(state.stream_aux.0, 6);
     state.conn_aux.0 += 11;
     state.stream_aux.0 += 11;
     Ok(StatusCode::Ok)
   }
 
-  async fn add13(mut state: ManualStream<Counter, (), Counter>) -> crate::Result<()> {
+  async fn add12(mut state: ManualStream<Counter, (), Counter>) -> crate::Result<()> {
     state.conn_aux.0 += 13;
     state.stream_aux.0 += 13;
     Ok(())
   }
 
+  async fn add13(
+    state: StateClean<'_, Counter, Counter, ReqResBuffer>,
+  ) -> crate::Result<StatusCode> {
+    state.conn_aux.0 += 15;
+    state.stream_aux.0 += 15;
+    Ok(StatusCode::Ok)
+  }
+
+  async fn add14(
+    state: StateClean<'_, Counter, Counter, ReqResBuffer>,
+  ) -> crate::Result<StatusCode> {
+    assert_eq!(state.conn_aux.0, 3);
+    assert_eq!(state.stream_aux.0, 3);
+    state.conn_aux.0 += 17;
+    state.stream_aux.0 += 17;
+    Ok(StatusCode::Ok)
+  }
+
   let router = Router::new(
     paths!(
       (
@@ -118,41 +138,74 @@ async fn nested_middlewares() {
           paths!(
             (
               "/bbb",
-              Router::new(paths!(("/ccc", get(add11)), ("/ddd", get(add11))), CounterMw).unwrap()
+              Router::new(paths!(("/ccc", get(add11)), ("/ddd", get(add12))), CounterMw).unwrap()
             ),
-            ("/eee", get(add11))
+            ("/eee", get(add13))
           ),
           (),
         )
         .unwrap()
       ),
-      ("/fff", get(add13)),
+      ("/fff", get(add14)),
     ),
     CounterMw,
   )
   .unwrap();
 
   let sf = ServerFrameworkBuilder::new(router).with_dflt_aux();
-  let mut rrd = ReqResBuffer::default();
-  rrd
-    .uri
-    .reset(|el| {
-      el.push_str("http://localhost/aaa/bbb/ccc");
-      Ok(())
-    })
-    .unwrap();
-  let path = rrd.uri.path();
-  let el = ServerFramework::<_, (), _, _, _, _, _, ()>::_route_params(&path, &sf._router).unwrap();
-  let mut router_auto_stream = AutoStream {
+  let mut auto_stream = AutoStream {
     conn_aux: Counter(0),
     peer: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
     protocol: None,
     req: Request::http2(Method::Get, ReqResBuffer::default()),
     stream_aux: Counter(0),
   };
-  let _ = sf._router.auto(&mut router_auto_stream, (0, &el.0)).await.unwrap();
-  // 3 + 3 + 11 + 7 + 7
-  assert_eq!(router_auto_stream.conn_aux.0, 31);
-  // 3 + 3 + 11 + 7 + 7
-  assert_eq!(router_auto_stream.stream_aux.0, 31);
+
+  {
+    auto_stream
+      .req
+      .rrd
+      .uri
+      .reset(|el| {
+        el.push_str("http://localhost/aaa/bbb/ccc");
+        Ok(())
+      })
+      .unwrap();
+    let el = ServerFramework::<_, (), _, _, _, _, _, ()>::_route_params(
+      auto_stream.req.rrd.uri.path(),
+      &sf._router,
+    )
+    .unwrap();
+    let _ = sf._router.auto(&mut auto_stream, (0, &el.0)).await.unwrap();
+    // 3 + 3 + 11 + 7 + 7
+    assert_eq!(auto_stream.conn_aux.0, 31);
+    // 3 + 3 + 11 + 7 + 7
+    assert_eq!(auto_stream.stream_aux.0, 31);
+  }
+
+  auto_stream.conn_aux = Counter(0);
+  auto_stream.req.rrd.clear();
+  auto_stream.stream_aux = Counter(0);
+
+  {
+    auto_stream
+      .req
+      .rrd
+      .uri
+      .reset(|el| {
+        el.push_str("http://localhost/fff");
+        Ok(())
+      })
+      .unwrap();
+    let el = ServerFramework::<_, (), _, _, _, _, _, ()>::_route_params(
+      auto_stream.req.rrd.uri.path(),
+      &sf._router,
+    )
+    .unwrap();
+    let _ = sf._router.auto(&mut auto_stream, (0, &el.0)).await.unwrap();
+    // 3 + 17 + 7
+    assert_eq!(auto_stream.conn_aux.0, 27);
+    // 3 + 17 + 7
+    assert_eq!(auto_stream.stream_aux.0, 27);
+  }
 }
diff --git a/wtx/src/http2/tests/connections.rs b/wtx/src/http2/tests/connections.rs
index b596ae97..42f00912 100644
--- a/wtx/src/http2/tests/connections.rs
+++ b/wtx/src/http2/tests/connections.rs
@@ -1,11 +1,11 @@
 use crate::{
   http::{Header, Headers, Method, ReqResBuffer, ReqResData, Request, StatusCode},
   http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2Tokio},
-  misc::{simple_seed, Either, UriRef, UriString, Xorshift64},
+  misc::{Either, UriRef, UriString, Xorshift64, simple_seed},
   tests::_uri,
 };
 use core::time::Duration;
-use tokio::net::{tcp::OwnedWriteHalf, TcpListener, TcpStream};
+use tokio::net::{TcpListener, TcpStream, tcp::OwnedWriteHalf};
 
 #[tokio::test]
 async fn connections() {
diff --git a/wtx/src/http2/tests/hpack.rs b/wtx/src/http2/tests/hpack.rs
index 44f0b252..70946071 100644
--- a/wtx/src/http2/tests/hpack.rs
+++ b/wtx/src/http2/tests/hpack.rs
@@ -1,19 +1,19 @@
 use crate::{
   http::{Header, StatusCode},
   http2::{
-    hpack_decoder::HpackDecoder, hpack_encoder::HpackEncoder, hpack_header::HpackHeaderBasic,
-    MAX_HPACK_LEN,
+    MAX_HPACK_LEN, hpack_decoder::HpackDecoder, hpack_encoder::HpackEncoder,
+    hpack_header::HpackHeaderBasic,
   },
-  misc::{from_utf8_basic, simple_seed, Vector, Xorshift64},
+  misc::{Vector, Xorshift64, from_utf8_basic, simple_seed},
 };
 use alloc::string::String;
 use core::{fmt::Formatter, marker::PhantomData};
 use serde::{
-  de::{Deserializer, MapAccess, Visitor},
   Deserialize,
+  de::{Deserializer, MapAccess, Visitor},
 };
 use std::{
-  fs::{read_dir, File},
+  fs::{File, read_dir},
   io::Read,
   path::Path,
   process::Command,
diff --git a/wtx/src/misc/blocks_deque/tests.rs b/wtx/src/misc/blocks_deque/tests.rs
index a3f388e6..c8f67316 100644
--- a/wtx/src/misc/blocks_deque/tests.rs
+++ b/wtx/src/misc/blocks_deque/tests.rs
@@ -5,7 +5,7 @@
 // RO = Right Occupied
 // T = Tail (Exclusive)
 
-use crate::misc::{blocks_deque::BlockRef, BlocksDeque};
+use crate::misc::{BlocksDeque, blocks_deque::BlockRef};
 
 // [. . . . . . . .]: Empty - (LF=8, LO=0,RF=0, RO=0) - (H=0, T=0)
 // [. . . . . . . H]: Push front - (LF=7, LO=0, RF=0, RO=1) - (H=7, T=8)
diff --git a/wtx/src/misc/deque/tests.rs b/wtx/src/misc/deque/tests.rs
index 4c6dfb06..86ac37a2 100644
--- a/wtx/src/misc/deque/tests.rs
+++ b/wtx/src/misc/deque/tests.rs
@@ -1,4 +1,4 @@
-use crate::misc::{deque::is_wrapping, Deque};
+use crate::misc::{Deque, deque::is_wrapping};
 
 #[test]
 fn as_slices() {
diff --git a/wtx/src/web_socket/handshake/tests.rs b/wtx/src/web_socket/handshake/tests.rs
index ae6242ec..29027f7f 100644
--- a/wtx/src/web_socket/handshake/tests.rs
+++ b/wtx/src/web_socket/handshake/tests.rs
@@ -10,8 +10,8 @@ macro_rules! call_tests {
 use crate::{
   tests::_uri,
   web_socket::{
-    compression::NegotiatedCompression, Compression, Frame, OpCode, WebSocketAcceptor,
-    WebSocketConnector, WebSocketOwned,
+    Compression, Frame, OpCode, WebSocketAcceptor, WebSocketConnector, WebSocketOwned,
+    compression::NegotiatedCompression,
   },
 };
 use core::{