ahmad.leo/yudanto

Senior Backend Engineer · Jakarta

Ahmad Leo Yudanto

I build backend systems that stay calm under load, so the people who run them can stay calm too.

Nearly ten years building and testing software, the last five in production backends for e-commerce and accounting SaaS. Started in QA, so I still think like a tester. Today I lead a promo squad on Klik Indomaret, one of Indonesia's largest grocery e-commerce platforms: about 90,000 orders on a normal day and up to 500,000 on campaign days.

k8s pods · catalog consumers 200 → 30
same traffic, 85% fewer pods
−85%Kubernetes pods on Kafka consumer services after fixing rebalancing (200 → 30)
90%+unit test coverage on every service in my scope, up from 0–15%
0weekends or overtime asked of my team across three promo launches
500korders a day on campaign peaks, 5× a normal day, on services I work on
Selected work

Three pieces of work I'm proud of

The catalog consumers kept rebalancing. Every rebalance paused the group, lag grew, and the answer had been to add pods. More pods meant more members joining and leaving, which meant more rebalancing. The cluster had grown to 200 pods and the lag was still there.

The root cause was consumers taking too long between polls and getting kicked out of the group, plus an out-of-memory crash that restarted pods mid-batch. I fixed the consumer, not the cluster:

# consumer, per topic
partition.assignment.strategy = StickyAssignor   # keep partitions on rebalance
max.poll.interval.ms          = ↑ raised         # slow batches no longer evicted
max.poll.records              = ↓ lowered        # smaller, predictable batches
ackMode                       = RECORD
concurrency                   = 1 thread per partition
  • Fixed the OOM in the consumer service so pods stopped restarting mid-batch.
  • Made consumption idempotent: a message already logged as processed is skipped, so retries are safe.
  • Added a dead-letter topic and moved heavy scheduled topics into their own application mode, so they stopped loading the main consumer group.

Same traffic, 30 pods, lag back under control, including campaign days that jump from about 90,000 to 500,000 orders. Nobody gets paged for it any more.

When I joined, most services had between 0 and 15% unit test coverage and no quality gate. I added JaCoCo and SonarQube to the existing CI/CD pipeline so every merge reports coverage, then brought the services in my scope above 90%.

The part I'm proudest of is how it stays there. I wrote our team's engineering rules as Markdown, then packaged them as AI skills: one writes tests to our conventions, one reviews pull requests and posts comments, one resolves test-file merge conflicts, and one debugs by reproducing a production issue in a unit test with real data first.

  • Everyone on my team now uses AI to write tests and debug, under the same written rules, so the output looks like ours.
  • Production issues on our services have dropped noticeably since tests became the default.
  • My SDET background is why this worked: I design the tests first and let the tooling fill them in.

Promotions are where e-commerce money goes wrong: one rule off and the cart gives away margin, or a customer is charged more than the shelf label says. I lead the squad that builds them.

  • Free Gift (Hadiah Gratis): a new promo type. Meet the condition and a free item joins the cart. New APIs for eligible gifts and add-to-cart, with stock handled so a gift never oversells. In its first year: 2.5 million orders with a gift and 6.5 million free items handed out.
  • Non-base to base migration: moved existing promotions onto the base promo model without breaking live campaigns.
  • Paired-product exclusion: removed paired products from specific promos, which touched pricing, strike-through labels and upsell logic across cart and catalog.

Every launch shipped on schedule, and nobody on the team worked a weekend for it. I plan for that on purpose: a team that isn't exhausted makes fewer mistakes in money logic.

Experience

From tester to the person who owns the backend

Jun 2025 – now

Senior Backend Engineer

EDTS · Klik Indomaret
  • Lead a three-person squad across promo, cart, catalog and order services: about 11 million orders a quarter, peaking at 500,000 a day.
  • 1,240 commits across 20 services in 16 months.
  • Kafka reliability work that cut consumer pods from 200 to 30.
  • Introduced unit testing, SonarQube quality gates and AI-assisted engineering for the team.
Spring Boot · PostgreSQL · Kafka · Redis · Elasticsearch · Kubernetes · GCP
Jan – May 2025

Career break

After a layoff, I studied Japanese full time, working through material up to N3, and sharpened data structures, algorithms and Kafka.

Dec 2019 – Dec 2024

Mekari · five years, three promotions

Indonesia's largest business SaaS: Jurnal accounting
Software Engineer 2 · 2024
Software Engineer 1 · 2021 – 2024
Senior SDET · 2021
SDET · 2019 – 2020
  • Built Jurnal's integrations: bank statements, e-commerce marketplaces, Moka POS transactions and supply chain. Took the integration issues nobody else wanted to touch and closed them.
  • As SDET, built and ran web and API automation covering 1,300+ web scenarios and 1,000+ API scenarios, plus JMeter load tests and the Jenkins pipeline around them. Mentored and interviewed new testers.
Java · Go · Ruby on Rails · Vue/Nuxt · Kafka · RabbitMQ · MongoDB · MySQL · AWS · ArgoCD · Datadog
2015 – 2019

Earlier

Automation testing at Blibli.com. Web and backend development at Gloding (Java Server Faces), Gumcode (Laravel APIs for iOS and Android) and PT Javan Cipta Solusi. B.Sc. Information Technology, Universitas Brawijaya.

Working with me

How I work best

For anyone I work with: what to expect from me, and what helps me do my best work.

What you can expect from me

  • I take the issue nobody wants.Old integrations, flaky consumers, unclear money logic. I like closing those.
  • Calm beats heroic.I'd rather spend a week making a system boring than spend every month firefighting it.
  • I protect my team's time.I scope and plan so launches land without weekends. Tired people write bugs.
  • I debug with real data.Production rows, logs and payloads go into a failing test first. Then I fix the line that's wrong.
  • I write things down.Team rules, conventions and runbooks live in Markdown, so people and AI tools follow the same playbook.

What helps me do my best work

  • Explain the business flow first.Once I understand why a promo or an order behaves the way it does, I move fast in the code.
  • Direct feedback.Tell me plainly when I'm wrong. I'll say my concern once, then commit to the decision.
  • Room to improve the tools.Some of my best results came from fixing how we work, not only what we ship.

How I lead

  • Safe to say what you think.On my team, anyone can raise a concern, disagree with me, or admit a mistake without it being held against them.
  • Hard conversations happen face to face.If I have feedback for you, you hear it from me directly and early. Nothing in a review should surprise anyone or leave them guessing who said it.
  • Merit over seniority or status.The best argument wins, whoever makes it. Title and tenure don't settle a technical decision.
  • Politics is not the main tool.I know it exists and I can work with it, but problems get solved with data and honest discussion first.
Toolbox

What I use day to day

Backend

Java 8–17 and Spring Boot (primary), Go, Ruby on Rails, Laravel

Messaging

Kafka (consumer tuning, DLQ, idempotency), RabbitMQ, Sidekiq

Data

PostgreSQL, MySQL, MongoDB, Redis, Elasticsearch

Platform

Kubernetes (GKE), Docker, GCP, AWS, ArgoCD, Jenkins

Quality

JUnit 5, Mockito, JaCoCo, SonarQube, Selenium, Cucumber, JMeter, Postman

Observability & AI

Datadog, Sentry, Zipkin, Claude Code with team-written skills

Contact

Say hello.

Happy to talk about Kafka, testing, promo engines or AI-assisted engineering. Email is the fastest way to reach me.

ahmadleoyudanto@gmail.com