The False Dilemma of Modern Architecture

When building a modern application with a static frontend, we often find ourselves facing a binary choice:

  • To bet everything on a Backend-as-a-Service solution(Supabase, Firebase) - simple but limited

  • Build a complete backend(Spring Boot, Node.js) - powerful but complex

This choice is a false dilemma. The hybrid architecture proposes a third way: using each technology where it excels

Architectural Vision

Traditional Architecture: Monolithic

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Traditional Architecture" {
  actor Utilisateur as user
  component "Frontend" as frontend #LightBlue
  component "Monolithic Backend" as backend #LightCoral {
    [Authentification]
    [CRUD]
    [Logique Métier]
    [Jobs]
    [APIs Tierces]
  }
  database "Database" as db #LightGray

  user --> frontend
  frontend --> backend : All requests
  backend --> db
}

note right of backend
Everything goes through the backend
even simple operations
⚠️ Single point of congestion
⚠️ Complexity from the start
⚠️ Tight coupling
end note
@enduml

In this approach, even the simplest operations (reading an article, creating a comment) must go through your backend. You pay the cost of complexity from day one.

The BaaS Architecture: Every Delegate

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Architecture BaaS Pure" {
  actor Utilisateur as user
  component "Frontend" as frontend #LightBlue
  cloud "Supabase / Firebase" as baas #LightGreen {
    [Auth]
    [Database]
    [Storage]
    [Edge Functions]
  }

  user --> frontend
  frontend --> baas : All operations
}

note right of baas
Rapid development
No server to manage
⚠️ Limited for complex logic
⚠️ Vendor lock-in
⚠️ Constrained Edge Functions
end note
@enduml

On the other hand, delegating everything to a BaaS is attractive at first but quickly shows its limits as soon as business logic becomes complex.

Hybrid Architecture: Separation of Concerns

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Utilisateur as user #LightBlue

package "Frontend Layer" {
  component "Static Site JBake" as frontend #SkyBlue
}

package "Simple Layer (Supabase)" #LightGreen {
  component "Authentication" as auth
  component "Basic CRUD" as crud
  component "File Storage" as storage
  component "Real-Time" as realtime
}

package "Business Layer (Spring Boot)" #Coral {
  component "Complex Logic" as logic
  component "Orchestration" as orchestration
  component "Scheduled Jobs" as jobs
  component "Integrations" as integrations
}

database "Shared PostgreSQL" as db #LightGray

user --> frontend

frontend --> auth : OAuth2, JWT
frontend --> crud : Articles, Profiles
frontend --> storage : Images, Files
frontend --> realtime : Notifications

frontend --> logic : Calculations, Reports
frontend --> orchestration : Workflows
logic --> integrations : Stripe, APIs
orchestration --> db
jobs --> db

crud --> db
auth --> db

note bottom of db
**A single source of truth**
Shared between Supabase and Spring Boot
end note

note right of auth
**Free up to 50k users**
Configuration in a few clicks
OAuth2 multi-providers
end note

note right of logic
**Enabled only if necessary**
Kotlin + Coroutines
Complex transactions
end note
@enduml

The hybrid architecture clearly separates responsibilities according to the complexity and nature of the operations.

Design Principles

Principle 1: Start Simple, Evolve Intelligently

@startuml
skinparam backgroundColor #FEFEFE

rectangle "**Phase 1: MVP**" #LightGreen {
  component "JBake + Supabase" as mvp
  note right
✓ Development in days
✓ Cost: €0
✓ Concept validation
  end note
}

rectangle "**Phase 2: Growth**" #LightYellow {
  component "JBake + Supabase\n+ Spring Boot (optional)" as growth
  note right
✓ Business logic emerges
✓ First scheduled jobs
✓ Third-party integrations
  end note
}

rectangle "**Phase 3: Scale**" #LightCoral {
  component "Complete Architecture" as scale
  note right
✓ Complex orchestration
✓ Optimized performance
✓ Distributed cache
  end note
}

