Skip to content
Kien

Hi, I'm

Kien Nguyen Trung

Technical Lead · Software Engineer

Hanoi, Vietnam

Kien Nguyen Trung

Software engineer and technical lead, backend-heavy but at home across the stack. I build the layer in the middle: services that fan one request out to dozens of third-party APIs, keep the answers correct under load, and hide the mess from everyone downstream. Distributed systems, integration at scale, and the tooling a team needs to debug it at three in the morning.

  • 4.5

    years across backend, frontend & DevOps

  • 42

    runbook commands I wrote for the team

  • ~150

    live third-party integrations

  • 6

    engineers on the team I lead

Leading an engineering teamSprint planning & estimationHiring, interviews & onboardingTechnical roadmapMulti-repo release trainsProduction incident responsePartner-facing technical communicationCross-team API contractsTeam AI runbooksCode review & mentoringAPI contract designIdentity & state modellingLive migration planningFailure-domain isolationModule boundaries & enforced contractsComposite identifiers over sessionsTypeScriptJavaScriptPythonGoSQLNestJSKoaExpressFastAPISupplier adapters (Python / Go)Microservices & horizontal scalingMulti-supplier aggregationGDS / NDC flight flowsSOAP / XML supplier APIsWebhooks & status reconciliationHotel / flight / tour / transfer / carMySQLPostgreSQLMongoDBSQL ServerRedisNeo4jElasticsearch

About

I'm Kien, a software engineer in Hanoi, currently technical lead on a team of six. For four years I've been working on one problem wearing different costumes: making a lot of systems that disagree with each other behave like one.

That sentence sounds tidy. The hard part is everything around it. Partners identify the same real-world thing by different codes, so somewhere there has to be an identity table — mine is around 1.9 million rows — and a defensible way to bridge between them. The request that actually leaves your service is assembled at runtime from cache, per-account config and third-party credentials, so when an incident arrives carrying nothing but a trace-id, guessing is not a strategy: you need tooling that rebuilds the exact request you sent. And a change that touches money can span eleven repositories at once, where missing one of them costs real money and throws no exception anywhere.

The work I'm proudest of is rarely a feature. It's the audit that found the case nobody had tested, the tool that turned a two-hour ritual into one command, or the refactor that let a service stop falling over at 3 GB. I turn repeated procedures into shared tooling, and I write down what I could not verify.

Outside work: music, travelling, and the gym.

Projects

Systems I built and kept running

View all

05/2024 – present · Designed the supplier module contract and the migration model; owns the release train on the hotel gateway

The aggregation layer that makes many wholesalers answer one API contract: one module per supplier, brand differences pushed into data, and cross-call state carried inside the identifiers themselves.

  • 75

    supplier codes on 31 modules

  • 8

    gateway services

  • 5

    product lines on one contract

  • Node.js
  • Koa 2
  • Express 4
  • MySQL + Knex
  • Redis (ioredis)
  • AWS SQS
  • +5
Live demo

02/2026 – present · Author and maintainer — solo

~70 engineering runbooks packaged as executable commands across 3 installable repos used by two teams — with mechanised guardrails on every operation that touches production.

  • ~70

    executable runbooks

  • 3

    installable repos

  • 9

    MCP servers, per-tool scoped

  • 6

    subagent roles

  • Claude Code skills & plugins
  • MCP (9 servers)
  • Bash
  • Python 3
  • Node.js
  • macOS launchd
  • +2
Live demo

2026 · Owner of the mapping campaigns — design, execution, verification, rollback

Resolving the same physical hotel across suppliers in a ~1.9M-row identity table — using a bridge-through-a-third-supplier technique, verified by name similarity and geo distance before any write.

  • 1.9M

    rows in the identity table

  • +109,786

    rows written in the largest campaign

  • 94.9%

    mean name similarity

  • 11,953

    rows deliberately rolled back

  • Node.js
  • MySQL + Knex
  • Redis
  • Neo4j + Cypher
  • Python (TF-IDF, Siamese)
  • fuzzball
  • +1
Live demo

08/2026 · Sole author, rolled out to four further services

Two design calls — snapshot the request at the first handler line, before any code mutates it, and derive the field table from each endpoint's own validation schema — made the tool portable enough to ship across all five products in a single day.

  • 5

    products, shipped the same day

  • 44–75%

    smaller payload than JSON

  • ~626K

    search log rows in production

  • Node.js
  • Koa
  • Express
  • MySQL + Knex
  • Redis
  • Joi
  • +2
Live demo

Now

What is on the desk this quarter

  • Leading a 6-engineer team through a multi-repo release train — a single go-live can span 11 repositories.
  • Writing supplier-integration adapters in Python (FastAPI) and Go, alongside the daily Node.js/TypeScript stack.
  • Keeping ~90 supplier integrations (~150 supplier codes) alive across hotel, flight, tour, transfer and car hire.
  • Iterating on two team AI runbook packs — 42 slash commands, 5 scheduled headless jobs.

