Senior Backend Developer — Qom, Iran
👋 Nice to meet you. I'm a senior backend developer based in QOM, IRAN with 6+ YEARS in .NET & C#. I design DISTRIBUTED EVENT-DRIVEN services on Azure that stay RELIABLE at scale.
Bet Technology — Senior Backend Developer · 5 yrs
Distributed .NET microservices on Microsoft Azure — built for high-throughput, reliability-critical workloads, with MongoDB in production.
Each service owns its data and publishes events instead of reaching across boundaries — so services stay independent, deployable, and easy to evolve.
public sealed class OrderService : IOrderService { public async Task<Result> PlaceAsync(Order order, CancellationToken ct) { await _repo.SaveAsync(order, ct); // hand off across the boundary via an event await _bus.PublishAsync(new OrderPlaced(order.Id), ct); return Result.Ok(); } }
Thin, explicit endpoints with model validation handled up front — controllers stay free of plumbing and intent reads clearly.
var group = app.MapGroup("/orders").WithTags("Orders"); group.MapPost("/", async (PlaceOrder cmd, IOrderService svc, CancellationToken ct) => { var result = await svc.PlaceAsync(cmd.ToOrder(), ct); return result.IsSuccess ? Results.Accepted() : Results.BadRequest(result.Error); });
Write-through plus a short TTL keeps hot reads off the database without serving stale data on the paths that matter.
public async Task<Order> GetAsync(string id, CancellationToken ct) { if (_cache.TryGet(id, out Order hit)) return hit; var order = await _repo.FindAsync(id, ct); _cache.Set(id, order, _ttl); // short TTL, write-through return order; }
One place maps failures to responses, so handlers throw domain errors and clients always get a consistent problem shape.
app.UseExceptionHandler(handler => { handler.Run(async ctx => { var ex = ctx.Features.Get<IExceptionHandlerFeature>()?.Error; var problem = ex.ToProblemDetails(); ctx.Response.StatusCode = problem.Status ?? 500; await ctx.Response.WriteAsJsonAsync(problem); }); });
Services react to messages on Azure Service Bus rather than calling each other directly — decoupled, resilient, and replayable.
await processor.StartProcessingAsync(ct); processor.ProcessMessageAsync += async args => { var evt = args.Message.Body.ToObjectFromJson<OrderPlaced>(); await _handler.HandleAsync(evt, args.CancellationToken); await args.CompleteMessageAsync(args.Message); // at-least-once };
Documents are shaped around read patterns, with indexes on the fields that drive queries — modeling for how data is actually used.
var keys = Builders<Order>.IndexKeys .Ascending(o => o.CustomerId) .Descending(o => o.CreatedAt); await _orders.Indexes.CreateOneAsync( new CreateIndexModel<Order>(keys), ct: ct); var recent = await _orders .Find(o => o.CustomerId == id) .SortByDescending(o => o.CreatedAt) .Limit(20).ToListAsync(ct);
Check the cache, fall back to Mongo on a miss, then populate — keeping p95 latency low under heavy read load.
var cached = await _cache.GetAsync(key, ct); if (cached is not null) return cached; var doc = await _mongo .Find(x => x.Id == id) .FirstOrDefaultAsync(ct); await _cache.SetAsync(key, doc, _ttl, ct); // cache-aside return doc;
Environment-specific settings live in config, not code — so a release is a configuration change, reviewed and reversible.
// appsettings.Production.json { "ServiceBus": { "MaxConcurrentCalls": 16 }, "Mongo": { "MaxPoolSize": 200 }, "Cache": { "TtlSeconds": 30 }, "FeatureFlags": { "NewPricing": true } }
Services that can't drop traffic. I lean on scalable distributed design on Azure, careful data modeling, and caching on the paths that matter — so the system stays responsive under load.
Microservices live or die on their seams. I work through domain boundaries and event-driven messaging so services stay independent, deployable, and able to evolve without a cascade of breakage.
You can't fix what you can't see. I push on observability and resilience — instrumentation, sensible failure modes, and operational stability — so issues are caught early and recovered fast.
Began a BSc in Telecommunications Engineering at Shahab Danesh University — systems thinking, networks, and the math behind reliable communication.
Earned the degree and joined Rahyab Telecom as a Backend Developer — .NET & C# on business-critical systems, APIs, integrations, caching, and the debugging that keeps production stable.
Joined Bet Technology — designing and owning .NET microservices on Azure: architecture decisions, release readiness, code review, and hands-on work across core services.
6+ years in. Distributed, event-driven systems on Azure with MongoDB in production — and looking for the next backend challenge where system design and ownership matter.
“Clean code and clear ownership beat cleverness — systems get read and maintained far more than they get written.
“Pragmatic practices over dogma. The goal is a team that can deliver and evolve complex systems without fear.
“Good backend work is cross-functional — partnering with frontend, product, and DevOps to ship end-to-end.
Swap these for real LinkedIn recommendations (name · role · photo) when you have them.
Open to senior backend roles & contracts
© 2026 Oveis Kabuli · Senior Backend Developer · Qom, Iran