TLS 1.3 in 30.8 KB: wolfSSL vs MbedTLS

wolfSSL’s new tinytls13 profile against a parity-matched MbedTLS, measured on Cortex-M33, x86_64, and aarch64.


wolfSSL and MbedTLS both target small embedded TLS, but configured and built with parity options they are not the same size. The new tinytls13 profile is a TLS 1.3-only build that strips everything which is not TLS 1.3 and defaults to a tiny PSK and ECDHE floor. It builds a complete TLS 1.3 PSK client in 30.8 KB on Cortex-M33, 44% smaller than a fully-minimized MbedTLS, and it is smaller on every platform and every configuration we measured.

The numbers



TLS 1.3 PSK client floor (X25519, SHA-256 only) across platforms. wolfSSL tinytls13 (blue) vs MbedTLS 3.6 (grey).

Thumb-2 is the densest instruction set, aarch64 sits in the middle, and x86_64 is the largest, but the relative advantage holds across all three. All four configurations on Cortex-M33:

Configuration wolfSSL (B) MbedTLS (B) smaller
PSK X25519 30,836 55,544 −44%
PSK P-256 37,347 55,544 −33%
Cert (ECDSA P-256) 62,765 69,348 −9%
mTLS 66,554 70,116 −5%

Everything past the floor is opt-in: a static memory pool with no system malloc is 31.4 KB, P-256 instead of X25519 is 36.5 KB, and ML-DSA-44 post-quantum verify, including the SHA-3/SHAKE it pulls in, fits in 42.8 KB.

Why the floor gap is so wide


One dependency explains most of the 44%. MbedTLS’s TLS 1.3 hard-errors without mbedtls_x509_crt, so MBEDTLS_X509_CRT_PARSE_C has to stay enabled: it cannot build a TLS 1.3 client without its X.509 certificate-handling code, even for a pure-PSK handshake that never sees a certificate. tinytls13 has no such dependency and compiles X.509 out entirely. Once both libraries carry certificates on purpose, the gap narrows to between 4% and 9%.

How the code is distributed



Component breakdown of the roughly 37 KB PSK P-256 client on Cortex-M33, bucketed from per-symbol sizes.

Cryptography is only ~12 KB (32%) of the total. The TLS 1.3 protocol, covering the handshake, extensions, record layer, and key schedule, is ~18 KB (49%). The protocol, not the math, dominates the footprint.

How we measured


  • Same operation, same flags. Both libraries are built from source with -Os -flto -ffunction-sections -fdata-sections and -Wl,–gc-sections, then run wolfSSL_connect against mbedtls_ssl_handshake.
  • MbedTLS is fully optimized too. It uses the baremetal_size preset, a minimal PSA_WANT_* config, AES table reduction, and SHA-384 off so it matches wolfSSL’s SHA-256-only floor.
  • Sizes come from the linked binary. Flash is text plus data, and the breakdown is bucketed from nm per-symbol sizes, with 96% attributed.

Try it


The smallest wolfSSL TLS 1.3 client is one flag:

./configure --enable-tinytls13
make

Every configuration is built and make check-ed in CI with live handshakes negotiating TLS13-AES128-GCM-SHA256. The full whitepaper has the exact build steps behind every number. Questions? Contact facts@wolfssl.com or +1 425 245 8247.

*Measured June 2026: wolfSSL v5.9.x (tinytls13) and MbedTLS 3.6.x, both built from source. Cortex-M33 and aarch64 with GCC 14.2, x86_64 with clang.

Download wolfSSL Now