mvp -down-> growth : When complexity\njustifies it
growth -down-> scale : Optimization\ncontinuous
@enduml

Do not build Spring Boot if you don’t need it.Start with Supabase, add Spring Boot when complexity justifies it.

Principle 2: Separation by Nature of Operation

@startmindmap
skinparam backgroundColor #FEFEFE
* Operations\nApplicative

left side

** Simple Operations\n(Supabase)
***_ CRUD Standard
****_ Reading
****_ Creation
****_ Update
****_ Deletion
***_ Authentication
****_ Login/Logout
****_ OAuth2
****_ Session management
***_ Storage
****_ Upload files
****_ CDN automatic
***_ Real Time
****_ WebSocket
****_ Notifications

right side

** Complex Operations\n(Spring Boot)
***_ Business Logic
****_ Complex calculations
****_ Business rules
****_ Advanced validations
***_ Orchestration
****_ Multi-services
****_ Distributed transactions
****_ Saga patterns
***_ Scheduled Tasks
****_ Periodic reports
****_ Synchronizations
****_ Cleanings
***_ Integrations
****_ Payments (Stripe)
****_ APIs third parties
****_ Services ML/AI

@endmindmap

Principle 3: A Single Source of Truth

@startuml
skinparam backgroundColor #FEFEFE

database "PostgreSQL" as db #LightGray {
  package "Schema: auth (Supabase)" #LightGreen {
    [users]
    [sessions]
    [identities]
  }

  package "Schema: public (Shared)" #SkyBlue {
    [articles]
    [comments]
    [profiles]
  }

  package "Schema: business (Spring Boot)" #Coral {
    [orders]
    [payments]
    [reports]
  }
}

component "Supabase" as supabase #LightGreen
component "Spring Boot" as spring #Coral

supabase -down-> users : Manage
supabase -down-> sessions : Manage
supabase -down-> articles : Access
supabase -down-> comments : Access
supabase -down-> profiles : Accesses

spring -down-> articles : Access
spring -down-> profiles : Access
spring -down-> orders : Manage
spring -down-> payments : Manage
spring -down-> reports : Manage

note right of db
**Advantages:**
• No complex synchronization
• JOINs possible between tables
• Guaranteed consistency
• Unified migrations
end note
@enduml

By sharing the same PostgreSQL instance, Supabase and Spring Boot work on the same data without complex synchronization.

Orchestration of the Flows

Flow 1: Centralized Authentication

@startuml
skinparam backgroundColor #FEFEFE
autonumber

actor "User" as user
participant "JBake" as jbake
participant "Supabase Auth" as auth
participant "Spring Boot" as spring
database "PostgreSQL" as db

== Authentification ==
user -> jbake : Clique "Log in"
jbake -> auth : Redirect OAuth2 (Google/GitHub)
auth -> user : Consent screen
user -> auth : Authorize
auth -> auth : Generate JWT
auth -> jbake : Returns `JWT` + Refresh Token
jbake -> jbake : Store tokens (`sessionStorage`)

== Accès aux Ressources ==
group Opération Simple (CRUD)
  user -> jbake : Create an article
  jbake -> db : POST with JWT
  note right: Supabase Row Level Security\nchecks JWT automatically
  db -> jbake : Article created
end

group Opération Complexe (Métier)
  user -> jbake : Generate a report
  jbake -> spring : POST /api/reports\nwith JWT
  spring -> spring : Validate JWT Supabase
  spring -> spring : Extracted claims (`user_id`, roles)
  spring -> db : Complex queries
  spring -> jbake : Report generated
end

note over auth, spring
**The JWT is universal**
Validated by Supabase AND Spring Boot
No double authentication
end note
@enduml

Key point: A single authentication process, a single JWT, usable everywhere.

Flux 2: Orchestration of a complex business process

@startuml
skinparam backgroundColor #FEFEFE
autonumber

