Choosing a stack you can maintain alone.
A stack one person can maintain is one web app, one Postgres database and a host that runs both, in a language you already know. Every extra service adds upgrades, alerts and failure modes, measured in hours a month. Add a queue, cache or second service only when the simpler setup has failed in a way you can write down.
Facts checked
The boring-technology argument, applied to one person
Dan McKinley’s Choose Boring Technology gives a company “about three innovation tokens” to spend on new technology, and argues that the long-term cost of keeping a system working dwarfs the inconvenience of building with familiar tools. Boring, in his sense, means the failure modes are known. Postgres, Python and cron are boring. That is the point.
A one-person company has fewer tokens than that, probably one. Spend it on the product. If the product is a scheduling tool for dental clinics, the scheduling logic is where novelty belongs; the database, the web framework and the deploy pipeline should be things you could fix half-asleep.
The practical test: when this part breaks at 23:00, can you find the cause from its logs without opening the documentation? If not, it is not boring to you yet, however popular it is.
Start with one app and Postgres
Postgres covers most of what small SaaS products reach for extra services to do. Each of these keeps one fewer thing running:
- Background jobs: a queue that stores jobs in Postgres, such as GoodJob or Solid Queue for Rails, pg-boss for Node or Procrastinate for Python. Jobs are rows, they survive restarts, and you can inspect them with SQL.
- Scheduled work: a cron-style trigger that calls an HTTP route in your app beats a separate scheduler process.
- Sessions and rate limits: signed cookies, or a small table with an expiry column. A cache server earns its place when you can measure a query that is too slow, not before.
- Search: Postgres full-text search (
tsvector,to_tsquery) handles a catalogue of tens of thousands of rows without a search cluster. - Files: an object-storage bucket, never the app’s local disk, which a redeploy may replace.
- One codebase: a monolith with folders, not services with network calls. Splitting later is a refactor; merging services back is a migration.
What each part costs in hours a month
Money is the visible cost of a component. Time is the larger one for a solo founder, and it is rarely written down. The ranges below are our estimates, not measurements: they assume a small production app, a few hours of incident time spread over a year, monthly dependency updates and the upgrade cadences in the next section. Use them to compare options, not to plan a budget.
| Component | Managed (est. hours/month) | Self-run on a server (est. hours/month) | Where the time goes |
|---|---|---|---|
| Web app on a platform | 1–2 | 2–4 | Dependency updates, a failed build now and then; self-run adds OS patches, TLS, reverse proxy |
| Postgres | 0.5–1 | 3–6 | Watching disk and slow queries; self-run adds minor releases at least quarterly, backups, restore tests |
| Redis or a separate queue | 0.5–1 | 1–3 | Memory limits, persistence settings, one more connection string to rotate |
| Each extra service | 1–3 | 2–5 | Its own deploys, logs, auth between services, version drift |
| Kubernetes cluster | 4–10 | 10+ | Cluster upgrades, add-ons, manifests; worth it for teams, rarely for one person |
| Error tracking and uptime check | 0.5–1 | 1–2 | Reading alerts and closing noise; self-run adds keeping the tool itself up |
Plan upgrades around published end-of-life dates
Runtimes and databases stop getting security fixes on known dates. Put them in your calendar the day you choose a version. The three you are most likely to run:
- Node.js has changed its schedule: from Node 27 every line becomes LTS and is supported for 36 months from its first Current release. Production should run only LTS lines.
- Python gives each version about two years of bug fixes, then security fixes until five years after release.
- PostgreSQL supports each major version for five years and ships minor releases at least every three months. Minor upgrades need only new binaries and a restart; major ones need
pg_upgradeor a dump and restore. - A cadence that works alone: apply minor and patch updates monthly, on the same day each month. Do one major upgrade a year per component, and never two in the same week, so a regression has one suspect.
| Version | Status today | End of life |
|---|---|---|
| Node.js 22 † | Maintenance LTS | 2027-04-30 |
| Node.js 24 † | Active LTS | 2028-04-30 |
| Node.js 26 † | LTS from 2026-10-28 | 2029-04-30 |
| Python 3.11 † | Security fixes only | 2027-10 (scheduled) |
| Python 3.12 † | Security fixes only | 2028-10 (scheduled) |
| Python 3.14 † | Bug fixes | 2030-10 (scheduled) |
| PostgreSQL 14 † | Supported | Final release 2026-11-12 |
| PostgreSQL 17 † | Supported | Final release 2029-11-08 |
| PostgreSQL 18 † | Supported | Final release 2030-11-14 |
† Competitor details come from each vendor’s own published pages on the dates shown; prices and plans change, so check the vendor before you decide. Node.js 22 (2026-10-30) · Node.js 24 (2026-10-30) · Node.js 26 (2026-10-30) · Python 3.11 (2026-10-30) · Python 3.12 (2026-10-30) · Python 3.14 (2026-10-30) · PostgreSQL 14 (2026-10-30) · PostgreSQL 17 (2026-10-30) · PostgreSQL 18 (2026-10-30)
Observability you will actually read
A solo founder does not watch dashboards. Set up only signals that arrive by themselves, and make each one rare enough that you act on it.
- Errors by email, grouped. One message per new kind of error, not one per occurrence. If you get more than a few a week that you ignore, fix them or silence them; an inbox you skim is no inbox.
- An outside uptime check on a route that touches the database, every few minutes. It catches what in-app error tracking can’t: the app not running at all.
- Backup alerts. A failed backup should page you the same day. So should no successful backup for two intervals, which is how a job that silently stopped shows up.
- A monthly look at slow queries. With the
pg_stat_statementsextension,select query, mean_exec_time from pg_stat_statements order by mean_exec_time desc limit 10is the whole review. Check that your host allows it; on Canner, extensions need the dedicated Postgres instance. - Skip for now: distributed tracing, custom metrics pipelines, log shipping to a second vendor. They pay off with many services and many people.
What to avoid as a one-person team
If you are weighing a platform against a server you run yourself, PaaS, VPS or Kubernetes compares the three in detail.
- Two languages in production. Every runtime doubles the upgrade calendar above.
- A database you have never restored. Pick a host where a restore is a button or one command, and try it before you need it.
- Building your own auth. Password storage, reset flows and session fixation are well-solved problems; use your framework’s auth or a hosted service.
- Self-running stateful services to save $10 a month. At three to six hours a month for a self-run Postgres, the managed one pays for itself if your time is worth more than a few dollars an hour.
- Microservices for a future team. Hire the team first. A clean monolith splits more easily than a distributed system merges.
- The newest major version on day one. Wait for the first few minor releases; the Node project itself recommends only LTS lines for production.
Questions
What is the best tech stack for a solo developer?
The one you already know, reduced to one web app and one Postgres database on a managed host. Use Postgres for jobs, sessions and search until a measured problem says otherwise, and keep to one language in production.
Do I need Redis for a small SaaS?
Usually not at first. Postgres-backed queues such as GoodJob, Solid Queue or pg-boss handle background jobs, and signed cookies handle sessions. Add Redis when you can show a query or workload that Postgres can’t serve fast enough.
How often should I upgrade Node, Python and Postgres?
Apply minor and patch releases monthly. Plan one major upgrade a year per component, well before its end-of-life date: Node LTS lines and Python versions publish their dates, and each PostgreSQL major version is supported for five years.
Related
- GuideWhen a dedicated server beats PaaS on cost
- GuideEstimating hosting cost per customer for a SaaS
- GuidePricing a SaaS so infrastructure doesn’t eat the margin
- GuideFree tiers: who pays for them
- BlogIn Quebec Tech, Wealth Picks the Founders
- BlogCanadian Pre-Seed Funding: What Each Program Actually Gives You
One app, one database, one bill.
Deploy the app and its Postgres together on Canner, and spend your evenings on the product. More guides for one-person companies in small software companies.