Skip to content
JAEWON CHANGSystems Dossier
Language
Skip to the work index

Software Engineer — the frontend of a 4M DAU service, and the delivery path behind it

Scroll

The bill arrived with the code

I was writing frontend code for a service used by millions when the egress bill and the pager started landing on my desk as well. From then on I read the segments outside the viewport too — CDN, cache, servers, deploys, data.

Every figure here is a second measurement

I don't narrow a problem by intuition. I split it into segments with logs and events, find where the seconds and the bytes leak, change the structure, then measure the same metric again.

An LLM is one more system to verify

Not something special. Responses are checked against a schema, and quality is re-measured by replaying real sessions.

Nudge Healthcare · 2024 · Cache optimisation
Daily network transfer

235GB/day

Cache keys and invalidation re-cut to how each resource changes, and a Service Worker took repeat requests off the network.

−43.6% · egress cost down over 30%
Nudge Healthcare · 2024 · Ad data platform

Seven events from request to click, defined and collected, then BigQuery to name the bottleneck. Then the bundle and the ad script changed places.

P90 ad load4–5s → 2–3s
Click-through rate+30%
Revenue on that placement+20%

Faster meant more seen, more seen meant more clicked, more clicked meant more revenue. All three were verified in sequence.

Scale operated
Requests / month

253M

Transfer / month

4.27 TB

Image delivery on CloudFront and Lambda@Edge. A different measurement from the cache figures above; the two are never summed.

Affiliate community codebases

1 10+

Ten-plus folded into one multi-tenant service, migrated one DNS record at a time. Maintenance headcount settled at about 20% of before.

Work Index

  1. 01Ten-plus affiliate communities folded into one multi-tenant service2024 – 2025The same feature was being built in more than ten places at once. I merged them into one codebase and cut traffic over one DNS record at a time.10+ codebases → 1 · maintenance headcount at ~20%
  2. 02Rebuilding the CloudFront and browser cache path for a 43.6% cut in daily transfer2024Before adding anything, I read the request path. Cache keys and invalidation were matched to how each resource actually changes, and a Service Worker took repeat requests off the network entirely.417 → 235 GB/day · egress cost down 30%+
  3. 03Instrumenting seven ad-lifecycle events, building the CMS, then reordering execution2024Ad metrics lived in several places, so no one could name the bottleneck. I defined the events, collected them, split the path in BigQuery, then changed the order in which the bundle and the ad script run.P90 4–5s → 2–3s · CTR +30% · placement revenue +20%
  4. 04Operating image delivery on CloudFront and Lambda@Edge2023 – 2025An edge path that transforms images on the way out, carrying 253 million requests and 4.27 TB a month.4.27 TB/month · 253M requests/month
  5. 05Isolating admin batch load from the user-facing service2024When the admin system ran a large batch, the user-facing service slowed down. The cause was not in the view layer but in shared server resources.Batch load no longer propagates to user traffic
  6. 06A mobile offerwall SDK — decomposing product requirements into execution sites2024Across app, web, SDK, server and QA, I defined where each capability executes and where its data lives.5 execution sites · ~15 people across disciplines
  7. 07Moving ~15 services in daily campus use onto Kubernetes and GitOps2022 – 2026Every service deployed differently and some were over ten years old. Nothing moved at once: dependencies were assessed first, then services migrated one by one.15 on-premise services, some over a decade old
  8. 08Consolidating and migrating the shared MySQL estate2023 – 2025Servers, accounts and naming differed per service, so production and test databases could be confused. I set a standard, cleaned up, then moved production.dev / prod / test split, deprecated databases identified, production moved
  9. 09An RAG and MCP agent that performs academic tasks, not just answers about them2025A natural-language request had to end in a system action, not only a reply. For an agent that acts, a wrong execution is more dangerous than a wrong answer.Three-tier flow across Next.js, Spring Boot and a FastAPI agent
  10. 10An AI speaking assistant that reads a live Zoom conversation2025 – 2026Not a separate window you re-explain yourself to: the server already holds the context of the conversation in progress.Zoom RTMS inbound, SSE outbound, schema-validated LLM responses
  11. 11An operator's lab that replays real sessions to re-measure prompt quality2025 – 2026Running a fresh Zoom session for every prompt change is wasteful, and invented test sentences are not real conversation. Stored sessions are replayed up to a chosen moment and compared under identical conditions.Replaying a 30-minute session to minute 17 to A/B a prompt change
  12. 12SafeLens — detecting and redacting personal information in images2025Detects personal information and faces in an uploaded image and redacts only what the user confirms. First of ten teams at the hackathon.1st of 10 teams
  13. 13HellsMate — keeping a workout goal with people who know you2023Not a solo tracking app: you invite people who know you and manage the mission together. Second of twelve teams at UNITHON 9th.2nd of 12 teams · excellence award
  14. 14MeetMin — finding a meeting point from everyone's starting point2024Recommends a place with low total travel cost given where everyone starts, with the aim of avoiding a result where one person travels far longer than the rest.NestJS, Kotlin client, deployed on EC2
