Self-hosting vs managed services for small companies
Self-hosting vs managed services helps small companies decide what to run themselves, what to outsource, and how to avoid extra work and risk.

Why this decision gets messy fast
A small team can look at one monthly invoice and think the answer is obvious. If a managed database costs five times more than a virtual server, self-hosting can look like easy savings.
But the invoice is only part of the cost. The moment you run something yourself, you also own the boring work: updates, backups, access control, alerts, restore tests, and the 2 a.m. question of who fixes it now.
One infrastructure choice can quietly create daily chores for weeks. A team might save $400 a month by moving a service in-house, then lose that money in engineer time because someone now spends 20 minutes a day checking logs, patching packages, and cleaning up failed jobs. If that person is also supposed to ship product work, the real cost shows up as slower releases and more stress.
Managed services have their own price. You pay more cash, and sometimes you accept limits you would not choose for yourself. Still, they remove whole categories of work like patching, backup automation, failover setup, basic monitoring, and first-line support during outages.
For a small company, that trade is often worth it.
Workloads also behave differently. A self-hosted internal tool that nobody touches outside office hours is one thing. A customer-facing database, email system, or payment service is another. Teams get into trouble when they treat them the same.
A sane decision has little to do with ideology. You do not need to own everything, and you do not need to rent everything forever. You need to know which parts of your stack are cheap to run, cheap to recover, and cheap to maintain. Everything else should justify itself by saving real time, real money, or both.
That is why the best setup for a small company is often mixed. Keep control where it stays simple. Pay for help where failure is expensive.
What usually fits self-hosting
Small teams can self-host more than people think, but only when the workload is boring, predictable, and easy to restore. The safest choices are usually tools your team uses every day and already understands.
Source control and CI often fit that description. If your team already knows Linux, runs Docker without drama, and can read logs when a runner fails, hosting Git repositories and build jobs in-house can make sense.
Internal tools also tend to behave well on self-hosted infrastructure. A company wiki, an internal dashboard, a team job board, or an admin panel with limited public exposure usually has simple traffic patterns. If one server goes down for 20 minutes, the business is annoyed, not blocked.
Logs and metrics can be another good fit. SaaS observability bills climb fast once ingestion grows. If your product creates a lot of events, a self-hosted stack like Grafana, Prometheus, Loki, or Sentry can cut recurring costs a lot. This only works if someone watches disk growth, retention settings, and alert noise before they become a mess.
Databases need more caution. A stable PostgreSQL instance for one product can live on your own infrastructure, but only if one person clearly owns backups, updates, failover plans, and restore tests. If nobody owns that job, keep the database managed.
Signs it is a good fit
A workload usually fits self-hosting when most of this is true:
- Traffic stays fairly steady.
- Recovery steps are written down and tested.
- One person owns patching, backups, and access rules.
- The team can diagnose Linux and networking issues without panic.
- A short outage hurts productivity more than revenue.
That last point matters. Self-host workloads your team can fix with a calm runbook, not ones that wake everyone up at 3 a.m.
What usually belongs in managed services
Some workloads look simple until they fail at 2 a.m. That is where managed services usually earn their keep.
Email is a good example. Sending app emails, handling bounces, processing inbound replies, and protecting sender reputation takes steady care. A small team can run a mail server, but most teams should not. One bad config can put your domain into spam folders for weeks.
Money-related systems also belong outside your own servers in most cases. Payments, tax calculation, invoicing rules, fraud checks, and chargeback handling change often, and mistakes cost real cash. If a customer gets charged twice, or tax is wrong in one state or country, fixing the trust problem is harder than fixing the code.
Public login is another common trap. If your team does not have real security depth, use a provider for authentication. Password resets, MFA, session handling, bot defense, suspicious login checks, and account recovery sound routine until someone tries to break them.
The same goes for internet edge services like DNS, CDN caching, DDoS and bot filtering, TLS certificate handling at scale, and WAF rules. These systems sit in front of everything else. If they fail, users cannot even reach your product.
Compliance-heavy tools also fit managed services better. If a system needs round-the-clock audit logs, retention rules, access controls, legal updates, or formal certifications, a small company usually pays less by renting that work instead of building it.
A 15-person SaaS team might self-host GitLab, internal dashboards, and some background workers, but still keep email, auth, payments, and edge protection with vendors. That split is often where this stops being a debate and starts making operational sense.
If you are unsure, ask one simple question: if this breaks on a Saturday, do you want your team fixing it, or do you want to open a support ticket?
How to decide one workload at a time
Treat each service as its own decision. Your database, CI runners, internal docs, monitoring, and customer login do not carry the same risk, so they should not all land on the same side.
Start with a plain inventory. List every service you pay for or run, then write down who depends on it each week. A tool used only by two developers is very different from a service that can lock customers out of your product.
A simple scorecard keeps the discussion honest. For each workload, rate four things:
- How much damage a failure causes
- How long you can tolerate downtime
- Whether your team can run and fix it
- What it really costs each month, including staff time
That last point matters more than people think. A cheap server is not cheap if one engineer loses half a day every week nursing it.
Then pick one low-risk internal tool and move only that. Good first candidates are often CI runners, an internal wiki, a private package registry, or log storage with a short retention window. If it breaks, your team gets annoyed. If your production database breaks, customers leave.
Before you move anything, write three things down on one page: how backups run, how alerts fire, and how you roll back. Be specific. Name where backups live, who gets the alert, and what you do if the new setup fails at 2 p.m. on a Tuesday.
A small company does not need a huge process here. It needs a calm one. If your team lacks deep infrastructure experience, a fractional CTO can review the scorecard and the first move without turning it into a six-week project.
Give the new setup a month. Then review uptime, support noise, team stress, and the real bill. Keep the workload self-hosted if it saves money and stays boring. Move it back to managed if your team has to babysit it.
A simple example from a 15-person SaaS team
Picture a 15-person SaaS company with one engineer who actually likes ops work. That detail changes everything. If nobody wants to own servers, self-hosting turns into a pile of half-done chores.
This team keeps its first move narrow. Source control and CI run in-house on a small GitLab setup with a couple of runners. That keeps build costs predictable, especially when the team runs lots of tests, preview builds, and container jobs. A good infrastructure review often leads to the same split: keep the build stack close, keep risky edge systems managed.
They do not try to bring everything inside.
Billing stays with a managed provider. Email stays with a provider that handles delivery, bounce rules, and sender reputation. Auth also stays managed, because password resets, MFA, session security, and abuse handling can eat a surprising amount of time. This is where small teams often get burned. They save a bit on tooling, then lose it in stress and support work.
Day to day, ownership is clear. The ops-minded engineer owns GitLab updates, runner health, backups, and restore checks. Each developer owns broken pipelines and slow jobs in their part of the codebase. The founder or finance lead owns billing settings, tax rules, and invoice issues inside the billing tool. One product engineer owns how login and signup feel in the app, while the auth provider handles the hard security pieces. Support watches email problems, but the email provider deals with reputation and deliverability.
Observability starts as managed for a simple reason: it is easy at first, and small teams change their stack often. Hosted logs and traces save time while the product is still moving fast. If usage fees climb high enough to hurt every month, the team can move metrics and logs in-house with tools like Grafana, Prometheus, and Loki. Before that point, self-hosting observability usually adds more work than it saves.
This split is boring, and that is why it works. The team self-hosts the parts closest to code and build spend, and it rents the parts where mistakes create finance, email, or security trouble.
Costs people forget
The bill you compare is usually too small. Teams count the server and forget the work around the server.
A $200 monthly VM can turn into a much bigger cost once someone owns patching, minor version upgrades, SSL renewals, log cleanup, disk growth, and those "just checking" sessions on Saturday night. None of that feels expensive in week one. It adds up by month six.
Backups also look cheap until you budget them honestly. You need backup storage, off-site copies, and time to test a restore. A backup you never restore is only a theory, and small companies often learn that at the worst moment.
Spare capacity is another cost people skip. If you self-host a database, build runner, or internal Git service, you need room for maintenance and failure. That might mean a second node, extra disk, or a machine that sits mostly idle until something breaks. Managed services hide this inside the price. Self-hosting makes you buy it yourself.
The people cost is often the biggest one. If one engineer knows how your Docker host, Postgres replica, and monitoring stack fit together, that person becomes part of your uptime plan. Vacation, sick days, or a new job can turn a "cheap" setup into a scramble.
A quick budget check helps. Count monthly hosting and storage, admin hours for patching and upgrades, backup testing time, spare capacity for maintenance or failure, and product work delayed by migration.
That last item hurts more than teams expect. If two developers spend three weeks moving CI, error tracking, and internal tools in-house, that is three weeks they did not spend shipping customer-facing work. The savings may still be real, but the trade needs a fair comparison.
This is where an experienced CTO or advisor can save money by making the scope smaller. Instead of moving everything, a small company might self-host stable internal tools like GitLab, Grafana, or Sentry and leave email delivery, payments, and customer-facing databases on managed services. The mix is often cheaper than either extreme, and a lot less stressful.
Mistakes that make self-hosting painful
Teams usually get into trouble when they move the most fragile, customer-facing systems first. The public app, the main database, login, billing, and email delivery all carry real business risk. If a small company wants to test self-hosting, internal tools are a safer start.
Backup mistakes are even worse because they stay hidden until a bad day. A dashboard may say every snapshot succeeded, but that does not prove you can recover. Restore one backup into a fresh machine, check that the app starts, and make sure the data is usable. If nobody on the team has done a full restore drill, the backup plan is still half-finished.
Another common mistake is copying a big company stack because it looks professional. A 12-person team does not need the same spread of clusters, queues, service meshes, and security layers that a large company runs. More moving parts mean more updates, more alerts, and more weird failures at 2 a.m. Small teams usually do better with fewer components and boring defaults.
Hardware limits cause a lot of pain too. People buy one strong server, feel pleased with the savings, then pile on databases, monitoring, Git, background jobs, and staging. It works until one noisy service eats disk or memory and everything else slows down with it. Separation does not need to be fancy, but some workloads should not share the same box.
The last trap is chasing tiny monthly savings while raising outage risk. Saving $80 or $200 each month is not a win if one downtime incident costs a week of trust, support time, and missed sales. The cheaper line item is not always the cheaper choice.
A simple rule helps: self-host what your team can fix calmly on a Tuesday afternoon. Leave the rest managed until you have the time, skill, and a clear reason to take it on.
A quick sanity check before you move
Self-hosting can work well for a small company, but only if you treat it like an ongoing responsibility, not a weekend project. The decision gets much easier when you test your plan against a few practical checks.
Ask these before you move any service:
- Who owns this service when it runs fine, and who owns it when it breaks?
- Can we restore the data this week on a test machine?
- How much downtime can the team and customers actually accept?
- What does this cost each month in cash and in staff time?
- If we regret this move, how do we switch back with a short outage?
The first point matters more than most teams admit. If your database, CI runner, or internal chat tool goes down, one named person should know where the logs are, how backups work, and what the first recovery step is. "The team" is not an owner.
Backups are another common trap. A backup file sitting in storage is not proof that you are safe. Do one restore test this week, not someday. Restore the data into a separate environment, check that it opens, and make sure the steps are written down clearly enough that someone else can repeat them.
Be honest about downtime. Some internal tools can be offline for a few hours and nobody will care much. Customer login, billing, and production databases usually need a much tighter limit. If your team cannot accept more than 30 minutes of downtime, your setup, monitoring, and recovery plan need to match that limit.
Now write down the real monthly cost. Include the server bill, storage, backups, monitoring, security updates, and the staff hours for patching and troubleshooting. Two hours a week from a senior engineer is a real cost, even if it never shows up on a cloud invoice.
Last, keep an exit path. Export data in standard formats when you can. Save config, scripts, and cutover steps. A small company stays sane when it can reverse a bad infrastructure choice without a long outage.
If you work with a fractional CTO, this is the kind of checklist they should ask you to finish before saying yes to self-hosting anything serious.
What to do next
Stop treating this as one big yes-or-no decision. Put your current stack on a single page and make it plain enough that anyone on the team can read it in five minutes.
For each service, write down what it does, who depends on it every day, what breaks if it goes down for an hour, and who will own updates, backups, and alerts. That simple map clears up a lot. Teams usually notice that a few tools are boring, internal, and low risk, while a few others are tied to revenue, customer trust, or sleep.
Then run a small trial. Pick one boring internal service and self-host only that. Good candidates are internal docs, a private CI runner, or a team-only monitoring tool. Avoid anything customer-facing for the first round. A trial like this tells you more than a month of debate.
Keep the risky parts managed until your team has better coverage. If a system handles customer logins, payments, email delivery, or your main production database, leave it where someone else already handles the ugly parts at 2 a.m.
Set a short review window. Two to four weeks is usually enough. Look at the real numbers: time spent, incidents, annoying maintenance, and the bill. If the team saved money but lost ten hours a month to babysitting, that is not a win.
If the tradeoffs still feel fuzzy, get a short outside review before you move more services. Someone who has run both startup product teams and production infrastructure can usually spot the hidden costs fast.
Oleg Sotnikov does that kind of fractional CTO work at oleg.is. His background is unusually broad, from software engineering to CTO and founder work, so a short review can help a small team decide what is safe to bring in-house and what should stay managed.
The next step does not need to be dramatic. Make the map, choose one low-risk service, measure the extra work, and decide from evidence instead of instinct.
Frequently Asked Questions
Can we self-host only part of our stack?
Yes. Most small teams do better with a mixed setup than an all-or-nothing move. Self-host the boring internal tools your team can fix calmly, and keep login, payments, email, and internet-facing protection with vendors.
What should we self-host first?
Start with one low-risk internal service. CI runners, internal docs, a private package registry, or short-retention log storage usually make better first tests than anything customer-facing.
What should stay managed?
Keep email delivery, payments, public auth, DNS, CDN, DDoS filtering, and compliance-heavy systems managed in most cases. When those fail, they hit revenue, trust, or security fast, and a small team rarely wants that burden.
How do I know a service is too risky to self-host?
Ask what happens if it breaks on a Saturday. If customers cannot log in, pay, or reach your app, or if your team would panic instead of follow a simple runbook, keep it managed for now.
Does self-hosting really save money?
Sometimes, but not as often as the server price suggests. Count engineer time for updates, backups, restore tests, alerts, disk cleanup, and late-night fixes, or the savings can disappear.
Should we self-host our production database?
Be careful with that one. A stable PostgreSQL setup can work on your own servers, but only if one person owns backups, updates, monitoring, failover planning, and restore tests. If nobody owns those jobs, use a managed database.
When does self-hosted observability make sense?
It makes sense when your usage bill keeps climbing and your team can manage storage, retention, alerts, and disk growth without constant babysitting. Early on, hosted logs and traces often save more time than they cost.
Who should own a self-hosted service?
Name one person for each service. That person should know where the logs live, how backups run, what triggers alerts, and what to do first when the service fails.
How often should we test backups and restores?
Test restores now, not someday. A backup file means very little until someone restores it on a fresh machine, checks the app, and confirms the data still works.
What should we check before moving a service in-house?
Write down the real monthly cost, the downtime you can accept, who owns the service, how backups work, how alerts fire, and how you roll back. Then move one small service, review the next few weeks, and undo the change if your team has to babysit it.