Skip to main content

01 - The Italian Indie Maker: Complete 2027 Stack

What it costs to run a digital product alone: declared costs, five criteria for choosing a stack, and a systemd service that restarts itself.

What do you think about this article?

01 - The Italian Indie Maker: Complete 2027 Stack
Indie Maker ItaliaPhoto:Ruben BoekelooPexels

At a Glance

What it costs to run a digital product alone: declared costs, five criteria for choosing a stack, and a systemd service that restarts itself.

What it costs to keep a digital product running on your own

Anyone who starts a digital product alone almost always asks the wrong question: which framework should I pick? The question that decides whether the project survives is a different one: how much do I need to earn every month so that the project does not cost me money and evening after evening? With a small server the infrastructure answer is surprisingly low, and the rest of the cost is your time, taxes and support. This article opens the series and lines up the technical choices by that criterion, pointing to the following articles for tax, payments, marketing and support.

The short answer: a virtual server good enough for a web application with a database starts, on the official price list consulted on 2026-11-13, at 5.49 euros per month excluding VAT (Hetzner Cloud's "Regular Performance" plan, listed as "from"). A collection fee for a standard card from the European Economic Area costs, on Stripe's Italian price list, 1.5% plus 0.25 euros per transaction. With these two figures the infrastructure breaks even with very few customers; the real target is a different one, and we calculate it below.

How to choose a stack when you work alone

For someone working alone, a stack is a maintenance debt that you will pay off on weekends. That is why the criteria matter more than the names: every extra technology is one more security update, one more way to break at two in the morning and one more thing to explain to whoever replaces you or helps you. Before reading the names, look at the five criteria I chose them by.

  • You already know it. Learning time is a cost that the product does not refund.
  • It has existed for years and has up-to-date official documentation. That way other people have already run into the problems.
  • It runs on a single server. No orchestrators as long as one server is enough.
  • It restarts by itself. If the process dies, the operating system brings it back up.
  • It can be replaced piece by piece. Database, application and web server stay separate.

The criteria are in order of importance, not of convenience: the first one alone is enough to discard half of the advice you read online. If you know Python and have never touched Java, a Spring Boot backend costs you months, however good a framework it is. If instead you come from the Java world and your product is a back-office tool, staying on Java is the competent choice. The last criterion protects the future: keeping database, application and web server as three distinct pieces lets you move only the one that grows.

The stack the author really uses, and why it is not a recipe

For transparency: the site you are reading runs on Angular with server-side rendering, Spring Boot on Java 21, PostgreSQL, Redis and nginx as a reverse proxy, on a Hetzner virtual server. It is a stack the author knew before building it; it is not universal advice. If your product is a content site, a static page generator with a single process is simpler and safer. If it is a tool with accounts and payments, you need a backend: choose the one you can repair on your own.

The break-even point, calculated

A break-even worked out on a spreadsheet is an idea; a break-even calculated by a program you can rerun with your own numbers is a tool. The script below uses three documented constants (server price, Stripe's percentage and fixed fee) and two declared assumptions: the domain and the monthly target. The function netto_per_abbonato subtracts the fee from the price; math.ceil always rounds up, because half a customer does not pay. The figures are before taxes and before your social security contributions, which you will find in articles 3 and 4.

# Monthly break-even of a small SaaS running on a single server.
# The three constants come from official pages consulted on 2026-11-13;
# domain and target are ASSUMPTIONS: replace them with your own.
import math

SERVER_MESE = 5.49          # Hetzner, "Regular Performance" plan, "from" price, VAT excluded
DOMINIO_ANNO = 12.00        # the reader's assumption, not a source
STRIPE_PERCENTUALE = 0.015  # standard EEA cards, Stripe Italy price list
STRIPE_FISSO = 0.25         # euros per successful transaction
OBIETTIVO_NETTO = 1000.00   # assumption: euros per month after fees, before taxes

costo_fisso = SERVER_MESE + DOMINIO_ANNO / 12

def netto_per_abbonato(prezzo):
    """What is left of a monthly payment after the Stripe fee."""
    return prezzo - (prezzo * STRIPE_PERCENTUALE + STRIPE_FISSO)

print(f"monthly fixed cost: {costo_fisso:.2f} EUR")
for prezzo in (3, 9, 19):
    netto = netto_per_abbonato(prezzo)
    pareggio = math.ceil(costo_fisso / netto)
    obiettivo = math.ceil((OBIETTIVO_NETTO + costo_fisso) / netto)
    print(f"{prezzo:>2} EUR: net {netto:5.2f} | break-even at {pareggio} | {OBIETTIVO_NETTO:.0f} EUR/month at {obiettivo} subscribers")

# Output:
# monthly fixed cost: 6.49 EUR
#  3 EUR: net  2.71 | break-even at 3 | 1000 EUR/month at 373 subscribers
#  9 EUR: net  8.62 | break-even at 1 | 1000 EUR/month at 117 subscribers
# 19 EUR: net 18.46 | break-even at 1 | 1000 EUR/month at 55 subscribers

The result tells you two things. First: with a 9-euro subscription a few customers are enough to cover the server and the domain, which means infrastructure is not the problem. Second: to reach 1,000 euros a month net of fees you need 117 subscribers at 9 euros, but only 55 at 19 euros. The price matters more than optimizing the server. The program is deterministic and its output is identical across two consecutive runs; the fee changes from card to card, for example premium cards and cards from outside the European Economic Area cost more on Stripe's price list, which is why the list should be reread at the moment you decide.

Mind what the program does not know: it does not include taxes, social security contributions, the VAT on your server purchases or refunds. For a digital service sold to consumers in other EU countries, VAT depends on the customer's country (article 58 of Directive 2006/112/EC), a topic you will meet again in the article on the regime forfettario. None of the figures above is a revenue forecast: they are costs and declared assumptions.

One server, three pieces and a process that gets back up

The minimal design has a web server that receives requests and forwards them to the application, the application that talks to the database, and a manager that brings the application back up if it dies. On Linux the manager is systemd, and its configuration lives in a unit file. The block below is a scheme to adapt: the application path and the binary are examples, and the unit was not started on a real server. It was, however, checked with systemd-analyze verify, which reads the file without starting anything and reports no syntax errors.

[Unit]
Description=Il mio SaaS (backend)
After=network.target

[Service]
Type=simple
DynamicUser=yes
WorkingDirectory=/opt/mio-saas
ExecStart=/usr/bin/node /opt/mio-saas/server.js
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
ProtectSystem=strict
PrivateTmp=true

[Install]
WantedBy=multi-user.target

# Output:
# (no message, exit 0)

Three lines do the work. Restart=on-failure tells systemd to bring the process back up if it exits with an error or is killed; without it, the default value is no and a night-time crash leaves you down until morning. RestartSec=5 waits five seconds between one attempt and the next, because the default is 100 milliseconds and an application that dies immediately would enter a frantic loop. DynamicUser=yes creates a temporary unprivileged user, and together with ProtectSystem=strict it makes the file system read-only for the process: if someone exploits a vulnerability, the possible damage is much smaller. Where the limit lies: ProtectSystem=strict prevents writing anywhere, so an application that saves files must declare its writable directories with StateDirectory=. The installation details and nginx are in the article on low-cost hosting on a VPS.

What to leave out of the initial stack

The quickest way to burn months is to build a company's infrastructure for a product that has no customers yet. Three things can almost always be postponed without harm, and each item has a reason.

  • A container orchestrator. With a single server, a systemd unit does the same job with a tenth of the complexity.
  • A complete monitoring stack. An external check that alerts you when the site does not respond, plus the system log, cover the main need at the start: knowing that something broke.
  • More than one database. A single PostgreSQL covers relational data, text search and JSON data for a long time.

Postponing does not mean ignoring: it means writing in the project diary the threshold that will change your mind, for example "when the server exceeds 80% CPU for a week". That way the decision to do more is made by a number, not by the enthusiasm of the moment. In the pre-mortem article you will find a method for listing these risks before launching.

Where to find payments, tax, customers and support

The technical part is only a fraction of the work. Before writing code it pays to know where you will find the rest, in the order in which it is usually needed. The launch pre-mortem serves to discover the risks before you spend months. The regime forfettario explains how what you earn is taxed. The payments with Stripe show how to receive money in a verifiable way. Organic marketing explains how to get found, solo support how not to be swamped by emails, and the numbers of small projects how to read success stories without being fooled.

Frequently asked questions

How much does it cost to keep a small digital product online?

The server starts at 5.49 euros per month excluding VAT on the Hetzner price list consulted on 2026-11-13; to this you add the domain (the amount depends on the registrar and the extension, check the price list) and the collection fees, which on Stripe's Italian price list are 1.5% plus 0.25 euros for standard European cards. The biggest cost remains your time.

Do I need a database separate from the application?

You need a database separate from the application process, not necessarily on another server. PostgreSQL on the same server as the application is a reasonable choice at the start, as long as the backups leave the server itself: the article on hosting shows how.

Better a VPS or a managed service?

A VPS costs less and teaches you how the system works, but security updates and backups are yours. A managed service costs more and takes that work off you. If you neither know nor want to learn how to run a server, the managed service is the honest choice, even if the monthly bill goes up.

What you can do now

You can calculate, with your own price and costs, how many subscribers are needed to cover the infrastructure and reach a monthly target, you can choose a stack with five verifiable criteria, and you can write a systemd unit that brings the application back up when it dies. You also know that the other items on the bill, tax and payments, have an article of their own.

Sources

Try These Tools

Free developer tools related to this topic.

Commenti

Caricamento commenti...

Sign in to comment

Discuss this article in the community

Join the Telegram group to discuss with other developers, ask questions and share your experiences.

Did you like this article?

Explore other content on the blog or discover my projects