actor "Client" as user
participant "JBake" as jbake
participant "Spring Boot" as spring
participant "Supabase DB" as supadb
participant "Stripe API" as stripe
participant "Inventory Service" as inventory
participant "Email Service" as email
database "PostgreSQL" as db

user -> jbake : Place order
jbake -> spring : POST /api/orders/create

== Orchestration Spring Boot ==
spring -> db : BEGIN TRANSACTION

par Vérifications Parallèles
  spring -> inventory : Check stock
  inventory -> spring : Stock OK
else
  spring -> db : Check customer profile
  db -> spring : Verified client
end

spring -> stripe : Create Payment Intent
stripe -> spring : Intent created (ID: pi_xxx)

spring -> db : Create Order (status: PENDING)
db -> spring : Order created

spring -> stripe : Confirm payment
stripe -> spring : Payment confirmed

spring -> db : Update Order (status: PAID)
spring -> inventory : Decrement stock
spring -> db : COMMIT TRANSACTION

par Notifications Asynchrones
  spring -> email : Email confirmation
else
  spring -> supadb : Insert notification
  note right: Real-time notification\nvia Supabase Realtime
end

spring -> jbake : Order confirmed
jbake -> user : Display confirmation

note over spring
**Spring Boot responsibilities:**
• Transaction ACID
• Multi-service orchestration
• Automatic rollback on error
• Edge case handling
end note
@enduml

What Spring Boot bringsReliable orchestration of complex processes involving multiple systems with transactional guarantee.

Flow 3 : Scheduled Jobs and Synchronizations

@startuml
skinparam backgroundColor #FEFEFE

participant "Scheduler\n(Spring Boot)" as scheduler
participant "Report Service" as report
participant "PostgreSQL" as db
participant "External API" as api
participant "Email Service" as email
participant "Supabase Storage" as storage

== Job Quotidien : 2:00 ==
activate scheduler
scheduler -> report : Triggers report generation

activate report
report -> db : Retrieve data\nfrom the last 24h
db -> report : Dataset

report -> report : Calculations & Aggregations
report -> report : Generation PDF

report -> storage : Upload PDF
storage -> report : URL publique

report -> email : Send to the admins\nwith link PDF
deactivate report

== Job Hebdomadaire : Sunday 3h00 ==
scheduler -> report : External synchronization

activate report
report -> api : Fetch external data
api -> report : New data

report -> db : Tables update
report -> db : Obsolete data cleanup
deactivate report

== Job Mensuel : 1st of the month ==
scheduler -> report : Billing

activate report
report -> db : Active client list
report -> report : Amount calculation
report -> api : Invoice generation (Stripe)
report -> email : Sending invoices
deactivate report

deactivate scheduler

note right of scheduler
**Impossible with Supabase alone**
Edge Functions not suitable
for long-running and recurring jobs
end note
@enduml

What Spring Boot brings: Reliable scheduled jobs with state management, automatic retry, and guaranteed execution.

Decision Matrix

When to Use Supabase?

@startuml
skinparam backgroundColor #FEFEFE

start

:Nouvelle fonctionnalité à implémenter;

if (CRUD simple ?) then (oui)
  :✅ **Supabase**;
  stop
else (non)
  if (Authentification ?) then (oui)
    :✅ **Supabase Auth**;
    stop
  else (non)
    if (Upload fichiers ?) then (oui)
      :✅ **Supabase Storage**;
      stop
    else (non)
      if (Temps réel ?) then (oui)
        :✅ **Supabase Realtime**;
        stop
      else (non)
        if (Row Level Security\nsuffisante ?) then (oui)
          :✅ **Supabase + Policies**;
          stop
        else (non)
          :⚠️ **Considérer Spring Boot**;
          #Coral:Passer à l'arbre\nde décision Spring Boot;
          stop
        endif
      endif
    endif
  endif
endif

@enduml

When to Use Spring Boot?

@startuml
skinparam backgroundColor #FEFEFE

start

:Nouvelle fonctionnalité complexe;

