Theory
Build vs buy: ready-made instead of your own
Build vs buy software for a two-person team: which parts to rent instead of building, how to pick a service that lasts, and how to keep a way out of vendor lock-in.
~9 min read · 9 exercises · 250 points
Before you start
Write it or rent it?
At GarageDesk, Nina is planning the build, and she'd happily write the SMS sending and the sign-in herself: it isn't hard, there are no monthly fees, and she'd understand every line. As her advisor, you get a say in what she writes and what she doesn't.
In this lesson you'll go through the product part by part, decide what to build and what to rent, pick services that will last, and keep a way out if a provider lets you down.
Build vs buy: build only the core
Every product is made of parts, and only a few of them are the reason customers pay. For each part ask one question: is this what customers pay us for?
- For GarageDesk, the rules that decide which car is due, by date and mileage, are the core. No ready-made service knows them; they are the product. Build them.
- Sign-in, payments, message delivery and hosting are the same for every product. Whole companies do nothing else, fix them around the clock and handle problems a small team wouldn't even think of. Rent them.

This choice is called build vs buy. For a two-person team it's mostly a choice about time. Sign-in looks like one form, but behind it are password resets, leaked passwords, emails that land in spam and a locked-out administrator calling on Saturday. Every week spent there is a week not spent on reminders.
The rule isn't "never write anything yourself". It's "write the part only you can write".
- DoBuild: the due-car rules by date and mileage. Rent: sign-in, payments, SMS and Viber delivery, hosting.
- Don't"Sign-in is just one form; I'll write it myself and save the fee."
The form is the easy part; resets, leaks and lockouts are the rest.
What renting costs in a year
Rented services are billed every month, so judge them by the yearly difference, not the monthly one. GarageDesk's tools bill goes from 2,000 to 3,500 UAH a month after renting SMS and Viber sending, payments, sign-in and hosting.
The extra cost is the difference, not the new bill:
- extra per month: 3,500 − 2,000 = 1,500 UAH;
- extra per year: 1,500 × 12 = 18,000 UAH.
Now put the other side next to it. Writing and securing those four parts would eat most of Nina's four weeks before launch, and then keep costing her time: fixes, security patches, a locked-out administrator, a delivery problem at night. Rented services get fixed while she sleeps.
So the honest comparison is "18,000 UAH a year" against "most of a month now plus maintenance forever", and for a two-person team with five shops waiting, weeks are the scarcer resource. The yearly number is still worth knowing: it's what you'd recheck if a provider doubled its price.
- Do(3,500 − 2,000) × 12 = 1,500 × 12 = 18,000 UAH extra a year.
- Don't3,500 × 12 = 42,000 UAH extra a year.
Counts the whole bill, including the 2,000 UAH GarageDesk paid anyway.
Recounting a money milestone
A money milestone is a revenue level that pays for one more thing; the first one on GarageDesk's ladder is "tools paid". When costs change, the milestone moves, so recount it.
The calculation is a division with one twist:
- monthly cost ÷ price per customer = customers needed;
- round up to a whole customer, because a fraction of a shop doesn't pay.
Before renting the four services, the tools bill was 2,000 UAH and each shop pays 600 UAH: 2,000 ÷ 600 ≈ 3.33, so 4 shops. After renting, the bill is 3,500 UAH: 3,500 ÷ 600 ≈ 5.83, so 6 shops.
Check the answer from both sides: 5 × 600 = 3,000 UAH falls 500 short; 6 × 600 = 3,600 UAH covers it. The five prepaid shops almost reach the new milestone; the sixth closes the gap.
A higher bill isn't a reason to skip renting. It's a reason to know exactly how many customers it costs.
- Do3,500 ÷ 600 ≈ 5.83 → round up to 6 shops. Check: 6 × 600 = 3,600 ≥ 3,500.
- Don't3,500 ÷ 600 ≈ 5.83 → round down to 5 shops.
5 × 600 = 3,000 UAH: 500 short of the bill.
You rent the work, not the responsibility
Renting a service takes work off your hands. It doesn't take the responsibility off. To the shops, GarageDesk sends the reminders; they've never heard of the provider and they'll call GarageDesk when a message doesn't arrive.
So a rented part still needs a little ongoing attention:
- watch it: read the delivery reports, notice when messages start failing;
- understand it: sender names, delivery rules and limits are part of your product now, even if you didn't write them;
- keep the way out: one module in your code and your own copy of the data, so a bad month with the provider doesn't become a bad year for you;
- recheck the deal: prices and terms change; know what you pay and what the alternatives cost.
This is still far less work than building and running the part yourself. The point is not to treat "rented" as "solved". A service you never look at is a dependency you discover on the day it fails.
- DoNina reads the weekly delivery report and notices that one operator's messages started failing.
- Don't"We pay the provider, so delivery is their problem now."
The shops will still call GarageDesk.
Choosing a service that lasts
When you rent a part, its failures become your failures. If the message service disappears, GarageDesk's reminders disappear with it, and the shops will blame GarageDesk, not a provider they've never heard of. So choose for staying power, not for price or polish. Check four things:
- Fit: do businesses like yours use it for the same job, such as small businesses sending reminders to their clients?
- Maturity: has it been around for several years?
- Care: is it still updated, and does support answer?
- A way out: can you export your data, and are there similar services you could move to?
Two signals look attractive and tell you almost nothing: being the cheapest by far and having an impressive demo. A service launched last autumn by two developers at half price may be excellent, but for the one part that must never fail, nobody knows yet whether it will be there next year.
- DoA service small businesses have used for reminders for years, still updated, with data export.
- Don't"Half the price and a beautiful interface, launched last autumn: let's take it."
Price and polish say nothing about next year.
Boring technology on purpose
The build-vs-buy logic applies to your own code too. When you start a business, build it on the stack you already know: boring technology, well known, mature, with an answer online for every error message.

