# LOC Comparison: Go Reference vs .NET Port > Generated 2026-02-25 (gap inventory populated). Lines of code counted with `wc -l` (includes blanks and comments). ## Summary | Metric | Go | .NET | .NET / Go | |--------|---:|-----:|----------:| | **Source files** | 123 | 249 | 2.0x | | **Source LOC** | 134,140 | 51,303 | 38% | | **Test files** | 127 | 562 | 4.4x | | **Test LOC** | 260,730 | 165,630 | 64% | | **Total files** | 250 | 811 | 3.2x | | **Total LOC** | 394,870 | 216,933 | 55% | The .NET port has **more files** (smaller, focused C# files vs Go's monolithic files) but **fewer total lines**. Source code is at 38% of Go LOC. Test code is at 64% of Go LOC. The higher file count reflects C#'s convention of one class/type per file. --- ## Source Code by Functional Area | Functional Area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go | Detail File | Notes | |-----------------|:--------:|-------:|:----------:|----------|--------:|-------------|-------| | Core Server | 10 | 21,223 | 13 | 3,597 | 17% | [core-server.md](core-server.md) | Go `server.go` + `client.go` = 13K+ combined | | Protocol | 3 | 1,829 | 6 | 1,156 | 63% | [protocol.md](protocol.md) | Parser, wire protocol, constants | | Subscriptions | 2 | 2,416 | 10 | 2,142 | 89% | [subscriptions.md](subscriptions.md) | Subject matching, trie, transforms | | Auth & Accounts | 5 | 7,260 | 41 | 3,445 | 47% | [auth-and-accounts.md](auth-and-accounts.md) | .NET includes Imports/ (12 files, 264 LOC) | | Configuration | 3 | 1,871 | 12 | 4,559 | 244% | [configuration.md](configuration.md) | .NET exceeds Go; includes rich config parsing | | Routes | 1 | 3,314 | 3 | 1,139 | 34% | [routes.md](routes.md) | Cluster full-mesh routing | | Gateways | 1 | 3,426 | 6 | 1,368 | 40% | [gateways.md](gateways.md) | Inter-cluster bridges | | Leaf Nodes | 1 | 3,470 | 5 | 1,553 | 45% | [leaf-nodes.md](leaf-nodes.md) | Hub-and-spoke edge topology | | **JetStream** | **20** | **55,228** | **68** | **16,630** | **30%** | [jetstream.md](jetstream.md) | Largest module; see breakdown below | | RAFT | 1 | 5,037 | 20 | 3,045 | 60% | [raft.md](raft.md) | Consensus protocol | | MQTT | 1 | 5,882 | 10 | 1,853 | 31% | [mqtt.md](mqtt.md) | MQTT protocol adapter | | WebSocket | 1 | 1,550 | 8 | 1,531 | 99% | [websocket.md](websocket.md) | Near-complete | | Monitoring | 2 | 4,396 | 15 | 2,308 | 53% | [monitoring.md](monitoring.md) | HTTP endpoints (/varz, /connz, etc.) | | Events | 2 | 4,133 | 5 | 1,642 | 40% | [events.md](events.md) | System events, message tracing | | TLS / Security | 12 | 4,207 | 7 | 516 | 12% | [tls-security.md](tls-security.md) | OCSP, certs, ciphersuites, proxy proto | | Internal DS | 34 | 4,020 | 7 | 4,225 | 105% | [internal-ds.md](internal-ds.md) | AVL, stree, THW, GSL, PSE, sysmem | | Logging | 4 | 936 | 0 | 0 | -- | [logging.md](logging.md) | .NET uses Microsoft.Extensions.Logging | | Utilities & Other | 19 | 3,282 | 3 | 244 | 7% | [utilities-and-other.md](utilities-and-other.md) | Ring, sendq, errors, ats, elastic, tpm | | Misc / Uncategorized | 1 | 660 | 6 | 70 | -- | [misc-uncategorized.md](misc-uncategorized.md) | | | **TOTAL** | **123** | **134,140** | **249** | **51,303** | **38%** | | | ### JetStream Breakdown | JetStream Sub-area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go | |--------------------|:--------:|-------:|:----------:|----------|--------:| | Core (orchestration, API, stream, consumer, store) | 10 | 28,150 | 5 | 1,656 | 6% | | API handlers | -- | (in Core) | 13 | 2,011 | -- | | Consumers | -- | (in Core) | 10 | 2,147 | -- | | Models | -- | (in Core) | 4 | 230 | -- | | Publish | -- | (in Core) | 5 | 639 | -- | | MirrorSource | -- | (in Core) | 2 | 1,085 | -- | | Snapshots | -- | (in Core) | 1 | 210 | -- | | Validation | -- | (in Core) | 1 | 60 | -- | | Storage (filestore, memstore, dirstore) | 9 | 16,191 | 19 | 6,254 | 39% | | Cluster (jetstream_cluster.go) | 1 | 10,887 | 8 | 2,338 | 21% | | **JetStream Total** | **20** | **55,228** | **68** | **16,630** | **30%** | Go consolidates JetStream into a few massive files: `consumer.go` (~6K), `jetstream_api.go` (~5K), `stream.go` (~8K), `filestore.go` (~12K), `jetstream_cluster.go` (~11K). The .NET port decomposes these into smaller, focused files. --- ## Test Code by Functional Area | Functional Area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go | |-----------------|:--------:|-------:|:----------:|----------|--------:| | Core Server | 7 | 18,011 | 173* | 25,024* | 139%* | | Protocol | 5 | 2,020 | 4 | 1,433 | 71% | | Subscriptions | 2 | 2,711 | 8 | 1,211 | 45% | | Auth & Accounts | 6 | 15,448 | 26 | 10,170 | 66% | | Configuration | 3 | 5,281 | 12 | 8,237 | 156% | | Routes | 1 | 5,041 | 18 | 6,025 | 120% | | Gateways | 1 | 7,667 | 17 | 5,914 | 77% | | Leaf Nodes | 2 | 11,778 | 22 | 7,238 | 61% | | JetStream (all) | 22 | 105,284 | 160 | 65,314 | 62% | | RAFT | 3 | 6,140 | 33 | 9,154 | 149% | | MQTT | 3 | 9,793 | 25 | 5,953 | 61% | | WebSocket | 1 | 4,982 | 13 | 2,590 | 52% | | Monitoring | 1 | 6,603 | 19 | 5,989 | 91% | | Events | 2 | 9,344 | 8 | 3,091 | 33% | | NoRace / Stress | 2 | 12,009 | 3 | 2,342 | 20% | | Internal DS | 7 | 3,557 | 6 | 3,837 | 108% | | Integration (test/) | 35 | 29,812 | -- | -- | -- | | Other / Misc | 14 | 2,904 | 14 | 2,058 | 71% | | **TOTAL** | **127** | **260,730** | **562** | **165,630** | **64%** | *\* The .NET "Core Server" root test directory (173 files, 25,024 LOC) contains mixed-purpose tests spanning multiple functional areas (server lifecycle, client protocol, pubsub, integration). Not directly comparable to the Go "Core Server" test files.* ### JetStream Test Breakdown | JetStream Test Area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go | |---------------------|:--------:|-------:|:----------:|----------|--------:| | Core tests | 9 | 42,582 | 50* | 14,824* | 35% | | Storage tests | 4 | 16,930 | 32 | 14,672 | 87% | | Cluster tests | 8 | 43,426 | 41 | 24,737 | 57% | | Consumer tests | -- | (in Core) | 22 | 7,701 | -- | | API tests | -- | (in Core) | 9 | 2,162 | -- | | Other (mirror, snap, stream) | -- | (in Core) | 6 | 1,918 | -- | | Benchmark | 1 | 2,346 | -- | -- | -- | | **JetStream Test Total** | **22** | **105,284** | **160** | **65,314** | **62%** | *\* JetStream root-level test files not in a named subdirectory.* --- ## Areas Where .NET Exceeds Go LOC | Area | Go LOC | .NET LOC | Ratio | Explanation | |------|-------:|----------|------:|-------------| | Configuration | 1,871 | 4,559 | 2.4x | Richer config parser with lexer/token model | | Internal DS | 4,020 | 4,225 | 1.05x | Full parity on AVL, stree, THW, GSL | | WebSocket | 1,550 | 1,531 | 0.99x | Near-identical coverage | --- ## Largest Gaps (Source LOC) | Area | Go LOC | .NET LOC | Gap (LOC) | .NET/Go | |------|-------:|----------|----------:|--------:| | Core Server | 21,223 | 3,877 | 17,346 | 18% | | JetStream Core | 28,150 | 8,038 | 20,112 | 29% | | JetStream Storage | 16,191 | 6,254 | 9,937 | 39% | | JetStream Cluster | 10,887 | 2,338 | 8,549 | 21% | | Auth & Accounts | 7,260 | 3,445 | 3,815 | 47% | | MQTT | 5,882 | 1,853 | 4,029 | 31% | | Monitoring | 4,396 | 2,308 | 2,088 | 53% | | Events | 4,133 | 1,642 | 2,491 | 40% | | TLS / Security | 4,207 | 516 | 3,691 | 12% | | Utilities & Other | 3,282 | 244 | 3,038 | 7% | --- ## Notes - **LOC counts include blank lines and comments.** Go tends to be more verbose with explicit error handling; C# uses exceptions and has less boilerplate per line. A 1:1 LOC ratio is not the goal. - **Go's monolithic files vs .NET's granular files.** Go's `client.go` is 6,700+ lines; the .NET equivalent is split across `NatsClient.cs`, `ClientFlags.cs`, `ClientKind.cs`, `INatsClient.cs`, etc. File count comparisons favor .NET. - **Go `test/` directory** (35 files, 29,812 LOC) contains integration/acceptance tests with no direct .NET equivalent directory; .NET integration tests are spread across subdirectories. - **Go `norace_*_test.go`** files (12,009 LOC) contain long-running race-condition tests that cross multiple subsystems. .NET equivalents are in `Stress/` (2,342 LOC). - **Configuration .NET > Go** because .NET implements a full lexer/parser/token pipeline for the NATS config format rather than using Go's simpler approach. - **.NET Logging = 0 LOC** because it uses `Microsoft.Extensions.Logging` + `Serilog` as NuGet packages rather than custom logging code. - **Internal Data Structures .NET >= Go** — the AVL, subject tree, time hash wheel, and GSL implementations are at or above Go parity.