All articles
Декабрь 20, 2025 · 4 min read

5 Things I Wish I Knew Before Building My First SaaS Product

Hard-won lessons from building SaaS products as a freelance developer. Multi-tenant architecture, billing, deployment, and avoiding common mistakes.

SaaSDjangoArchitectureStartupPython
By Kirill Strelnikov — Freelance Python/Django Developer, Barcelona

1. Multi-Tenancy Is an Architecture Decision, Not a Feature

My first SaaS was a time-tracking system for cafes (now one of my portfolio projects). I initially built it as a single-tenant app and tried to "add multi-tenancy later." Big mistake.

There are three main approaches to multi-tenancy:

I ended up going with schema-per-tenant in PostgreSQL, which gave me true data isolation without the overhead of separate databases. Read more about this approach in my deep dive on PostgreSQL schema-per-tenant architecture.

# The decision matrix I use now:
# < 10 tenants  -> separate schemas
# 10-1000 tenants  -> shared schema + tenant_id
# 1000+ tenants  -> shared schema + sharding

2. Build Billing Integration From Day One

I built the entire product first, then tried to add Stripe billing. This meant retrofitting user flows, adding subscription checks to every protected view, and handling edge cases like expired trials.

What I should have done:

class SubscriptionMiddleware:
    def __call__(self, request):
        if not request.user.is_authenticated:
            return self.get_response(request)

        tenant = request.user.tenant
        if tenant.subscription_status == 'expired':
            if not request.path.startswith('/billing/'):
                return redirect('/billing/renew/')

        return self.get_response(request)

Lesson: integrate Stripe (or your payment provider) in sprint 1, not sprint 10. Even if it is just a dummy checkout flow, the architecture needs to support it from the start.

3. Onboarding Flow Is Your Most Important Feature

My first version dropped users into an empty dashboard after signup. No tutorial, no sample data, no guidance. The result? A 70% drop-off rate within the first 5 minutes.

What worked:

After implementing proper onboarding, the 7-day retention rate jumped from 15% to 45%.

4. You Need Monitoring Before You Need Features

In the first month after launch, I had no idea how users were actually using the product. No error tracking, no performance monitoring, no usage analytics. When a critical bug affected 3 tenants, I only found out when they emailed me.

# Minimum monitoring stack for a SaaS:
# 1. Error tracking (Sentry)
import sentry_sdk
sentry_sdk.init(dsn="your-dsn", traces_sample_rate=0.1)

# 2. Application logging
import logging
logger = logging.getLogger(__name__)
logger.info("Tenant %s created employee %s", tenant.id, emp.id)

# 3. Business metrics
def track_event(tenant_id, event, metadata=None):
    Metric.objects.create(
        tenant_id=tenant_id,
        event=event,
        metadata=metadata or {},
        timestamp=timezone.now()
    )

5. Your Pricing Model Will Change — Design for It

I started with a flat monthly fee. Then customers asked for per-employee pricing. Then enterprise clients wanted annual contracts with custom features. Each pricing change required database migrations and billing logic rewrites.

The pattern that works: store pricing as configuration, not code.

class Plan(models.Model):
    name = models.CharField(max_length=50)
    price_monthly = models.DecimalField(max_digits=8, decimal_places=2)
    max_employees = models.IntegerField(null=True)  # null = unlimited
    max_locations = models.IntegerField(null=True)
    features = models.JSONField(default=dict)
    # e.g. {"excel_export": true, "api_access": false}

This way, you can create new plans, adjust limits, and add features without touching code.

The Bottom Line

Building a SaaS is 20% coding and 80% product decisions. Get the architecture right early (multi-tenancy, billing, monitoring), invest heavily in onboarding, and keep your pricing model flexible. If you are planning a SaaS project, I would love to discuss your requirements — I have made these mistakes so you don't have to.

Need help building something similar? I am a freelance Python/Django developer based in Barcelona specializing in AI integrations, SaaS platforms, and business automation. Free initial consultation.

Get in touch

Telegram: @KirBcn · Email: [email protected]