← Writings
·

On Shipping Smaller

The most common reason software projects stall is not technical complexity. It is the habit of making things bigger than they need to be before anyone has seen them.

There is a pattern I have seen in engineering teams across different companies and domains. A feature starts as a small, clear idea. Over the course of planning and implementation, it accumulates edge cases, nice-to-haves, and speculative requirements. By the time it ships, it is three times larger than the original idea and two weeks late. When it reaches users, half of what was built goes untouched.

This is not a failure of ambition. It is a failure of discipline — the discipline to decide what the smallest useful version of something is, build that, and learn from it before building more.

The Cost of Building Ahead

When you build features that users have not asked for, you are spending certainty on uncertainty. You are certain about the cost: the engineering time, the testing, the added complexity in the codebase. You are uncertain about the value: whether users will use this feature, whether they will use it as you imagined, whether the problem you are solving is the one they actually have.

The asymmetry is important. Certainty is expensive. Uncertainty is cheap. The discipline of shipping small is the discipline of refusing to spend certainty on uncertainty before you have evidence that the trade-off is worth it.

A graph showing feature usage distribution, with a sharp drop where most usage concentrates in core features and long-tail features receiving nearly zero engagement
In most products, a small fraction of features account for the vast majority of usage

What Smaller Actually Means

Shipping smaller does not mean shipping worse. It means making deliberate choices about what to defer.

Consider a notifications system. The full vision might include in-app notifications, email digests, push notifications, Slack integration, user preference controls, and a notification history view. The minimum useful version might be a single in-app notification for the one event that users most frequently miss.

The minimum version delivers most of the value with a fraction of the complexity. It also delivers something the full version cannot: real data about which notifications users actually care about, before you have built the infrastructure to support all of them.

Version 1 (shipped in a week):
  - In-app alert when assigned to a task
  - Dismissable
  - Links to the relevant task

Version 2 (shipped after learning from version 1):
  - Email notification (because 40% of users miss in-app alerts)
  - Batched, not per-event (because users told us one-at-a-time was noisy)

Version 3 (deferred indefinitely):
  - Slack integration (only 3 users mentioned it)
  - Preference controls (nobody complained about not having them)

The product that emerged from this sequence is smaller than the one that was planned. It is also better, because it was shaped by actual usage rather than speculation.

The Feature You Did Not Build

There is a specific failure mode in product engineering that I think of as the ghost feature: work that was completed and shipped, but that lives in the product without contributing to it. Ghost features add to the surface area the team must maintain without adding to the value users receive.

Every ghost feature was once speculative work that was never validated. The cost of building it was paid. The return never came.

The discipline of not building speculative features is, over the long run, one of the highest-leverage practices available to an engineering team. The time not spent on ghost features is time available for work that matters. The complexity not added is complexity that does not need to be managed.

This is not always popular advice. Scope reduction in planning meetings often encounters resistance from stakeholders who have strong opinions about what users need. The counter to this is not argument — it is the track record of shipping and learning, which builds the credibility to make future scope decisions stick.

A timeline showing a feature expanding in scope during planning, then contracting after shipping when usage data shows which parts were actually used
Scope almost always expands during planning and contracts after shipping — the question is when you pay the cost of learning

On Iteration Speed

The strongest argument for shipping smaller is not about any individual feature. It is about the cumulative effect of iteration speed on the quality of a product over time.

A team that ships a small version every week, learns from it, and adjusts can make twelve significant course corrections in three months. A team that ships a large version every three months makes one. If the large team’s assumptions are correct, they ship more in one cycle than the small team. But assumptions are rarely fully correct, and the cost of discovering that at month three is much higher than the cost of discovering it at week one.

The products that improve most reliably over time are the ones built by teams with high iteration speed and the discipline to let user behavior inform the next iteration rather than the original plan.

A Note on “Good Enough”

There is a common misreading of ship-small philosophy: that it is an argument for low quality, for cutting corners, for releasing work that is not ready.