if (Orchestration\nmulti-services ?) then (oui)
  :✅ **Spring Boot**;
  stop
else (non)
  if (Transaction ACID\ncritique ?) then (oui)
    :✅ **Spring Boot**;
    stop
  else (non)
    if (Job planifié ?) then (oui)
      :✅ **Spring Boot Scheduler**;
      stop
    else (non)
      if (Intégration API\ntierce complexe ?) then (oui)
        :✅ **Spring Boot**;
        stop
      else (non)
        if (Calculs lourds\n> 10 secondes ?) then (oui)
          :✅ **Spring Boot**;
          stop
        else (non)
          if (Cache distribué\nnécessaire ?) then (oui)
            :✅ **Spring Boot + Redis**;
            stop
          else (non)
            :⚠️ **Probablement Supabase**;
            #LightGreen:Revenir à l'arbre\nde décision Supabase;
            stop
          endif
        endif
      endif
    endif
  endif
endif

@enduml

Examples of Architecture by Project Type

Blog / Portfolio

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Personal Blog - 95% Supabase" {
  component "JBake" as jbake #SkyBlue

  package "Supabase (Free)" #LightGreen {
    [Auth: OAuth2 Google]
    [Articles (CRUD)]
    [Commentaires]
    [Images (Storage)]
    [Notifications Realtime]
  }

  package "Spring Boot (Optional)" #LightCoral {
    [Newsletter Mensuelle]
    note bottom: Scheduled job only
  }

  database "PostgreSQL" as db

  jbake --> [Auth: OAuth2 Google]
  jbake --> [Articles (CRUD)]
  jbake --> [Commentaires]
  jbake --> [Images (Storage)]
  jbake --> [Notifications Realtime]

  [Articles (CRUD)] --> db
  [Commentaires] --> db
  [Newsletter Mensuelle] --> db
}

note bottom of "Spring Boot (Optional)"
**Spring Boot not mandatory**
Newsletter can be managed
by a third-party service (Mailchimp)
end note
@enduml

Verdict: 100% Supabase is more than enough.

SaaS application

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Application SaaS - Hybrid Architecture" {
  component "JBake / React" as frontend #SkyBlue

  package "Supabase" #LightGreen {
    [Auth Multi-tenant]
    [Profils Utilisateurs]
    [Données Simples]
    [Storage Documents]
  }

  package "Spring Boot" #Coral {
    [Facturation (Stripe)]
    [Analytics Avancées]
    [Rapports Mensuels]
    [Quotas & Limites]
    [Webhooks Stripe]
  }

  cloud "External Services" {
    [Stripe API]
    [SendGrid Email]
  }

  database "Shared PostgreSQL" as db

  frontend --> [Auth Multi-tenant]
  frontend --> [Profils Utilisateurs]
  frontend --> [Données Simples]
  frontend --> [Facturation (Stripe)]
  frontend --> [Analytics Avancées]

  [Auth Multi-tenant] --> db
  [Profils Utilisateurs] --> db
  [Données Simples] --> db

  [Facturation (Stripe)] --> db
  [Facturation (Stripe)] --> [Stripe API]
  [Analytics Avancées] --> db
  [Rapports Mensuels] --> db
  [Rapports Mensuels] --> [SendGrid Email]
  [Webhooks Stripe] ..> [Stripe API] : Écoute
}

note right of "Spring Boot"
**Required for:**
• Subscription management
• Recurring billing
• Dynamic quotas
• Complex analytics
• Reliable webhooks
end note
@enduml

Verdict: Hybrid architecture needed. Supabase for the essentials, Spring Boot for the critical part (payments, invoicing).

