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 |
Go server.go + client.go = 13K+ combined |
| Protocol |
3 |
1,829 |
6 |
1,156 |
63% |
protocol.md |
Parser, wire protocol, constants |
| Subscriptions |
2 |
2,416 |
10 |
2,142 |
89% |
subscriptions.md |
Subject matching, trie, transforms |
| Auth & Accounts |
5 |
7,260 |
41 |
3,445 |
47% |
auth-and-accounts.md |
.NET includes Imports/ (12 files, 264 LOC) |
| Configuration |
3 |
1,871 |
12 |
4,559 |
244% |
configuration.md |
.NET exceeds Go; includes rich config parsing |
| Routes |
1 |
3,314 |
3 |
1,139 |
34% |
routes.md |
Cluster full-mesh routing |
| Gateways |
1 |
3,426 |
6 |
1,368 |
40% |
gateways.md |
Inter-cluster bridges |
| Leaf Nodes |
1 |
3,470 |
5 |
1,553 |
45% |
leaf-nodes.md |
Hub-and-spoke edge topology |
| JetStream |
20 |
55,228 |
68 |
16,630 |
30% |
jetstream.md |
Largest module; see breakdown below |
| RAFT |
1 |
5,037 |
20 |
3,045 |
60% |
raft.md |
Consensus protocol |
| MQTT |
1 |
5,882 |
10 |
1,853 |
31% |
mqtt.md |
MQTT protocol adapter |
| WebSocket |
1 |
1,550 |
8 |
1,531 |
99% |
websocket.md |
Near-complete |
| Monitoring |
2 |
4,396 |
15 |
2,308 |
53% |
monitoring.md |
HTTP endpoints (/varz, /connz, etc.) |
| Events |
2 |
4,133 |
5 |
1,642 |
40% |
events.md |
System events, message tracing |
| TLS / Security |
12 |
4,207 |
7 |
516 |
12% |
tls-security.md |
OCSP, certs, ciphersuites, proxy proto |
| Internal DS |
34 |
4,020 |
7 |
4,225 |
105% |
internal-ds.md |
AVL, stree, THW, GSL, PSE, sysmem |
| Logging |
4 |
936 |
0 |
0 |
-- |
logging.md |
.NET uses Microsoft.Extensions.Logging |
| Utilities & Other |
19 |
3,282 |
3 |
244 |
7% |
utilities-and-other.md |
Ring, sendq, errors, ats, elastic, tpm |
| Misc / Uncategorized |
1 |
660 |
6 |
70 |
-- |
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.