It is not. Shipping small means shipping a limited scope at high quality. The notifications feature that only handles one event type should handle that one event type flawlessly — with proper error handling, good copy, sensible defaults. What it does, it should do well.

The scope is limited. The craft is not.


The features that users rely on most are almost always smaller than you planned and better than you expected, because they had the benefit of real feedback before the scope was locked. Start with less, ship it well, and let users tell you what to build next.

Ada sebuah pola yang pernah saya lihat di tim engineering di berbagai perusahaan dan domain. Sebuah fitur dimulai sebagai ide yang kecil dan jelas. Dalam proses perencanaan dan implementasi, ia mengumpulkan kasus tepi, nice-to-have, dan kebutuhan spekulatif. Pada saat ia dirilis, ia tiga kali lebih besar dari ide aslinya dan terlambat dua minggu. Ketika mencapai pengguna, setengah dari apa yang dibangun tidak pernah disentuh.

Ini bukan kegagalan ambisi. Ini adalah kegagalan disiplin — disiplin untuk memutuskan apa versi terkecil yang berguna dari sesuatu, membangunnya, dan belajar dari itu sebelum membangun lebih banyak.

Biaya Membangun Lebih Awal

Ketika kamu membangun fitur yang belum diminta pengguna, kamu menghabiskan kepastian untuk ketidakpastian. Kamu yakin tentang biayanya: waktu engineering, pengujian, kompleksitas yang ditambahkan ke codebase. Kamu tidak yakin tentang nilainya: apakah pengguna akan menggunakan fitur ini, apakah mereka akan menggunakannya seperti yang kamu bayangkan, apakah masalah yang kamu selesaikan adalah masalah yang sebenarnya mereka miliki.

Asimetri ini penting. Kepastian itu mahal. Ketidakpastian itu murah. Disiplin merilis lebih kecil adalah disiplin untuk menolak menghabiskan kepastian untuk ketidakpastian sebelum kamu memiliki bukti bahwa trade-off itu sepadan.

Grafik yang menunjukkan distribusi penggunaan fitur, dengan penurunan tajam di mana sebagian besar penggunaan terkonsentrasi di fitur inti
Di sebagian besar produk, sebagian kecil fitur menyumbang sebagian besar penggunaan

Apa yang “Lebih Kecil” Sebenarnya Berarti

Merilis lebih kecil bukan berarti merilis lebih buruk. Artinya membuat pilihan yang disengaja tentang apa yang harus ditunda.

Pertimbangkan sistem notifikasi. Visi lengkapnya mungkin mencakup notifikasi in-app, email digest, push notification, integrasi Slack, kontrol preferensi pengguna, dan tampilan riwayat notifikasi. Versi minimal yang berguna mungkin satu notifikasi in-app untuk satu event yang paling sering terlewat oleh pengguna.

Versi minimal memberikan sebagian besar nilai dengan sebagian kecil kompleksitas. Ia juga memberikan sesuatu yang tidak bisa diberikan oleh versi lengkap: data nyata tentang notifikasi mana yang sebenarnya diperhatikan pengguna, sebelum kamu membangun infrastruktur untuk mendukung semuanya.

Versi 1 (dirilis dalam seminggu):
  - Alert in-app saat ditugaskan ke sebuah task
  - Bisa di-dismiss
  - Link ke task yang relevan

Versi 2 (dirilis setelah belajar dari versi 1):
  - Notifikasi email (karena 40% pengguna melewatkan alert in-app)
  - Dikumpulkan, bukan per-event (karena pengguna bilang satu-per-satu terlalu bising)

Versi 3 (ditunda tanpa batas):
  - Integrasi Slack (hanya 3 pengguna yang menyebutkannya)
  - Kontrol preferensi (tidak ada yang mengeluh karena tidak memilikinya)