E-commerce

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "E-commerce - 70% Spring Boot" {
  component "Storefront (JBake/React)" as frontend #SkyBlue

  package "Supabase" #LightGreen {
    [Auth Clients]
    [Catalogue Produits\n(lecture seule)]
    [Images Produits]
  }

  package "Spring Boot (Core Business)" #Coral {
    [Gestion Commandes]
    [Paiements Stripe]
    [Gestion Stock]
    [Calcul Frais Port]
    [Génération Factures]
    [Synchronisation ERP]
    [Emails Transactionnels]
  }

  cloud "Integrations" {
    [Stripe]
    [Transporteur API]
    [ERP Externe]
  }

  database "PostgreSQL" as db

  frontend --> [Auth Clients]
  frontend --> [Catalogue Produits\n(lecture seule)]
  frontend --> [Gestion Commandes]

  [Auth Clients] --> db
  [Catalogue Produits\n(lecture seule)] --> db

  [Gestion Commandes] --> db
  [Paiements Stripe] --> [Stripe]
  [Gestion Stock] --> db
  [Calcul Frais Port] --> [Transporteur API]
  [Génération Factures] --> db
  [Synchronisation ERP] --> [ERP Externe]
  [Synchronisation ERP] --> db
}

note right of "Spring Boot (Core Business)"
**Spring Boot essential:**
• Critical transactions
• Complex orchestration
• Multiple integrations
• Legal compliance
• Synchronization jobs
end note
@enduml

VerdictSpring Boot indispensable. Supabase for auth and catalog only.

Progressive Migration Strategy

@startuml
skinparam backgroundColor #FEFEFE

|Semaine 1-2|
start
:Create project Supabase;
:Configure Auth (Google, GitHub);
:Define initial PostgreSQL schema;
:Implement basic CRUD on JBake;
:Deploy MVP on GitHub Pages;
note right
**Deliverable:** Working application
**Cost:** €0
**Time:** 1–2 weeks
end note

|Semaine 3-4|
:Observe actual usage;
:Identify limitations;

|Décision|
if (Logique complexe\némerge ?) then (non)
  |Supabase|
  :Continue with Supabase only;
  :Add Edge Functions if needed;
  stop
else (oui)
  |Spring Boot|
  :Create Spring Boot project;
  :Configure validation JWT Supabase;
  :Migrate complex logic to Spring Boot;
  note right
**Selective migration**
Only what is complex
  end note
endif

|Semaines suivantes|
:Deploy Spring Boot (Cloud Run, EC2);
:Connect to PostgreSQL Supabase;
:Implement first scheduled jobs;
:Integrate APIs third-party;

stop

note right
Final hybrid architecture Supabase + Spring Boot in perfect harmony
end note
@enduml

Costs and Operational Considerations

Cost Structure

@startuml
skinparam backgroundColor #FEFEFE

package "Estimated Monthly Costs" {

  rectangle "Phase MVP\n(0-1000 users)" #LightGreen {
    [JBake (GitHub Pages): 0€]
    [Supabase: 0€]
    [Spring Boot: N/A]
    note bottom: **Total: 0€/mois**
  }

  rectangle "Growth Phase\n(1k-10k users)" #LightYellow {
    [JBake (GitHub Pages): 0€]
    [Supabase: 0€]
    [Spring Boot (Cloud Run): 20-50€]
    [PostgreSQL (si séparé): 0-30€]
    note bottom: **Total: 20-80€/mois**
  }

  rectangle "Scale Phase\n(10k-100k users)" #LightCoral {
    [JBake (Netlify Pro): 19€]
    [Supabase Pro: 25€]
    [Spring Boot (instances multiples): 100-300€]
    [Redis Cache: 20-50€]
    [Monitoring: 20€]
    note bottom: **Total: 184-414€/mois**
  }
}

note right of "Scale Phase\n(10k-100k users)"
At this stage, the revenues largely justify the costs
end note
@enduml

Operational Responsibilities

@startuml
skinparam backgroundColor #FEFEFE