Project

Move it yourself

Raise the hit rate and requests stop earlier. Only the ones that reach the origin are billed as transfer.

BrowserService WorkerCloudFrontOrigin
Cache hit rate44%
Before (measured)After (measured)
Daily transfer

235GB/day

Reaching origin

56%

417 GB/day and 235 GB/day are the measured values. Everything between them is a linear model for illustration, not a bill.

Systems Operated

Delivery and edge

CloudFront
Re-cut cache keys and invalidation; cut transfer
Lambda@Edge
Operated the edge image transform path
Service Worker
Removed repeat requests from the network via Web Cache API
Route 53
Per-record sequential cutover during migration

Cloud

EC2
Per-service instances and the unified server
Auto Scaling
Absorbed the traffic increase after consolidation
S3
Session recordings and transcripts; image origin
RDS
Handled CA rotation and TLS connectivity
ALB · Elastic Beanstalk
Service deployment environments
SES
Production access request and sending operations

Containers and delivery

Kubernetes
Staged migration of on-premise services
Docker
Containerisation, and restart during incidents
ArgoCD
Reconciled desired state from Git into the cluster
Helm
Held per-service differences as values
GitHub Actions
Image builds and EC2 deployment pipelines

Operations

Nginx
Reverse proxy inspection during incidents
PM2
Process operation and log rotation
Grafana
Monitoring, and the gap between health checks and reality
Vault
Kept credentials out of code and config
Linux
Direct operation of on-premise servers

Data

GA4
Collected seven ad-lifecycle events
BigQuery
Segment-level bottleneck analysis
MySQL · MariaDB
Shared estate operation, backup and migration

Web and server

React · TypeScript
Frontend of a ~4M DAU service
Next.js
The agent service, and this document
Node.js · NestJS
API server development
Spring Boot
Backend integration on team projects

AI systems

LLM API
Treated as an external system requiring verification
RAG · Vector DB
Regulations retrieved rather than remembered
MCP
The tool boundary where an agent actually acts
JSON Schema
Validation of LLM response shape
Zoom RTMS
Realtime speech inbound and session state

App release

Google Play
Internal test track through to production access
App Store
iOS review passed and shipped

Field Notes

OPS-01

Service down with nothing listening on 8080

Signal

A health check alert surfaced the fault; I connected to the server directly.

Action

I checked state through Portainer and SSH and inspected Nginx. Nothing healthy was listening on the service's 8080 port. I brought production back up with Docker Compose.

Prevention

I did not stop at recovery but went looking for why the process was gone — which is where the log accumulation in OPS-02 came from.

Docker ComposeNginxSSHPortainer
OPS-02

21 GB of accumulated PM2 logs

Signal

While inspecting server state I found PM2 logs had grown to roughly 21 GB.

Action

I cleared the logs to reclaim the disk. Clearing is a reprieve rather than a fix, though: the same thing happens again.

Prevention

I applied pm2-logrotate with max_size 10M, retain 7, compression, and date-based file management and rotation.

PM2Linux
OPS-03

Ping succeeds while the service is down

Signal

Ping-based monitoring calls a healthy service down when ICMP is blocked, and calls a host healthy when the HTTP service behind it is dead.