09/2026

Open source

Claims you can npm-install

@kien2k1/multi-channel-alert

One call fans an alert out to Telegram and the other channels you wire in. Extracted from alerting code I kept rewriting at work — published so I would stop rewriting it.

How I work

The rules the lessons left behind

Counts, not adjectives

If a claim can't be re-derived by counting, it doesn't go on this site or on a slide. "~90 integrations" survives an audit; "huge scale" doesn't.

Label the blast radius

Every command in the team's runbook packs carries a 🟢🟠🔴 label in the index, before anyone runs it. Knowing what a command can break is cheaper than finding out.

Ship the train, not the wagon

When a go-live spans 11 repositories, the unit of release is the set, not the repo. The merge order is part of the design.

Logs are the product too

With ~150 supplier codes upstream, a booking you can't trace is a booking you can't defend. The command that rebuilds an upstream request from one trace-id exists because the logs were written to make it possible.

Lessons

A real problem, what it cost, and what I changed

View all

· 4 min read

Two schedulers end up managing the same workload and neither knows the other exists. The concurrency nobody chose, a memory limit that belongs to the cgroup, and a crash loop hiding inside a pod that reports itself healthy — and why the fix is to pick one layer and let it do the multiplying.

  • Kubernetes
  • Node.js
  • PM2
  • operations

· 4 min read

A support ticket: searching one destination returns no hotels while the regions around it are fine. Nothing was down — the destination existed twice in the mapping data and the hotels hung off the other row. The fix became a runbook command that has to count the results before it may say "fixed".

  • data quality
  • debugging
  • observability
  • runbooks

· 5 min read

Two teams, two companies, ~40 AI slash commands. What changed was not the automation — it was that a runbook and the tool that runs it finally became the same file, and that every dangerous one had to declare itself.

  • AI tooling
  • Claude Code
  • developer experience
  • documentation

Skills

Technical leadership

  • Leading an engineering team
  • Sprint planning & estimation
  • Hiring, interviews & onboarding
  • Technical roadmap
  • Multi-repo release trains
  • Production incident response
  • Partner-facing technical communication
  • Cross-team API contracts
  • Team AI runbooks
  • Code review & mentoring

Architecture & design

  • API contract design
  • Identity & state modelling
  • Live migration planning
  • Failure-domain isolation
  • Module boundaries & enforced contracts
  • Composite identifiers over sessions

Languages

  • TypeScript
  • JavaScript
  • Python
  • Go
  • SQL

Backend frameworks

  • NestJS
  • Koa
  • Express
  • FastAPI
  • Supplier adapters (Python / Go)
  • Microservices & horizontal scaling

Integration

  • Multi-supplier aggregation
  • GDS / NDC flight flows
  • SOAP / XML supplier APIs
  • Webhooks & status reconciliation
  • Hotel / flight / tour / transfer / car

Databases

  • MySQL
  • PostgreSQL
  • MongoDB
  • SQL Server
  • Redis
  • Neo4j
  • Elasticsearch

Message queues

  • AWS SQS
  • Apache Kafka
  • RabbitMQ
  • BullMQ

UI & frontend

  • React 19
  • Next.js
  • Redux
  • Ant Design
  • MaterialUI
  • Tailwind CSS
  • Recharts
  • SCSS
  • Figma

Platform & monitoring

  • Docker
  • Kubernetes
  • Linux
  • GitLab CI
  • DataDog
  • Sentry
  • Grafana + Loki
  • Kibana
  • CloudWatch
  • New Relic

Worked with

  • Spring Boot
  • Laravel
  • Flask
  • Apache Spark
  • Hadoop
  • Scala
  • AWS Athena

Writing

Engineering notes from real systems

View all

· 4 min read

In most systems the expensive test outcome is red. In a booking system it is green — a passing test just bought something. How the full flow gets tested anyway: a selection rule that doubles as the safety mechanism, and an evidence pack, not a checkmark, as the thing partners actually review.

  • testing
  • integrations
  • QA
  • evidence

· 4 min read

Eight gateway services, one shared integration branch, and a promotion to production that is a deliberate, batched act with a human at the button. What "the unit of release is the set, not the repo" looks like when it has to run every week instead of sitting in a principles list.

  • release engineering
  • multi-repo
  • process
  • CI/CD

· 9 min read

Not "AI writes my code". The useful part was turning ~70 procedures that lived in one person's head into commands anyone can run, with the dangerous ones labelled and gated. Here is the shape of it, in numbers I can actually count.

  • AI tooling
  • Claude Code
  • developer experience
  • automation

Photos

Travel, work, and the moments in between

View all

Contact

Drop me a line — I answer as soon as I can.