package "Who Manages What?" {

  rectangle "Managed by Supabase (0 effort)" #LightGreen {
    [Authentification]
    [Base de données]
    [Backups automatiques]
    [Scaling automatique]
    [Monitoring DB]
    [Sécurité DB]
  }

  rectangle "Managed by GitHub (0 effort)" #SkyBlue {
    [Hébergement site statique]
    [HTTPS/SSL]
    [CDN global]
    [Déploiement automatique]
  }

  rectangle "To Manage (Spring Boot)" #LightCoral {
    [Déploiement application]
    [Monitoring APM]
    [Logs centralisés]
    [Scaling horizontal]
    [Mises à jour sécurité]
  }
}

note bottom of "To Manage (Spring Boot)"
**Can be minimized with:**
• Cloud Run (serverless)
• Kubernetes (if necessary)
• Managed services (RDS, etc.)
end note
@enduml

Conclusion: Perfect Balance

The Supabase + Spring Boot hybrid architecture is not a compromise, it’s asynergy.

The Principles to Remember

@startmindmap
skinparam backgroundColor #FEFEFE
* Architecture\nHybrid

** Start Simple
***_ MVP with Supabase
***_ 0€ initial cost
***_ Quick validation

** Evolve intelligently
***_ Add Spring Boot\nif necessary
***_ Gradual migration
***_ No total redesign

** Exploit the forces
***_ Supabase: Simplicity
***_ Spring Boot: Power
***_ PostgreSQL: Single source

** Minimize Complexity
***_ No synchronization
***_ No duplication
***Clear architecture

** Optimize Costs
***_ Free at the start
***_ Progressive scaling
***_ ROI evident

@endmindmap

When to Choose This Architecture?

✅ This architecture is ideal if:

  • You want to start quickly (MVP in days, not months)

  • You anticipate a growth in business complexity

  • You want to minimize the initial costs

  • You love PostgreSQL and want a single source of truth

  • You appreciate Kotlin and Coroutines for the business code

  • You want to avoid total vendor lock-in

�❌ This architecture is NOT suitable if :

  • Your project is simple and will remain (personal blog → 100% Supabase suffices)

  • You already have an established backend stack that you master

  • You prefer a traditional monolith

  • You need .NET, Python, or another backend language

Final overview

@startuml
skinparam backgroundColor #FEFEFE

package "Complete Hybrid Architecture" {

  actor "Users" as users

  rectangle "Frontend (Static)" #SkyBlue {
    [JBake / GitHub Pages]
    note right: Free, CDN global
  }

  rectangle "Simple Backend (Supabase)" #LightGreen {
    [Auth OAuth2]
    [CRUD APIs]
    [Storage]
    [Realtime]
    note right
Free up to 50k users
Zero server configuration
    end note
  }

  rectangle "Business Backend (Spring Boot)" #Coral {
    [Orchestration]
    [Jobs Planifiés]
    [Intégrations]
    [Transactions]
    note right
Enabled only if necessary
    end note
  }

  database "PostgreSQL\nSource Single Source of Truth" as db #LightGray

  users --> [JBake / GitHub Pages]

  [JBake / GitHub Pages] --> [Auth OAuth2]
  [JBake / GitHub Pages] --> [CRUD APIs]
  [JBake / GitHub Pages] --> [Storage]
  [JBake / GitHub Pages] --> [Realtime]
  [JBake / GitHub Pages] --> [Orchestration]

  [Auth OAuth2] --> db
  [CRUD APIs] --> db
  [Orchestration] --> db
  [Jobs Planifiés] --> db
  [Intégrations] --> db
}

note bottom of db
**One database, two consumers**
• Supabase for the simple
• Spring Boot for the complex
• No synchronization required
end note

@enduml

The Best of Both Worlds

This architecture gives you:

🚀 The Velocity of Supabase

  • Startup in hours, not weeks

  • OAuth2 authentication in a few clicks

  • Automatically generated REST APIs

  • Zero server configuration

�💪 The Power of Spring Boot

  • Kotlin and Coroutines for elegant asynchronous code

  • Orchestration of complex business processes

  • Reliable scheduled jobs

  • Guaranteed ACID transactions

  • Complete Spring ecosystem

