Plate 59
enum.IntEnum vs int Status Codes: Localhost Lab
Aditya Challa4 min read
Intro — what this post promises
HTTP-like status handling with enum.IntEnum vs bare int. This lab reports ops/s for equality, match, and set membership on Linux localhost.
Related links:
- path read text vs open localhost lab
- copy copy vs dict copy localhost lab
- html parser vs regex localhost lab
- xml etree vs json localhost lab
- logging formatter vs fstring localhost lab
- dataclass asdict vs vars localhost lab
- tracemalloc snapshot localhost lab
- gc collect cost localhost lab
Lab honesty (1 Oct 2026 IST): Python 3.13.5. Affiliates: 0. Differentiates from enum-vs-constants (lab 61) — that post compared Enum names to module constants; this one is IntEnum throughput vs int.
Verdict up front (n=500000): int == 404 ~46619990 ops/s; Status.MISS eq ~36624083; IntEnum == 404 ~52952067. Match: int ~19043460 vs enum ~14886038.
Arms
| Arm | Pattern |
|---|---|
| int == literal | bare codes |
| IntEnum == member | typed compare |
| IntEnum == int | cross compare |
| match int / match enum | structural switch |
in set of ints / enums | membership |
Seven rounds, p50. Status.MISS is an int (is_int=True), equals 404, and hashes into a set of int peers.
Lab topology
Script: lab-evidence/133-intenum-vs-int/results/run_lab.py.
Lead table (p50 ops/s)
| Arm | ops/s |
|---|---|
| eq int literal | 46619990 |
| eq IntEnum member | 36624083 |
| eq IntEnum to int | 52952067 |
| match int | 19043460 |
| match enum | 14886038 |
| set in int | 34783961 |
| set in enum | 32891368 |
IntEnum is not “free,” but it stayed in the same ballpark — especially when compared to int literals.
Why IntEnum still wins product-wise
You get .name ('MISS'), exhaustiveness in reviews, and fewer magic numbers in alerts. The cost on this run was modest versus losing a 404/403 mix-up at 3 a.m.
Reading it for SRE work
- Service status / exit codes → IntEnum at API boundaries; store/transmit as int when needed.
- Ultra-hot packet filters already on raw ints → keep ints; convert at the edge.
- Lab 61 covers non-int Enum naming; this post is IntEnum arithmetic/compare cost.
- Sets of IntEnum members behave with int peers (
hash_equal_in_set=True).
Match cost
match on enums ran ~14886038 ops/s vs ints ~19043460. Prefer clarity in control planes; do not micro-optimize status switches before profiling the I/O around them.
Membership checks were close (~34783961 vs ~32891368), so an allow-list of statuses can stay typed without a large tax.
If on-call dashboards already emit integer codes, IntEnum at the producer still documents intent; consumers can keep comparing to literals safely because IntEnum subclasses int.
Clarity budget
Spending a few percent of compare throughput to keep Status.MISS in source is usually the right trade. On this box, member equality still cleared ~36624083 ops/s. Optimize the HTTP client or DB round-trip before rewriting status enums back to magic ints.
Pitfalls
- Using plain
Enumwhere you need int equality with wire codes. - Assuming IntEnum is slower by “orders of magnitude” without measuring.
- Breaking JSON dumps (IntEnum is fine as int; complex Enum is not).
- Mixing lab 61 takeaways with this IntEnum microbench.
Reproduce
Evidence: summary.json, summary.txt.
Limits
One Linux box. Synthetic status stream. Not protobuf enums.
Takeaway
Bare int eq hit ~46619990 ops/s; IntEnum member eq ~36624083; IntEnum-to-int ~52952067. Prefer IntEnum for readable status codes — the throughput gap is small next to the clarity win.
Lab evidence
What I found running this
Ran lab-evidence/133-intenum-vs-int/results/run_lab.py on Linux localhost with Python 3.13.5 on 1 Oct 2026 IST. Seven rounds, p50 over n=500000 mixed status stream: int == 404 ~46619990 ops/s; Status.MISS eq ~36624083; IntEnum == 404 ~52952067; match int ~19043460 vs enum ~14886038; set membership int ~34783961 vs enum ~32891368. Status.MISS is_int=True, equals 404, and hashes with int peers; affiliates 0.