Action

I separated ICMP reachability from application state, and reviewed HTTP-based checks with curl.

Prevention

I set the standard that an alert only means something if server failure, service failure, network failure and monitoring failure can be told apart.

MonitoringGrafanaNginx
OPS-04

Outbound connectivity lost to a network policy change

Signal

A network policy change blocked outbound connectivity on the port the production server used, and the service could not be changed on the spot.

Action

I set up a temporary TCP relay path through a server that still had connectivity, keeping the service running.

Prevention

Once normal network conditions returned I moved back to the original structure. The temporary path was not left in place.

LinuxNetworking
OPS-05

RDS CA rotation against a Node.js 20 runtime

Signal

Connection problems appeared around an RDS CA rotation and expiry — and results differed by client, with DataGrip connecting where the CLI failed.

Action

I compared each client's trust store and TLS handling to establish which one verified the certificate how.

Prevention

Recorded: in production, the difference between client environments is often the cause of a connection failure rather than the certificate itself.

RDSTLSNode.js
OPS-06

A production container exiting with code 1

Signal

A Docker container on the production server exited with code 1.

Action

Cross-referencing container state, timestamps and logs pinned down when it exited.

Prevention

The root cause was not established. An unverified cause is not written down as one.

DockerLinux

The feedback that changed how I decide

Making technology decisions as SCG's president, I leaned hard at first toward what was already proven. A teammate told me I demanded a much higher standard of proof from new approaches than from the risk of the status quo.

They were right. So instead of asking whether something was stable, I changed the question to two: how far does this change reach, and how far can we roll it back if it goes wrong?

The person proposing an idea does not carry the whole burden of proving it safe. Deciding how much verification a change needs is the team's job.

When the reach is narrow

Try it in a small scope first. Agreement should not cost more than the change.

When the reach is wide

Widen the review and the people in it — more so the less reversible the change is.

When it can be undone

Confirm the path back, then go. The sequential DNS cutover was the same reasoning.

Record

Experience

01
2023.02 – 2025.04

Frontend team · part lead → deputy team lead

Nudge Healthcare
  • Built the web frontend of a service used by millions — roughly 4M daily active users and over 5M page views a day.
  • Full time for 26 months as an industrial technical agent under Korea's alternative military service programme: joined February 2023, completed the full term April 2025.
  • I was writing the React, TypeScript and Node.js frontend when transfer cost and the pager came with it. Re-cutting the CDN and browser cache policy took daily transfer from 417 to 235 GB, and 10+ affiliate communities were folded into one multi-tenant codebase, migrated one DNS record at a time.
  • Collaborated with product, PM, backend, Android, iOS, QA, data and operations — turning specifications into APIs and data flows, and working out schedules, dependencies and change impact.
  • Moved from part lead to deputy team lead in the frontend organisation, coordinating around 20 engineers.

Organisations

02
2022.03 – 2026.11

Member → dev lead → president

SKKU Systems Consultant Group (SCG)
  • Responsible for development management across the group, plus server and infrastructure operation, technical decisions, process definition and external liaison.
  • Operates around 15 web services in real campus use, some of them over ten years old.
2022.09 – 2023.02

Web development core member · lead

GDGoC SKKU (formerly GDSC)
  • Led training and practice-project management for a team of eight.
  • Produced instructional video, designed the practice projects, and ran the study curriculum and office hours.

Education

01
2020.03 – 2027.02

BSc Electronic & Electrical Engineering · double major in Software

Sungkyunkwan University
  • GPA 4.21 / 4.5 · 143 credits · graduating February 2027.
  • Coursework in operating systems, computer architecture, algorithms, databases, software engineering, artificial intelligence, web and mobile programming practicums, and a capstone design project.

Credentials

03
2025.09.12Industrial Engineer Information ProcessingHRD Korea
2021.07.16Craftsman Information Processing (now Craftsman Programming)HRD Korea
2026.08.15OPIc — Advanced LowACTFL

Awards

02
2025SafeLens — 1st of 10 teamsHackathon
2023HellsMate — 2nd of 12 teams, excellence awardUNITHON 9th

Contact

Seoul, Republic of Korea