💰 The Progressive Economy

  • 0€ to start and validate

  • Costs that follow growth

  • No premature over‑engineering

🎯 Architectural Flexibility

  • Progressive migration without rewrite

  • Adding Spring Boot only if necessary

  • No total vendor lock-in

  • Evolvable architecture

To Go Further

Technical Resources

Supabase Documentation :

Spring Boot documentation:

Supplementary Articles :

  • Securing APIs with JWT

  • PostgreSQL performance optimization

  • Progressive migration patterns

  • Error handling in distributed architecture

Real Use Cases

This hybrid architecture is successfully used in:

  • SaaS B2B: Supabase authentication, Spring Boot billing

  • Marketplaces: Catalog Supabase, transactions Spring Boot

  • Content PlatformsSupabase articles, Spring Boot analytics

  • Internal tools: CRUD Supabase, workflows Spring Boot

Startup Checklist

Phase 1 - Foundations (Week 1)

  • Create Supabase account - [ ] Configure PostgreSQL project - [ ] Enable Auth (Google, GitHub) - [ ] Define initial schema - [ ] Configure Row Level Security - [ ] Test APIs from JBake

Phase 2 - MVP (Week 2-3)

  • Implement main pages - [ ] Integrate OAuth2 authentication - [ ] Create CRUD forms - [ ] Configure Storage for files - [ ] Deploy on GitHub Pages - [ ] Test under real conditions

Phase 3 - Evolution (As needed)

  • Identify complex logic needs - [ ] Create Spring Boot project if needed - [ ] Configure Supabase JWT validation - [ ] Connect to Supabase PostgreSQL - [ ] Migrate complex features - [ ] Implement scheduled jobs - [ ] Deploy Spring Boot (Cloud Run, etc.)

Anti-Patterns to Avoid

�❌ Do not:

  • Duplicate the data between Supabase and Spring Boot

  • Create two separate PostgreSQL databases

  • Code the authentication yourself

  • Use Spring Boot for simple CRUD

  • Over-architecting from the outset

  • Ignore Supabase Row Level Security

Better to do:

  • Share a single PostgreSQL database

  • Let Supabase handle authentication

  • Use Spring Boot only for the complexity

  • Start simple, evolve gradually

  • Leverage the strengths of each technology

  • Secure with RLS at database level

Evolution perspectives

Adding New Capabilities

@startuml
skinparam backgroundColor #FEFEFE

rectangle "Current Architecture" #SkyBlue {
  [JBake]
  [Supabase]
  [Spring Boot]
}

rectangle "Possible Developments" #LightYellow {

  package "Performance" {
    [Redis Cache]
    [CDN pour Assets]
    [PostgreSQL Replicas]
  }

  package "Monitoring" {
    [Grafana]
    [Prometheus]
    [Sentry]
  }

  package "CI/CD" {
    [GitHub Actions]
    [Tests Automatisés]
    [Déploiement Continu]
  }

  package "Features" {
    [Search (ElasticSearch)]
    [Queue (RabbitMQ)]
    [Event Sourcing]
  }
}

[Spring Boot] .down.> [Redis Cache] : Peut ajouter
[Spring Boot] .down.> [Queue (RabbitMQ)] : Peut ajouter
[Spring Boot] .down.> [Search (ElasticSearch)] : Peut ajouter

[Supabase] .down.> [PostgreSQL Replicas] : Peut ajouter

note bottom
**Extensible architecture**
Each addition is independent
No global redesign necessary
end note
@enduml

Scaling Horizontal

As your application grows, the hybrid architecture scales naturally:

Supabase:

  • Automatically scale up to millions of operations

  • Read replicas for read performance

  • Point-in-time recovery for security

Spring Boot :

  • Multiple instances behind load balancer

  • Stateless design facilitates horizontal scaling

  • Kubernetes for orchestration if needed

PostgreSQL :

  • Partitioning for large tables

  • Connection pooling (PgBouncer)

  • Sharding if really necessary (rare)

Architectural Testimonials

