which takes some courage
용기가 필요한 일이다 · 자신의 실수를 공개적으로 공유하는 사람을 칭찬할 때
He's agreed to share both the techniques and the lessons, which takes some courage.
응용 연습
She presented her own outage report, which takes some courage.
SYSTEM SW / 2026-08-21 / Tech sharing & debate
숨은 의존성을 깨지 않는 부팅 시간 최적화 기술 공유
금요 기술 공유 세 번째 세션입니다. Pulse Watch 부팅 시간 단축 작업과 그로 인해 드러난 eSIM 부트 루프 경험을 바탕으로, 커널·BSP, 플랫폼 프레임워크, SQE, 모뎀 소프트웨어 팀이 부팅 단계별 측정 방법, 최적화 기법, 숨은 순서 의존성의 위험, 그리고 Atlas의 부팅 시간 예산을 토론합니다.
가상의 비즈니스 회의 · 중급~고급 · 2,202단어 · 약 18분
Good afternoon, everyone, and welcome to the third Friday tech share. Attendance keeps growing, which I take as a good sign, or maybe people just like the snacks. Today's topic is boot time. Dongwook led the boot time work on Pulse Watch, and as most of you know, that work had an unexpected side effect two weeks before launch. He's agreed to share both the techniques and the lessons, which takes some courage.
Thanks, Daniel. I'd rather people learn from my mistake than repeat it. I'll spend about twenty minutes on how we measured and reduced boot time, then ten minutes on what went wrong, and then I'd love a discussion about how we approach this on Atlas.
Mina from Framework. I worked on the other half of the Pulse Watch boot, from the system server onward, so I'll probably jump in a lot.
Nari from SQE. I found the boot loop, so I'm here to make sure we talk about testing.
Seojin from Modem Software. The modem was the other half of that race condition, so I want to understand how boot ordering decisions are made.
Let's start with measurement, because you can't optimize what you can't see. The first mistake people make is measuring boot time as one number, from power button to home screen. That number is useful for marketing, but useless for engineering. We split boot into five phases: the bootloader, the kernel up to the first user space process, the init phase that starts native services, the framework phase from the system server to the launcher, and finally the time until the device is actually usable.
Can you explain the difference between the last two? I always assumed that when the home screen appears, the device is ready.
That's a common assumption, and it's exactly where some teams cheat. You can make the home screen appear earlier by delaying a lot of work until after it's drawn. But if the user taps an app and it takes five seconds to open because the system is still busy in the background, the device isn't really ready. We measure the point where the CPU load drops below a threshold and a test app opens in normal time.
For tools, we used a kernel boot trace with timestamps for every driver probe, plus a system trace that covers the whole boot. The key is to collect them on every nightly build, not just when someone is investigating. On Pulse Watch, we had a dashboard showing each phase over time, so if a phase got slower by half a second, we knew which day and which change caused it.
How noisy were the measurements? Boot time can vary quite a bit from run to run.
Very noisy at first, about plus or minus two seconds. We reduced it by always booting ten times on three devices and taking the median, with the devices at the same temperature and battery level. After that, the variation was under three hundred milliseconds, which is good enough to see real regressions.
Now the techniques. In the kernel phase, the biggest win came from asynchronous driver probing. By default, many drivers probe one after another, and if one driver waits two hundred milliseconds for its hardware to respond, everything behind it waits too. We marked about forty drivers as safe to probe in parallel, and the kernel phase went from three point one seconds to one point eight.
How did you decide which drivers were safe to probe in parallel? That seems like exactly the kind of decision that could break hidden dependencies.
You're absolutely right, and I'll come back to that. For the kernel, we were fairly careful: a driver was only marked asynchronous if all its dependencies were declared explicitly in the device tree, so the kernel itself could enforce the ordering. That part actually went fine. The problem came later, in user space.
In the init phase, we did three things. We moved loading of non-essential kernel modules, like the ones for sensors that aren't needed until the user starts a workout, to after boot complete. We started the services that don't depend on each other in parallel instead of in a fixed sequence. And we removed six services that were left over from the previous watch and did nothing on the new hardware. Together, that saved about two seconds.
Six services doing nothing. That sounds a lot like the forty-nine kernel patches Sora found last week. We carry a lot of history without noticing.
How did you confirm those six services really did nothing? Removing a service seems even riskier than removing a wait.
Good question, and to be fair, we were more careful there. For each service, we checked which hardware it talked to and which other processes connected to it during a full day of use. If the hardware didn't exist on the watch and nothing connected to it, we removed it. We also kept the code for one release, disabled rather than deleted, so we could bring it back quickly if needed.
On the framework side, the largest saving came from reducing what the system server does before the launcher appears. We profiled every service's startup and found that about a third of the time was spent in services that the user can't interact with until much later, like backup, sync, and some health monitoring. We changed them to start after boot complete, with a short delay so they don't compete with the user's first actions.
Doesn't delaying services risk the problem you mentioned earlier, where the home screen looks ready but the device is still busy?
It does, and that's why we measured the usable point, not just the home screen. We tuned the delays so that background services start in small groups, and we checked that the test app still opened in normal time throughout. It's a balance: if everything starts at once, the first app launch is slow; if everything waits too long, sync and notifications feel delayed.
We also reduced the number of classes preloaded by the app process template. Preloading makes app launches faster later, but it costs boot time up front. On a watch with few apps, preloading thousands of classes wasn't worth it. On a phone, the trade-off is different, so please don't copy that change blindly to Atlas.
Now for the part I promised. The final change that got us below twenty seconds was starting the system server six seconds earlier by removing an explicit wait in init. That wait had been there for years, and the comment above it just said 'wait for modem'. Nobody remembered why. Our measurements showed nothing broke when we removed it, and the system server came up much faster.
And the reason it existed was the eSIM restore path, which only runs after a factory reset with an existing profile. So it was invisible in normal boot testing.
Exactly. The wait was an implicit dependency, an ordering guarantee that someone added years ago instead of fixing the provisioning service. When we removed it, we broke a contract that wasn't written down anywhere except in a three-word comment. Our boot tests didn't catch it because they always booted clean devices.
That's the testing lesson for me. Boot testing needs to cover the unusual boots, not just the normal one: first boot after a factory reset, boot after an OTA, boot with a full storage, boot with a SIM or eSIM profile, and boot after a crash. Those are the paths where old, forgotten waits usually matter.
I'd add a code review rule: if you remove a wait, a sleep, or an ordering constraint, you have to explain why it existed, not just show that nothing obviously broke. If you can't explain it, find out, or ask the original author before removing it.
I want to raise a slightly provocative question. How much does boot time actually matter? Most users reboot their phones once a week or less. We spent weeks of engineering time, and took real risk, to save six seconds that a user experiences maybe fifty times a year.
Fair point, but I'd argue boot time matters more than its frequency suggests. Boot is what happens after every update, and a slow boot after an update makes users feel the update made their phone worse. It's also on the critical path for recovering from crashes. If the device reboots unexpectedly, every second of boot is a second the user is staring at a logo, already annoyed.
I'd also mention emergency calls. If a phone reboots and the user needs to make an emergency call, the time until the modem is registered on the network really matters. That's a case where boot time is a safety topic, not just a convenience.
That's a strong argument. So maybe the right target isn't the total boot time, but specific milestones: time to emergency call capability, time to first unlock, and time until the device is usable. Those reflect what users actually need.
I like that framing a lot. It also changes how we optimize. If emergency calls are a milestone, then modem initialization is on the critical path and should start as early as possible, which is the opposite of what usually happens.
Let's bring this to Atlas. Marketing hasn't set a boot time claim yet, which is a rare opportunity. I'd propose we define milestone targets ourselves before anyone else does: emergency call capability within twelve seconds, first unlock within eighteen, and usable within twenty-two. Are those realistic?
For a new chipset on a new kernel, they're ambitious but not crazy. I'd suggest we treat them as budgets per phase rather than one target. If the bootloader gets two seconds, the kernel three, init four, and so on, each team knows its share and can't spend another team's time.
And SQE will add the unusual boot scenarios to the nightly suite from the first Atlas boot, not two weeks before launch. Factory reset with an eSIM, boot after an OTA, boot with full storage, and boot after a forced crash.
From the modem side, I'll document every ordering dependency between the modem and the framework explicitly, so nobody has to guess from a three-word comment again.
A practical question before we wrap up. When a boot regression appears on the dashboard, who owns it? On Pulse Watch, I sometimes saw a phase get slower and nobody picked it up for days, because it wasn't clear whether it was a kernel issue or a framework issue.
That's exactly why per-phase budgets help. If the kernel phase goes over its budget, kernel owns it, full stop. Even if the root cause turns out to be somewhere else, the owner of the phase is responsible for finding the right team. It removes the debate about who should look first.
I'd add one rule: a regression of more than three hundred milliseconds in any phase should automatically block the change that caused it from being promoted to the release branch. Otherwise, small regressions pile up, and by the time someone notices, there are twenty changes to untangle.
That's strict, but I like it. Our measurement noise is under three hundred milliseconds now, so the threshold wouldn't fire randomly. Let's try it on Atlas and see whether it causes more pain than it saves.
One more question from me. Dongwook, if you could go back, would you still have removed the wait for the modem?
Honestly, yes, but in a different order. I'd first find out why it existed, fix the provisioning service so it handles a slow modem properly, and only then remove the wait. The end result would have been the same boot time, without the boot loop. The mistake wasn't the optimization; it was skipping the investigation.
That's probably the most useful sentence from today. I'm going to put it on the wiki page, right at the top, so it's the first thing people read before they start optimizing anything.
Let me capture the action items. Dongwook: write up the boot measurement method and the phase dashboard for the wiki, and draft the per-phase budgets for Atlas. Mina: propose the milestone definitions for first unlock and usable. Seojin: document the modem ordering dependencies. Nari: add the unusual boot scenarios to the Atlas nightly suite. And I'll propose the review rule about removing waits and ordering constraints to all kernel and framework reviewers.
Thank you all for turning my worst week into something useful. I'll also share the raw boot traces from Pulse Watch on the wiki, before and after each optimization, so anyone working on Atlas can see exactly what changed in each phase and how we measured it.
That would be great for SQE too. Having a known good trace to compare against makes it much easier to explain a regression when we file it.
And I'll bring the modem dependency document to next week's session, in case anyone wants to review it before it's final.
That's what these sessions are for. Next Friday, August 28th, Jiwoo will present a blameless postmortem of the Orion storage panic. Same time, 4 p.m. Korea time. See you all then.
안녕하세요, 여러분. 세 번째 금요 기술 공유에 오신 걸 환영합니다. 참석자가 계속 늘고 있는데, 좋은 신호로 받아들이겠습니다. 아니면 간식이 좋아서일 수도 있고요. 오늘 주제는 부팅 시간입니다. 동욱 님이 Pulse Watch의 부팅 시간 작업을 이끌었는데, 다들 아시다시피 그 작업이 출시 2주 전에 예상치 못한 부작용을 낳았죠. 기법과 교훈을 모두 공유해 주기로 했는데, 용기가 필요한 일입니다.
고마워요, Daniel. 사람들이 제 실수를 반복하기보다 거기서 배우는 게 낫습니다. 부팅 시간을 어떻게 측정하고 줄였는지에 20분 정도, 무엇이 잘못됐는지에 10분 정도 쓰고, 그다음 Atlas에서 이걸 어떻게 접근할지 토론하면 좋겠습니다.
프레임워크팀 Mina입니다. Pulse Watch 부팅의 나머지 절반, 시스템 서버 이후 부분을 작업해서 아마 자주 끼어들 것 같아요.
SQE 나리입니다. 제가 부트 루프를 발견했으니, 테스트 이야기를 꼭 하도록 하려고 왔습니다.
모뎀 소프트웨어팀 서진입니다. 모뎀이 그 경쟁 상태의 다른 절반이었으니, 부팅 순서 결정이 어떻게 내려지는지 이해하고 싶습니다.
측정부터 시작하겠습니다. 볼 수 없는 건 최적화할 수 없으니까요. 사람들이 처음 저지르는 실수는 부팅 시간을 전원 버튼부터 홈 화면까지 하나의 숫자로 측정하는 겁니다. 그 숫자는 마케팅에는 유용하지만 엔지니어링에는 쓸모없습니다. 저희는 부팅을 다섯 단계로 나눴습니다. 부트로더, 첫 사용자 공간 프로세스까지의 커널, 네이티브 서비스를 시작하는 init 단계, 시스템 서버부터 런처까지의 프레임워크 단계, 마지막으로 단말이 실제로 쓸 수 있게 되기까지의 시간입니다.
마지막 두 개의 차이를 설명해 주실 수 있나요? 저는 항상 홈 화면이 뜨면 단말이 준비된 거라고 생각했어요.
흔한 가정이고, 바로 일부 팀이 꼼수를 쓰는 지점입니다. 많은 작업을 홈 화면이 그려진 이후로 미루면 홈 화면을 더 일찍 띄울 수 있습니다. 하지만 시스템이 백그라운드에서 아직 바빠서 사용자가 앱을 눌렀을 때 열리는 데 5초가 걸린다면, 단말은 진짜로 준비된 게 아닙니다. 저희는 CPU 부하가 임계값 아래로 떨어지고 테스트 앱이 정상 시간 안에 열리는 시점을 측정합니다.
도구로는 모든 드라이버 프로브에 타임스탬프가 찍힌 커널 부팅 트레이스와 부팅 전체를 다루는 시스템 트레이스를 썼습니다. 핵심은 누가 조사할 때만이 아니라 매 야간 빌드마다 수집하는 겁니다. Pulse Watch에서는 단계별 추이를 보여 주는 대시보드가 있어서, 어떤 단계가 0.5초 느려지면 어느 날 어떤 변경 때문인지 알 수 있었습니다.
측정값의 편차는 얼마나 컸나요? 부팅 시간은 실행마다 꽤 달라질 수 있잖아요.
처음엔 아주 컸습니다. 대략 ±2초 정도요. 단말 3대로 항상 10번씩 부팅하고 중앙값을 쓰고, 단말의 온도와 배터리 잔량을 같게 맞춰서 줄였습니다. 그 후로는 편차가 300밀리초 미만이 돼서, 실제 회귀를 보기에 충분했습니다.
이제 기법입니다. 커널 단계에서 가장 큰 효과는 비동기 드라이버 프로빙에서 나왔습니다. 기본적으로 많은 드라이버가 차례로 프로빙하는데, 드라이버 하나가 하드웨어 응답을 200밀리초 기다리면 그 뒤의 모든 것도 기다립니다. 약 40개 드라이버를 병렬 프로빙해도 안전하다고 표시했더니, 커널 단계가 3.1초에서 1.8초로 줄었습니다.
어떤 드라이버를 병렬로 프로빙해도 안전한지 어떻게 정하셨나요? 그게 바로 숨은 의존성을 깨뜨릴 수 있는 종류의 결정 같은데요.
정확한 지적이고, 그 얘기로 다시 돌아오겠습니다. 커널에서는 꽤 신중했습니다. 모든 의존성이 디바이스 트리에 명시적으로 선언돼서 커널 자체가 순서를 강제할 수 있는 경우에만 드라이버를 비동기로 표시했습니다. 그 부분은 실제로 문제없었습니다. 문제는 나중에, 사용자 공간에서 생겼습니다.
init 단계에서는 세 가지를 했습니다. 사용자가 운동을 시작하기 전까지 필요 없는 센서용 모듈처럼 필수가 아닌 커널 모듈 로딩을 부팅 완료 이후로 옮겼습니다. 서로 의존하지 않는 서비스들은 고정된 순서 대신 병렬로 시작했습니다. 그리고 이전 워치에서 남아 있던, 새 하드웨어에서는 아무 일도 하지 않는 서비스 6개를 제거했습니다. 다 합쳐 약 2초를 줄였습니다.
아무것도 안 하는 서비스가 6개라니. 지난주 소라 님이 찾은 커널 패치 49개와 아주 비슷하게 들리네요. 저희는 모르는 사이에 많은 과거 유산을 들고 다니고 있어요.
그 서비스 6개가 정말 아무것도 안 한다는 걸 어떻게 확인하셨나요? 서비스를 없애는 건 대기를 없애는 것보다 더 위험해 보이는데요.
좋은 질문이고, 공정하게 말하면 거기서는 더 신중했습니다. 서비스마다 어떤 하드웨어와 통신하는지, 하루 종일 사용하는 동안 어떤 다른 프로세스가 연결하는지 확인했습니다. 그 하드웨어가 워치에 없고 아무것도 연결하지 않으면 제거했습니다. 그리고 필요하면 빨리 되돌릴 수 있도록 한 릴리스 동안은 코드를 삭제하지 않고 비활성화한 상태로 남겨 뒀습니다.
프레임워크 쪽에서는 런처가 나타나기 전에 시스템 서버가 하는 일을 줄인 게 가장 크게 절약됐습니다. 모든 서비스의 시작 과정을 프로파일링해 보니, 시간의 약 3분의 1이 백업, 동기화, 일부 건강 모니터링처럼 사용자가 한참 뒤에야 사용할 수 있는 서비스에 쓰이고 있었습니다. 그것들을 부팅 완료 이후에 시작하도록 바꾸고, 사용자의 첫 동작과 경쟁하지 않도록 짧은 지연을 뒀습니다.
서비스를 지연시키면 앞서 말씀하신 문제, 홈 화면은 준비된 것처럼 보이는데 단말은 아직 바쁜 상황이 생길 위험이 있지 않나요?
그렇습니다. 그래서 홈 화면만이 아니라 사용 가능 시점을 측정한 겁니다. 백그라운드 서비스가 작은 그룹으로 나뉘어 시작하도록 지연을 조정했고, 그 과정 내내 테스트 앱이 정상 시간 안에 열리는지 확인했습니다. 균형의 문제예요. 모든 게 한꺼번에 시작하면 첫 앱 실행이 느리고, 모든 게 너무 오래 기다리면 동기화와 알림이 늦게 느껴집니다.
앱 프로세스 템플릿이 미리 로드하는 클래스 수도 줄였습니다. 미리 로드하면 나중에 앱 실행이 빨라지지만, 그만큼 부팅 시간을 먼저 씁니다. 앱이 적은 워치에서는 클래스 수천 개를 미리 로드할 가치가 없었습니다. 폰에서는 트레이드오프가 다르니, 그 변경을 Atlas에 무작정 복사하지는 마세요.
이제 약속한 부분입니다. 20초 미만으로 내려가게 한 마지막 변경은 init의 명시적 대기를 없애서 시스템 서버를 6초 일찍 시작한 것이었습니다. 그 대기는 몇 년 동안 있었고, 그 위의 주석에는 '모뎀 대기'라고만 적혀 있었습니다. 왜 있는지 아무도 기억하지 못했죠. 저희 측정에서는 그걸 없애도 아무것도 깨지지 않았고, 시스템 서버가 훨씬 빨리 올라왔습니다.
그리고 그게 있던 이유는 기존 프로필이 있는 상태로 공장 초기화한 후에만 실행되는 eSIM 복원 경로였죠. 그래서 일반 부팅 테스트에서는 보이지 않았던 거고요.
정확합니다. 그 대기는 암묵적 의존성이었습니다. 몇 년 전 누군가 프로비저닝 서비스를 고치는 대신 추가한 순서 보장이었죠. 그걸 없애면서 세 단어짜리 주석 외에는 어디에도 적혀 있지 않던 계약을 깨뜨린 겁니다. 부팅 테스트는 항상 깨끗한 단말로 부팅했기 때문에 그걸 잡지 못했습니다.
그게 저에게는 테스트 교훈입니다. 부팅 테스트는 일반적인 부팅만이 아니라 특이한 부팅도 다뤄야 합니다. 공장 초기화 후 첫 부팅, OTA 후 부팅, 저장 공간이 가득 찬 상태의 부팅, SIM이나 eSIM 프로필이 있는 부팅, 크래시 후 부팅이요. 오래되고 잊힌 대기가 보통 중요해지는 경로가 바로 그런 곳입니다.
코드 리뷰 규칙을 추가하고 싶습니다. 대기, sleep, 순서 제약을 없앨 때는 눈에 띄게 깨진 게 없다는 걸 보여 주는 것만이 아니라 그게 왜 있었는지 설명해야 합니다. 설명할 수 없다면 알아내거나, 없애기 전에 원래 작성자에게 물어봐야 합니다.
조금 도발적인 질문을 하고 싶습니다. 부팅 시간이 실제로 얼마나 중요할까요? 대부분의 사용자는 일주일에 한 번 이하로 폰을 재부팅합니다. 사용자가 1년에 50번 정도 겪을 6초를 줄이려고 몇 주의 엔지니어링 시간을 쓰고 실제 위험도 감수했어요.
타당한 지적이지만, 부팅 시간은 빈도가 시사하는 것보다 더 중요하다고 주장하고 싶습니다. 부팅은 모든 업데이트 후에 일어나고, 업데이트 후 부팅이 느리면 사용자는 업데이트 때문에 폰이 나빠졌다고 느낍니다. 크래시에서 복구하는 크리티컬 패스이기도 합니다. 단말이 예기치 않게 재부팅되면, 부팅 1초 1초가 이미 짜증 난 사용자가 로고만 바라보는 시간이죠.
긴급 전화도 언급하고 싶습니다. 폰이 재부팅됐는데 사용자가 긴급 전화를 걸어야 한다면, 모뎀이 네트워크에 등록될 때까지의 시간이 정말 중요합니다. 그건 부팅 시간이 편의가 아니라 안전 문제가 되는 경우입니다.
강력한 논거네요. 그럼 올바른 목표는 전체 부팅 시간이 아니라 특정 마일스톤일 수도 있겠어요. 긴급 전화 가능 시점, 첫 잠금 해제 시점, 단말 사용 가능 시점이요. 그게 사용자가 실제로 필요로 하는 걸 반영하니까요.
그 관점 정말 마음에 드네요. 최적화 방식도 바뀝니다. 긴급 전화가 마일스톤이라면 모뎀 초기화가 크리티컬 패스에 있고 최대한 일찍 시작해야 하는데, 보통 일어나는 것과는 정반대죠.
이걸 Atlas로 가져와 봅시다. 마케팅이 아직 부팅 시간 문구를 정하지 않았는데, 드문 기회입니다. 다른 누구보다 먼저 저희가 마일스톤 목표를 정하자고 제안합니다. 긴급 전화 가능 12초 이내, 첫 잠금 해제 18초 이내, 사용 가능 22초 이내요. 현실적인가요?
새 커널의 새 칩셋치고는 야심 차지만 무리는 아닙니다. 하나의 목표가 아니라 단계별 예산으로 다루자고 제안합니다. 부트로더 2초, 커널 3초, init 4초 같은 식으로 정하면, 각 팀이 자기 몫을 알고 다른 팀의 시간을 쓸 수 없게 됩니다.
그리고 SQE는 출시 2주 전이 아니라 Atlas 첫 부팅부터 특이한 부팅 시나리오를 야간 스위트에 추가하겠습니다. eSIM이 있는 공장 초기화, OTA 후 부팅, 저장 공간이 가득 찬 부팅, 강제 크래시 후 부팅이요.
모뎀 쪽에서는 모뎀과 프레임워크 사이의 모든 순서 의존성을 명시적으로 문서화해서, 아무도 다시는 세 단어짜리 주석으로 추측할 필요가 없게 하겠습니다.
마무리하기 전에 실무적인 질문 하나요. 대시보드에 부팅 회귀가 나타나면 누가 담당하나요? Pulse Watch에서 어떤 단계가 느려졌는데, 커널 문제인지 프레임워크 문제인지 분명하지 않아서 며칠씩 아무도 맡지 않는 걸 가끔 봤거든요.
그래서 단계별 예산이 도움이 되는 겁니다. 커널 단계가 예산을 넘으면 커널이 담당하는 거죠, 끝. 근본 원인이 다른 곳으로 밝혀지더라도, 그 단계의 담당자가 적절한 팀을 찾을 책임을 집니다. 누가 먼저 봐야 하느냐는 논쟁을 없애 줍니다.
규칙 하나를 추가하고 싶어요. 어떤 단계든 300밀리초 넘게 회귀하면, 그걸 일으킨 변경이 릴리스 브랜치로 올라가는 걸 자동으로 막아야 합니다. 그렇지 않으면 작은 회귀가 쌓이고, 누군가 알아챌 때쯤엔 풀어야 할 변경이 스무 개가 됩니다.
엄격하지만 마음에 듭니다. 이제 측정 편차가 300밀리초 미만이라 임계값이 무작위로 발동하지는 않을 겁니다. Atlas에서 시도해 보고, 덜어 주는 것보다 고통을 더 주는지 지켜봅시다.
저도 질문 하나 더요. 동욱 님, 돌아갈 수 있다면 그래도 모뎀 대기를 없애셨을까요?
솔직히 그렇습니다. 하지만 순서를 다르게 했을 겁니다. 먼저 그게 왜 있었는지 알아내고, 프로비저닝 서비스가 느린 모뎀을 제대로 처리하도록 고친 다음, 그때서야 대기를 없앴겠죠. 최종 결과는 부트 루프 없이 같은 부팅 시간이었을 겁니다. 실수는 최적화가 아니라 조사를 건너뛴 것이었어요.
그게 아마 오늘 가장 유용한 문장일 거예요. 사람들이 뭔가를 최적화하기 전에 가장 먼저 읽도록 위키 페이지 맨 위에 넣을게요.
실행 항목을 정리하겠습니다. 동욱 님은 위키용으로 부팅 측정 방법과 단계별 대시보드를 정리하고, Atlas 단계별 예산 초안을 작성해 주세요. Mina는 첫 잠금 해제와 사용 가능 시점에 대한 마일스톤 정의를 제안해 주세요. 서진 님은 모뎀 순서 의존성을 문서화해 주세요. 나리 님은 특이한 부팅 시나리오를 Atlas 야간 스위트에 추가해 주세요. 그리고 저는 대기와 순서 제약 제거에 관한 리뷰 규칙을 모든 커널과 프레임워크 리뷰어에게 제안하겠습니다.
제 최악의 한 주를 유용한 무언가로 바꿔 주셔서 모두 감사합니다. 그리고 Atlas를 작업하는 누구든 각 단계에서 정확히 무엇이 바뀌었고 어떻게 측정했는지 볼 수 있도록, 최적화 전후의 Pulse Watch 원본 부팅 트레이스도 위키에 공유하겠습니다.
SQE에도 아주 좋겠네요. 비교할 수 있는 정상 트레이스가 있으면, 회귀를 등록할 때 설명하기가 훨씬 쉬워집니다.
그리고 확정 전에 검토하고 싶은 분이 있을 수 있으니, 모뎀 의존성 문서를 다음 주 세션에 가져오겠습니다.
이 세션이 바로 그걸 위한 거죠. 다음 주 금요일 8월 28일에는 지우 님이 Orion 스토리지 패닉에 대한 비난 없는 포스트모템을 발표합니다. 같은 시간, 한국 시간 오후 4시입니다. 그때 뵙겠습니다.
용기가 필요한 일이다 · 자신의 실수를 공개적으로 공유하는 사람을 칭찬할 때
He's agreed to share both the techniques and the lessons, which takes some courage.
응용 연습
She presented her own outage report, which takes some courage.
볼 수 없는 건 최적화할 수 없다 · 측정의 중요성을 강조할 때
Let's start with measurement, because you can't optimize what you can't see.
응용 연습
Add tracing first; you can't optimize what you can't see.
엔지니어링에는 쓸모없는 · 지표가 의사 결정에 도움이 되지 않음을 지적할 때
That number is useful for marketing, but useless for engineering.
응용 연습
An average crash rate across all models is useless for engineering.
일부 팀이 꼼수를 쓰는 지점 · 지표를 좋게 보이도록 조작하기 쉬운 부분을 경고할 때
That's a common assumption, and it's exactly where some teams cheat.
응용 연습
Benchmark mode detection is where some teams cheat.
실제 회귀를 볼 수 있을 만큼 충분한 · 측정 정확도가 목적에 충분함을 말할 때
After that, the variation was under three hundred milliseconds, which is good enough to see real regressions.
응용 연습
With ten runs per build, the data is good enough to see real regressions.
가장 큰 효과(성과) · 여러 개선 중 가장 효과가 큰 것을 말할 때
In the kernel phase, the biggest win came from asynchronous driver probing.
응용 연습
The biggest win came from removing unused services.
그 얘기로 다시 돌아오겠다 · 중요한 질문을 뒤에서 다루겠다고 할 때
You're absolutely right, and I'll come back to that.
응용 연습
Good question about memory; I'll come back to that.
모르는 사이에 · 인식하지 못한 채 무언가가 쌓이는 상황을 말할 때
We carry a lot of history without noticing.
응용 연습
Boot time crept up by two seconds without anyone noticing.
균형의 문제다 · 두 가지 상충하는 목표 사이의 조율이 필요할 때
It's a balance: if everything starts at once, the first app launch is slow; if everything waits too long, sync and notifications feel delayed.
응용 연습
It's a balance between battery life and responsiveness.
그 변경을 무작정 복사하지 마라 · 다른 제품의 해결책을 맥락 없이 적용하지 말라고 할 때
On a phone, the trade-off is different, so please don't copy that change blindly to Atlas.
응용 연습
The watch tuning is different, so don't copy that change blindly.
암묵적 의존성 · 문서화되지 않은 순서나 조건에 기대는 관계를 말할 때
The wait was an implicit dependency, an ordering guarantee that someone added years ago instead of fixing the provisioning service.
응용 연습
The app had an implicit dependency on the old file path.
문서화되지 않은 계약 · 명시되지 않았지만 다른 코드가 의존하는 동작을 말할 때
When we removed it, we broke a contract that wasn't written down anywhere except in a three-word comment.
응용 연습
The log format was a contract that wasn't written down.
조금 도발적인 질문 · 통념에 의문을 제기하는 질문을 던질 때
I want to raise a slightly provocative question.
응용 연습
Here's a slightly provocative question: do we need this feature at all?
빈도가 시사하는 것보다 더 · 드물게 일어나도 중요성이 클 수 있음을 주장할 때
Fair point, but I'd argue boot time matters more than its frequency suggests.
응용 연습
Update failures matter more than their frequency suggests.
야심 차지만 무리는 아닌 · 도전적이지만 달성 가능한 목표를 평가할 때
For a new chipset on a new kernel, they're ambitious but not crazy.
응용 연습
A two-week turnaround is ambitious but not crazy.
이 세션이 바로 그걸 위한 것이다 · 모임의 목적을 상기시키며 격려할 때
That's what these sessions are for.
응용 연습
Sharing mistakes openly? That's what these sessions are for.