networking · distributed systems · developer infrastructure
I build systems that move packets, events, and memory.
Mostly I rebuild things that already exist — a BGP speaker, a memory store for
AI agents, an image server with no dependencies — because reading the RFC is not
the same as making the bytes come out right. A few of them ended up in production.
I work at the seams — where software meets a protocol, a disk, or an operator
at three in the morning. That is where the interesting failures live, and it is
usually where the documentation stops.
Before I add a retry, I want to know exactly how the thing breaks. Most of what
I build started as a question I could not answer by reading.
Prefer
+boring technology that has already failed in public
+code written to be read twice and changed once
+immutability by default, init over setters
+observability before optimisation
+the RFC, not the blog post about the RFC
+one word per concept — entity, service, endpoint, column
Avoid
−complexity that arrived together with the hype
−abstractions written before the third caller exists
−implicit behaviour, however clever
−a framework where the standard library would do
−vocabulary that means less the closer you look
On the benchMCP agent memory (Nectom) · BGP feed provider · Roslyn analyzers for ASP.NET Core · zero-dependency Go services
Background10+ years, enterprise and independent · Russia, remote-friendly
02Work
01networking · .net 10 · 2025 — now · production
BGPLite
A BGP-4 route server, written from scratch.
I wanted to understand BGP without reading someone else's implementation, so I
wrote my own. It runs at bgp.vhex.dev
as AS 65444 and peers with BIRD, FRR, MikroTik, Cisco and Juniper — which is the
only test that really counts.
rfc
4271 · 4724 graceful restart · 8092 large communities
A regulated-industry platform, as event-driven microservices.
The kind of system where a modelling mistake turns into a compliance problem.
Auditability and data integrity were requirements, not chores. Co-architected
end to end, from the domain model to the CI that shipped it.
domain
DDD and CQRS on MediatR, roughly 60 handlers
messaging
RabbitMQ and Azure Service Bus behind one abstraction
Every coding agent forgets everything between sessions, and each one wants its
own store. Nectom is a single memory service that Claude Code, Cursor, Gemini
and Codex all read and write — over REST and over MCP. One memory, any tool.
shape
hexagonal, with ports for storage and embeddings
retrieval
pgvector in PostgreSQL, next to the metadata it belongs to
embeddings
strategy-based providers — Ollama or OpenAI-compatible
Curated BGP prefix feeds by AS or by country, delivered over eBGP. A commercial layer on top of BGPLite.
SSRF-hardened via ConnectCallback host pinning
03Notes
Decisions I had to argue myself into, and the ones I still can't close.
Why a hand-written BGP codec on Span<byte>?
context
The wire format is fixed by RFC 4271. Nothing about it is going to change.
decision
Parse directly off Span<byte> — no intermediate objects, no serializer.
trade-off
A much larger test surface. Worth it: here the codec is the domain.
Why pgvector instead of a dedicated vector database?
context
Nectom stores memories and their embeddings, and the two must never disagree.
decision
Keep both in PostgreSQL, in the same transaction.
trade-off
Lower raw QPS. In exchange: transactional joins, and one system to operate.
Why two message brokers behind one interface?
context
An enterprise platform split across an on-prem perimeter (RabbitMQ) and a cloud-bound workload (Azure Service Bus). Domain events had to flow through both without each service knowing which wire it was on.
decision
One IMessageBroker abstraction — publish/consume semantics, not transport features. Delivery guarantees, retry and DLQ live behind it; callers speak in integration events.
trade-off
The abstraction hides the transports' real differences (topic fanout vs. competing consumers, session locks, ordering). It pays off only if you refuse to leak either side's vocabulary through the interface — the moment a handler asks "am I on RabbitMQ?", the layer has failed.
Why no protobuf anywhere in BGPLite?
context
Everything around it speaks protobuf, so the question kept coming back.
decision
BGP already has a fixed binary layout. The RFC is the schema.
trade-off
No generated code to lean on — and nothing to keep in sync either.
Open questions
Things I have not solved. If you have, I'd genuinely like to hear about it.
Can exact-union CIDR aggregation stay incremental when withdrawals interleave with announcements? Today I rebuild the set, and I am not proud of it.
How do you demonstrate that a Graceful Restart implementation is correct, rather than merely not crashing? RFC 4724 describes behaviour, not evidence.
Where does pgvector stop being the right answer? The operational threshold — recall at scale, HNSW build cost, index rebuild behaviour under write load — is the next thing worth measuring before the store quietly becomes the wrong one.
Is there a way to write a protocol state machine in C# that a reviewer can check against the RFC line by line, without a code generator in the middle?
04Log
Trajectory, not a résumé.
2026
BGPLite in production — own BGP-4 codec, graceful restart, large communities
Nectom — shared MCP memory for agents, pgvector retrieval
Wrote How I Wrote a BGP Server and Didn't Lose My Mind — Habr · DEV.to
Zero-dependency Go services — image server, host monitoring
2023 — 24
Enterprise CRM/ERP — DDD and CQRS across 12 microservices
Internal libraries — event bus, tag mapper, GitLab client
Self-hosted GitLab and CI/CD for the whole platform
—Contact
Building something at the protocol or platform layer?
I'm most useful where systems get low-level, distributed, or both. Architecture
review, protocol work, distributed backends, AI infrastructure — all in scope.
Also happy to just argue about RFCs.