Althaf Asard

Selected work from a hotel booking platform.

I worked across the product area used by guests, from React and Astro to backend services, search, booking, integrations, and AWS delivery.

Search was one part of the backend work.

I also worked on inventory, booking and payment flows, partner integrations, and cloud delivery. The listing path below changed as the catalogue and availability data grew.

04 / FINAL DESIGN

DMS to read models

The final design used DMS to feed two read models. Catalogue data moved through S3 and Lambda into Elasticsearch. Availability moved through Kinesis and Lambda into Valkey.

Source of truth
MySQL
Read model
Elasticsearch for catalogue filtering; Valkey for availability.
Sync or request path
Two sync paths with different update delays
MySQL feeds 2 independent read paths.
SOURCEMySQL
  1. Branch 01
    Catalogue pathDMS → S3 → Lambda
    OUTPUTElasticsearch
  2. Branch 02
    Availability pathDMS → Kinesis → Lambda
    OUTPUTValkey

MySQL remains the source of truth. Catalogue updates may arrive later; availability updates have a shorter delay.

WHY I CHANGED IT

Catalogue data could arrive later, while availability needed a shorter delay. Keeping the paths separate made the system easier for the team to maintain.

DMSLambdaElasticsearchValkey
HISTORICAL PRODUCTION CAPTURE

A historical capture recorded a 379.31 ms median.

Across 30 populated searches, latency measured in the browser was 379.31 ms at the median and 886.27 ms at p95. It was a single snapshot, not an SLA or a load test. The capture covered availability data for around 9,000 to 16,000 properties. The sample was not a sustained load or controlled A/B test.

379.31
median ms
StarRocks capture
886.27
p95 ms
browser observed
~ 9 to 16k
properties
availability coverage
02
INVENTORYSELECTED CONTRIBUTION

Inventory had to handle retries.

PROBLEM

Holds, partner changes, retries, expiry, and partial failures can happen together. The system needed one place to track the state.

WHAT I DID

Built a NestJS, Fastify, and MySQL inventory service with transactional holds, idempotent commit and cancel behaviour, compensation, immutable events, expiry and recovery jobs, and reconciliation.

OUTCOME

A transactional inventory boundary that kept retries and concurrent changes explicit.

NestJSFastifyMySQLTransactionsReconciliation
03
BOOKING + PAYMENTSELECTED CONTRIBUTION

One booking flow for every booking type.

PROBLEM

Direct, bid, and request and offer bookings could drift apart in pricing, payment state, and expiry.

WHAT I DID

Unified the cart and payment models, added authenticated asynchronous callbacks, and handled compensation and payments in multiple currencies across the client migrations.

OUTCOME

The server state machine became authoritative, so the workflow did not depend on a browser redirect.

Node.jsExpressPayment flowsWebhooksCompensation
04
ROOM ALLOCATIONSELECTED CONTRIBUTION

Moved room allocation into the main backend.

PROBLEM

The C++ room combination path made sense in the earlier design, but it was harder for the rest of the team to maintain after the search design changed.

WHAT I DID

Reimplemented the room allocation logic in Node.js with deterministic search, capacity accounting, pricing rules, and regression tests.

OUTCOME

The tested allocation rules were preserved, while the wider team could work in Node.js.

C++ to Node.jsConstraint searchDeterminismRegression tests
05
B2B INTEGRATIONSELECTED CONTRIBUTION

A partner integration that could absorb bursts.

PROBLEM

A channel manager integration needed to absorb bursts without making webhook receipt wait on downstream inventory writes.

WHAT I DID

Built an asynchronous Bakuun boundary with API Gateway, Lambda, and SQS FIFO, preserving ordering within each message group while failed messages could be handled separately.

OUTCOME

Partner updates were acknowledged and processed asynchronously while related updates remained ordered.

BakuunAPI GatewayLambdaSQS FIFO
06
CLOUD + HANDOVERSELECTED CONTRIBUTION

Cloud delivery and handover.

PROBLEM

Cloud services, derived stores, cache rules, and external integrations create context that can be easy to lose when one person leaves.

WHAT I DID

Worked across ALB, ECS on EC2, Aurora MySQL, ElastiCache Valkey, and Elasticsearch that we ran ourselves. Set up blue/green ECS deployments and AWS SAM workflows, then documented the system for handover.

OUTCOME

I left diagrams, runbooks, rebuild inputs, and a clear record of the system's limits.

ALBECSAurora MySQLAWS SAMRunbooks

Open to full stack work focused on backend systems.

I am looking for full stack work with a strong focus on backend systems. I work best on APIs, search, booking flows, data pipelines, and AWS.

Based in Sri Lanka. Available for my next role.

See how I work
AVAILABLE FOR FULL STACK AND AWS WORK2026