Skip to content

Performance & Benchmarks

iron-monk is a pure-Python validation library. It relies on optimized standard-library constructs — no compiled C/Rust extensions, no eval()-based code generation, no compilation toolchain at install time. The cost is a few microseconds of pure-Python overhead in tight loops; the payoff is faster cold starts and zero dependency baggage.

Methodology

Benchmarks were run on Python 3.14.4, Apple M2 Max, in an isolated virtual environment. Most scenarios execute 100,000 validations against a small primitive schema (string length + integer interval) so framework overhead is what is being measured, not user code. The Large List row uses 10,000 iterations over 1,000-item lists to isolate per-item dispatch cost; Guard Access runs 1,000,000 attribute reads to isolate the validated-instance read path.

The full script lives at support/benchmark.py.

Results

Metric iron-monk (0.26.0) msgspec (0.21.1) pydantic (2.13.4) attrs (26.1.0) marshmallow (4.3.0)
Package Size 0.10 MB 0.44 MB 5.88 MB 0.21 MB 0.17 MB
Cold Start 39.46ms 43.40ms 75.17ms 50.59ms 61.94ms
Object (100k) 0.158s 0.013s 0.054s 0.086s N/A
Dict (100k) 0.095s 0.058s 0.051s N/A 0.440s
Nested Dict (100k) 0.324s 0.071s 0.056s N/A 1.403s
Invalid Dict (100k) 0.235s 0.082s 0.075s N/A 1.017s
Sanitized Dict (100k) 0.104s 0.060s 0.050s N/A 0.429s
Partial Dict (100k) 0.065s N/A N/A N/A 0.267s
Union Dict (100k) 0.119s 0.056s 0.033s N/A N/A
Large List (10k × 1k items) 1.085s 0.056s 0.185s N/A N/A
Refs / Cross-Field (100k) 0.235s N/A N/A N/A N/A
Guard Access (1M attr reads) 0.257s (plain dataclass: 0.025s) N/A N/A N/A N/A
Function Call (100k) 0.171s N/A 0.050s N/A N/A

What the numbers mean

Holistically best-in-class for pure-Python

iron-monk is the only library on the board that natively handles standard objects, raw dicts, deeply nested schemas, dynamic partial updates, payload sanitization, function interception, Union routing, and cross-field Ref constraints — in a single zero-dependency package. It validates over 1 million dictionaries per second while still aggregating every error into a single response.

Serverless-ready cold starts

With zero dependencies, iron-monk is the fastest library on this list to import. In serverless environments where every millisecond of cold-start latency matters, the dependency tax of pydantic or msgspec is a real bill that iron-monk does not charge.

Why attrs wins on object instantiation

attrs generates Python source strings and compiles them with eval() at class-definition time. iron-monk deliberately does not — keeping the codebase auditable and free of dynamic codegen costs a few microseconds per object.

Why msgspec and pydantic win on raw loops

Both ship compiled C/Rust cores that beat CPython bytecode on hot loops. The trade-off is dependency size, install complexity, and rigidity around dynamic features (PATCH semantics, raw-dict sanitization, standalone constraint execution). For most application workloads, iron-monk's pure-Python overhead is invisible next to network or database latency — and you keep the ergonomics.


Run it yourself

The benchmark script is reproducible. Run it inside a fresh virtual environment to verify the numbers on your hardware:

mkdir monk_benchmarks && cd monk_benchmarks
uv init
uv python pin 3.14

uv add iron-monk msgspec pydantic attrs marshmallow

curl -O https://raw.githubusercontent.com/benesgarage/iron-monk/main/support/benchmark.py
uv run benchmark.py