Startup SaaS (50k users)

_ We started 100% Supabase. At 5k users, we added Spring Boot only for Stripe billing and monthly reports. One year later, 80% of our operations still go through Supabase. Spring Boot handles only the critical part. This separation allowed us to scale without a redesign. _

E-learning platform (10k users)

_ Supabase’s OAuth2 authentication saved us three weeks of development. The auto-generated APIs manage our entire course catalog. Spring Boot is used only for PDF certificates and progress emails. Simple, maintainable, scalable architecture. _

Marketplace B2B (3k users)

_ Spring Boot handles transactions between buyers and sellers (critical). Supabase handles everything else: profiles, real-time messaging, documents. The fact that they share the same PostgreSQL database avoids any complex synchronization for us. It is the best architectural choice we have made. _

Synthesis: A Modern Architectural Paradigm

The Supabase + Spring Boot hybrid architecture represents a new paradigm:the architectural specialization.

@startuml
skinparam backgroundColor #FEFEFE

rectangle "Old Paradigm" #LightCoral {
  card "Everything in the Backend" {
    [Auth]
    [CRUD]
    [Logique Métier]
    [Jobs]
    [Storage]
    [Realtime]
  }
  note bottom
Maximum complexity
from day 1
  end note
}

rectangle "New Paradigm" #LightGreen {
  card "Supabase\n(Commodity)" {
    [Auth]
    [CRUD Simple]
    [Storage]
    [Realtime]
  }

  card "Spring Boot\n(Differentiation)" {
    [Logique Métier]
    [Jobs]
    [Intégrations]
  }

  note bottom
Progressive complexity added only if necessary
  end note
}

[Ancien Paradigme] -right-> [Nouveau Paradigme] : Évolution

@enduml

The fundamental principle:Don’t build what already exists as a service. Focus on what differentiates your application.

The 80/20 Rule

In most applications:

  • 80% of operationsare standard CRUD → Supabase

  • 20% of operationsrequire business logic → Spring Boot

This natural rule justifies the hybrid architecture.

@startuml
skinparam backgroundColor #FEFEFE

package "Operations Distribution" {

  rectangle "80% - Standard Operations" #LightGreen {
    [Lecture de données]
    [Création d'entités]
    [Mise à jour simple]
    [Suppression]
    [Upload fichiers]
    [Authentification]

    note bottom: **Managed by Supabase**
  }

  rectangle "20% - Business Logic" #Coral {
    [Calculs complexes]
    [Workflows multi-étapes]
    [Transactions critiques]
    [Intégrations tierces]
    [Jobs planifiés]

    note bottom: **Managed by Spring Boot**
  }
}

note right
**Optimal focus:**
Your development time
concentrated on the 20% that
set your product apart
end note
@enduml

Final conclusion

Hybrid architecture is not a technical compromise, it’s anstrategic decision.

It allows you to:

  • �✅ Start quickly with a functional MVP

  • �✅ Validate your market without heavy investment

  • �✅ Gradually evolve when complexity requires it

  • �✅ Master your costs at each step

  • ✅ Leverage the best of each technology

  • ✅ Avoid premature over-engineering

  • Maintain flexibility for the future

It represents:

  • 🎯Pragmatism: Every technology where she excels

  • �🚀Velocityminimal time-to-market

  • �💰Economy: Costs aligned with value

  • �🔮Scalability: Architecture that grows with you

  • �🛡️RobustnessProven and reliable services

Your Next Step

If this architecture speaks to you, here’s where to start:

  1. Create a Supabase account(free)

  2. Define your minimal data schema

  3. Configure OAuth2 authentication

  4. Create your first JBake page that consumes the API

  5. Deploy to GitHub Pages

You will have a functional MVP ina few days.

Spring Boot will come naturally when you need it. Not before.


Hybrid architecture is the art of building exactly what is needed, when it is needed.

Good development! 🚀


Share this article if you think it can help other developers make the right architectural choices.

Related articles