The reason is the number of experiments. Finding customers, setting prices and shipping a first version are already uncertain. Learning a new framework at the same time adds a second experiment. When something breaks at night, you won't know whether the business idea failed or the framework did, and you'll spend the time you need for customers on surprises from the tools.
Nina's choice is the stack she used at the distributor for five years. It isn't exciting, and that's the point: its problems are known and its answers are searchable.
This isn't a rule against learning. Nina can try the new framework later, on a side project that isn't paying her rent. It's a rule about timing: keep the risky part of a new business in the business, not in the tools.
- DoBuild GarageDesk on the stack Nina has used for five years; try the new framework on a side project later.
- Don't"I'll learn the new framework while building GarageDesk: two birds with one stone."
Two experiments at once: when it breaks, you can't tell which one failed.
Your data lives in your own database
Many rented services offer to keep your data for you: a message service has a contact book, a payment provider keeps customer records. It's convenient, and it's a trap if that's the only copy.
If the car owners' phone numbers exist only in the SMS provider's contact book, switching providers means asking the old one to hand them over, in whatever format it chooses, maybe after the account has been closed for unpaid bills. The module in your code is useless if the data behind it belongs to someone else.
The safe pattern is simple:
- GarageDesk's own database is the source of truth: car owners, phone numbers, cars, mileage, which reminders went out;
- each request to the provider carries what that message needs: the number and the text;
- the provider's records are a copy, useful for delivery reports, never the only place to look.
The same applies to money: keep your own record of who paid what and when, even if the payment provider also has one.
- DoPhone numbers live in GarageDesk's database; each reminder sends the number and text to the provider.
- Don'tPhone numbers live only in the SMS provider's contact book.
Leaving means asking the old provider for your own data.
Keep a way out: one module per provider
Renting a service creates a dependency. Providers raise prices, change terms and go down. You can't avoid that, but you can keep the way out short. Two habits do most of the work.
One module in between. Don't let your code call the SMS provider from fifty places. Put one small module, "send a reminder", between GarageDesk and the provider. The rest of the code only talks to the module. To switch providers, Nina rewrites that one module, a day's work instead of a month's, and nothing else notices. The same goes for payments and sign-in.

Your own copy of the key data. Keep the car owners' phone numbers, the reminder history and the record of who paid what and when in GarageDesk's own database. The provider gets what it needs for each message or payment, but it isn't the only place the data lives.
Together these are how you avoid vendor lock-in: being stuck with a provider because leaving would cost too much.

- DoGarageDesk → "send a reminder" module → today's SMS provider.
- Don'tFifty places in the code call the provider directly.
Switching becomes a month of hunting through the code.
Ready to practise?
Answer the lesson's exercises and earn 250 points the first time you finish it.
Start the exercises