Produk yang muncul dari urutan ini lebih kecil dari yang direncanakan. Ia juga lebih baik, karena dibentuk oleh penggunaan aktual daripada spekulasi.

Fitur yang Tidak Kamu Bangun

Ada mode kegagalan spesifik dalam product engineering yang saya sebut sebagai fitur hantu: pekerjaan yang selesai dan dirilis, tapi yang hidup dalam produk tanpa berkontribusi padanya. Fitur hantu menambah area permukaan yang harus dikelola tim tanpa menambah nilai yang diterima pengguna.

Setiap fitur hantu pernah menjadi pekerjaan spekulatif yang tidak pernah divalidasi. Biaya membangunnya telah dibayar. Pengembaliannya tidak pernah datang.

Disiplin untuk tidak membangun fitur spekulatif adalah, dalam jangka panjang, salah satu praktik yang paling berpengaruh tersedia untuk tim engineering. Waktu yang tidak dihabiskan untuk fitur hantu adalah waktu yang tersedia untuk pekerjaan yang penting. Kompleksitas yang tidak ditambahkan adalah kompleksitas yang tidak perlu dikelola.

Ini tidak selalu menjadi saran yang populer. Pengurangan scope dalam rapat perencanaan sering menghadapi penolakan dari para pemangku kepentingan yang memiliki pendapat kuat tentang apa yang dibutuhkan pengguna. Jawaban terhadap ini bukan argumen — melainkan rekam jejak merilis dan belajar, yang membangun kredibilitas untuk membuat keputusan scope di masa depan berlaku.

Timeline yang menunjukkan fitur yang berkembang scope-nya selama perencanaan, kemudian berkontraksi setelah rilis
Scope hampir selalu berkembang selama perencanaan dan berkontraksi setelah rilis — pertanyaannya adalah kapan kamu membayar biaya pembelajaran

Tentang Kecepatan Iterasi

Argumen terkuat untuk merilis lebih kecil bukan tentang fitur individu manapun. Ini tentang efek kumulatif dari kecepatan iterasi pada kualitas produk dari waktu ke waktu.

Tim yang merilis versi kecil setiap minggu, belajar dari itu, dan menyesuaikan dapat membuat dua belas koreksi arah yang signifikan dalam tiga bulan. Tim yang merilis versi besar setiap tiga bulan membuat satu. Jika asumsi tim besar benar, mereka merilis lebih banyak dalam satu siklus daripada tim kecil. Tapi asumsi jarang sepenuhnya benar, dan biaya menemukan itu pada bulan ketiga jauh lebih tinggi daripada biaya menemukannya pada minggu pertama.

Produk yang paling andal meningkat dari waktu ke waktu adalah yang dibangun oleh tim dengan kecepatan iterasi tinggi dan disiplin untuk membiarkan perilaku pengguna menginformasikan iterasi berikutnya daripada rencana asal.

Catatan tentang “Cukup Baik”

Ada kesalahpahaman umum dari filosofi kirim-lebih-kecil: bahwa itu adalah argumen untuk kualitas rendah, untuk memotong sudut, untuk merilis pekerjaan yang belum siap.

Bukan. Merilis lebih kecil berarti merilis scope yang terbatas dengan kualitas tinggi. Fitur notifikasi yang hanya menangani satu jenis event harus menangani satu jenis event itu dengan sempurna — dengan penanganan error yang tepat, copy yang baik, default yang masuk akal. Apa yang dilakukannya, harus dilakukan dengan baik.

Scopenya terbatas. Keahliannya tidak.


Fitur-fitur yang paling diandalkan pengguna hampir selalu lebih kecil dari yang kamu rencanakan dan lebih baik dari yang kamu harapkan, karena mereka mendapat manfaat dari umpan balik nyata sebelum scope dikunci. Mulailah dengan lebih sedikit, kirim dengan baik, dan biarkan pengguna memberi tahu kamu apa yang harus dibangun selanjutnya.