Vasil Kosturski
On software and technology
I’m a Software Architect with over 15 years of experience. As a Senior Principal Engineer at Smartsheet, I lead the AI Ecosystem domain, with a focus on agentic integrations and MCP. Before that, I spent over a decade designing large-scale distributed systems, most recently event streaming for live sports data at Sportradar. Here I write long-form deep dives into how systems like these work under the hood.
Latest

Generation Got Cheap, Trust Didn’t: A Multi-Agent Trading System with Guardrails and Traceability
Generation got cheap, trust didn’t. How a 4-trader multi-agent system uses output guardrails and per-run audit trails to close the verification gap.
How Smartsheet built a remote MCP server on AWS
Distributed Tracing Demo with OpenTelemetry and Grafana Cloud
Monitoring Kafka in Kubernetes with Prometheus and Grafana
Leader Election and Failover with Zookeeper – Case Study
Unit and Integration Testing in Apache Flink
AWS Data Lake: Handling News Data Stream via Firehose C# Client, Athena, Glue, and MySQL RDS
Series
- Exploring the async/await state machine
How the C# compiler turns an async method into a state machine, from the awaitable pattern to synchronization contexts, ConfigureAwait and stack traces.
7 parts- Part 1: Exploring the async/await State Machine – The Awaitable Pattern
- Part 2: Exploring the async/await State Machine – Main Workflow and State Transitions
- Part 3: Exploring the async/await State Machine – Conceptual Implementation
- Part 4: Exploring the async/await State Machine – Concrete Implementation
- Part 5: Exploring the async/await State Machine – Synchronization Context
- Part 6: Exploring the async/await State Machine – Nested Async Calls and ConfigureAwait(false)
- Part 7: Exploring the async/await State Machine – Stack Traces and Refactoring Pitfalls
- Clash of Styles
Programming paradigms side by side: one problem solved with object-oriented C# and with functional F#, and what each style makes easy or hard to extend.
6 parts- Part 1: Clash of Styles, Part #1 – Operations Matrix via OOP
- Part 2: Clash of Styles, Part #2 – Operations Matrix via FP
- Part 3: Clash of Styles, Part #3 – Extensibility via OOP and FP
- Part 4: Clash of Styles, Part #4 – Adding Support for Rational Numbers with FP
- Part 5: Clash of Styles, Part #5 – Double Dispatch, or When to Abandon OOP
- Part 6: Clash of Styles, Part #6 – FP in OOP via the Visitor Pattern
- Causal consistency guarantees
When eventual consistency is not enough: the causal guarantees, such as read your writes and monotonic reads, and how MongoDB provides them.
3 parts - Node.js microservices on AWS EKS
Node.js microservices deployed to Kubernetes on AWS EKS with a Travis CI pipeline, built for Udacity's Cloud Developer Nanodegree.
3 parts - GraphQL social media demo
A small social network built end to end with GraphQL: a Node and Apollo server and a React client.
2 parts - .NET scheduled tasks on AWS Fargate
Running a containerized .NET console app on a schedule as an AWS Fargate task.
2 parts
Writing by topic
.NET & languages
26 posts- GraphQL, Node, Apollo and React (Social Media Demo Project) – Part 2
- GraphQL, Node, Apollo and React (Social Media Demo Project) – Part 1
- Exploring the async/await State Machine – Stack Traces and Refactoring Pitfalls
- Exploring the async/await State Machine – Nested Async Calls and ConfigureAwait(false)
- Exploring the async/await State Machine – Synchronization Context
- Exploring the async/await State Machine – Series Overview
- Exploring the async/await State Machine – Concrete Implementation
- Exploring the async/await State Machine – Conceptual Implementation
- Exploring the async/await State Machine – Main Workflow and State Transitions
- Exploring the async/await State Machine – The Awaitable Pattern
- The Intuitive Guide to Understanding Closures in C#
- Polymorphism on Steroids – Dive Into Multiple Dispatch (Multimethods)
- The “Clash of Styles” Series – FP vs. OOP as a Daily Choice
- Clash of Styles, Part #6 – FP in OOP via the Visitor Pattern
- Clash of Styles, Part #5 – Double Dispatch, or When to Abandon OOP
- Clash of Styles, Part #4 – Adding Support for Rational Numbers with FP
- Clash of Styles, Part #3 – Extensibility via OOP and FP
- Clash of Styles, Part #2 – Operations Matrix via FP
- Clash of Styles, Part #1 – Operations Matrix via OOP
- Course Review – “Programming Languages” Series on Coursera
- Don’t Help Your Clients to Deadlock
- The Dispose Pattern Step by Step
- A Practical Intro to Covariance and Contravariance in C#
- FirstOrDefault() is a Code Smell
- Avoid Conversion Operators
- GetHashCode() Pitfalls
Distributed systems
18 posts- Distributed Tracing Demo with OpenTelemetry and Grafana Cloud
- Monitoring Kafka in Kubernetes with Prometheus and Grafana
- Leader Election and Failover with Zookeeper – Case Study
- Unit and Integration Testing in Apache Flink
- The Outbox Pattern with Mongo, Kafka and Debezium in C#
- Kafka Messaging with Cloud Events, Protobuf, and Polymorphic Types
- Kafka Messaging with Protobuf and Schema Registry in C#
- Producing and Consuming Kafka Messages in CloudEvents Format Using the C# SDK
- Exploring Kafka Streams Partitioning, Scaling, and Fault Tolerance
- Integration Tests for your Kafka Producer with “Testcontainers” in C#
- Kafka Networking via Wireshark
- Exploring Kafka Listeners in Docker
- Monitoring Public Transportation with the Kafka Ecosystem (Demo Project)
- Should You Migrate Your Reporting Queries From a “General Purpose” DB (MongoDB) to a Data Warehouse (ClickHouse)? (Performance Overview)
- Causal Consistency Guarantees in MongoDB – Lamport Clock, Cluster Time, Operation Time, and Causally Consistent Sessions
- Causal Consistency Guarantees in MongoDB – “majority” Read and Write Concerns
- Causal Consistency Guarantees – Case Studies
- MongoDB Change Data Capture via Debezium Kafka Connector with a .NET 5 Client
Cloud
9 posts- AWS Data Lake: Handling News Data Stream via Firehose C# Client, Athena, Glue, and MySQL RDS
- AWS Site-to-Site VPN with strongSwan
- AWS RDS Replication and Recoverability
- Running Containerized .NET Scheduled Tasks with AWS Fargate – Part 2
- Running Containerized .NET Scheduled Tasks with AWS Fargate – Part 1
- Running NodeJS Microservices in Kubernetes using AWS EKS & Travis CI – Part 3
- Running NodeJS Microservices in Kubernetes using AWS EKS & Travis CI – Part 2
- Running NodeJS Microservices in Kubernetes using AWS EKS & Travis CI – Part 1
- Deploying Your Node API to AWS Using Elastic Beanstalk (Demo Project)
Data & ML
8 posts- Sentiment Analysis of Stocktwits Messages using LSTM in PyTorch
- TensorFlow Serving gRPC Endpoint in Docker with a .NET 5 Client
- Predicting English Premier Leagues Games Using Transfermarkt Market Values
- Predicting Football Clubs Winning Percentage in the English Premier League Using Pythagorean Expectation
- Making Predictions in C# with a Pre-Trained TensorFlow Model via ONNX
- Course Review – “Deep Learning Specialization” by Andrew Ng, DeepLearning.AI on Coursera
- Course Review – “Machine Learning” by Andrew Ng, Stanford on Coursera
- The Experienced Developer Stepping Into Machine Learning – Why and How?