DEV Community

Sumit Dhaka
Sumit Dhaka

Posted on

Why I Separated MIB Compilation from SNMP Execution in Python

Why I Separated MIB Compilation from SNMP Execution in Python

When I began building network-management tools, I wasn't planning to write a MIB compiler or implement an SNMP runtime.

I was building applications that needed to manage MIBs, query devices, decode notifications and simulate SNMP behavior.

The problem was that MIB compilation and SNMP integration kept becoming engineering projects of their own.

As those applications grew, I realized that understanding what a MIB describes and communicating with an SNMP device are two separate responsibilities.

Separating those responsibilities became one of the most important architectural decisions in my Trishul projects.

The original problem

My early tools used PySMI and PySNMP.

Both are capable, maintained projects. My difficulty wasn't that they couldn't perform their primary functions. It was how their integration fitted into my applications.

The existing architecture centered around compiling MIBs into Python modules that the PySNMP runtime could load. PySMI also supports JSON output, but I wanted a stable, portable data contract for applications that shouldn't need the same Python runtime.

I also encountered specific error-handling, dependency-resolution and runtime-integration issues while developing my projects.

At the application level, the SNMP Suite had accumulated separate worker processes and loopback communication to coordinate protocol operations.

More features meant more integration machinery.

Decision 1: Make JSON the primary MIB artifact

I created Trishul SMI to compile SMIv1 and SMIv2 definitions into structured, versioned JSON.

The goal wasn't simply changing file extensions.

A useful compiled MIB artifact needs to preserve information that downstream systems can actually consume: numeric OIDs, symbolic names, syntax, enumerations, units, constraints and dependency information.

The compiler can emit standalone JSON modules and optional bundle manifests and OID indexes.

For example:

pip install trishul-smi

tsmi compile IF-MIB --online \
  --emit-manifest \
  --emit-oid-index \
  -o ./out
Enter fullscreen mode Exit fullscreen mode

This allows application code to consume compiled MIB knowledge without embedding a compiler or depending on PySNMP-generated Python modules.

It also makes the boundary explicit: compilation can happen as a build or management operation, while applications consume the resulting artifacts.

Decision 2: Keep the protocol runtime independent

Next came Trishul SNMP.

It provides asynchronous SNMP manager operations, notification handling, offline decoding and narrowly scoped simulation functionality.

It implements its own protocol handling rather than requiring PySNMP as a runtime dependency.

Crucially, Trishul SNMP does not require Trishul SMI to perform numeric-OID operations.

Compiled MIB bundles are optional. When supplied, they add symbolic names and richer value interpretation.

This avoided making a simple polling request depend on a separate MIB compilation subsystem.

The architectural relationship is:

MIB source files
       |
       v
  Trishul SMI
       |
       v
 Versioned JSON bundles
       |
       | optional enrichment
       v
  Trishul SNMP <----> SNMP devices
       |
       v
 Consumer applications
Enter fullscreen mode Exit fullscreen mode

The runtime has deliberate limits. It isn't a full SNMP agent framework, and SET operations are outside its documented scope.

What changed for my projects?

The first major consumer was Trishul SNMP Suite.

Its 2.0 rewrite moved toward in-process SNMP operations and a shared compiled-MIB pipeline, instead of relying on the old subprocess-based arrangement.

Later, Trishul RAM adopted the same libraries after a staged interoperability and compatibility review.

An October 2026 local polling study measured a median GET operation of 93.9 ms on the legacy integration versus 3.0 ms on the Trishul integration. Much of that difference came from avoiding repeated PySNMP engine setup.

That was an operation-level result, not a 31× improvement in complete monitoring pipelines. End-to-end measurements were much closer.

The broader benefit was architectural: the same libraries could be reused without making each application solve compilation and runtime integration independently.

What didn't magically improve?

Writing your own implementation means becoming responsible for its failures.

Real-world vendor MIBs exposed grammar and dependency problems that small test fixtures missed. SNMPv3 interoperability exposed protocol mistakes that required live-agent testing.

And larger compiler benchmarks showed that Trishul SMI wasn't faster in every scenario. PySMI performed better for local offline JSON generation under the measured conditions.

Those limitations matter.

For my use cases, the most valuable outcome was not winning every performance comparison. It was having a reusable contract, clearer responsibilities and a foundation I could evolve across projects.

The lesson

Sometimes a dependency problem really is an architecture problem.

But rewriting a dependency should never be the default answer. It makes sense only when the repeated integration costs justify the long-term maintenance responsibility.

For my projects, separating MIB knowledge from SNMP execution turned out to be that boundary.

What would you choose for a network-management platform: compiled Python MIB modules, a portable JSON schema, or runtime MIB parsing?

The longer engineering origin story is available at Trishul Developers.

Editorial disclosure: This article was prepared with AI writing assistance and checked against public project documentation. The engineering decisions and projects described are my own.

Top comments (0)