The Challenge

A European fintech company needed to migrate away from US-based email providers to meet strict data residency requirements. They needed:

  • Full GDPR compliance
  • European data residency
  • High deliverability rates
  • Scalability for 50,000+ users
  • Integration with existing systems

The Solution

We built a complete email stack using European infrastructure and open-source tools.

Architecture Overview

The stack consists of:

  1. MTA (Mail Transfer Agent): Postfix on Hetzner dedicated servers
  2. Storage: PostgreSQL for metadata, object storage for attachments
  3. Webmail: Roundcube with custom branding
  4. API: FastAPI for programmatic access
  5. Monitoring: Prometheus + Grafana on separate EU instances

Infrastructure Choices

Provider: Hetzner (German infrastructure)

  • 3 dedicated servers in Falkenstein data center
  • Load balancing with HAProxy
  • Automated failover setup

Database: Managed PostgreSQL from Scaleway

  • Multi-AZ deployment within Paris region
  • Automated backups to EU-only locations
  • Encrypted at rest and in transit

Object Storage: Scaleway Object Storage

  • S3-compatible API
  • All data in European regions
  • Lifecycle policies for compliance

Implementation Details

DNS Configuration

Proper DNS is critical for email deliverability:

# SPF Record
example.com. IN TXT "v=spf1 ip4:xxx.xxx.xxx.xxx -all"

# DKIM Record
default._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCS..."

# DMARC Record
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"

Postfix Configuration

Key configuration for European compliance:

# main.cf
smtpd_tls_security_level = encrypt
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high

# Data residency enforcement
# Only relay through European IPs
smtp_bind_address = xxx.xxx.xxx.xxx

Storage Architecture

Email content is stored securely:

# Pseudocode for attachment handling
def store_attachment(file, metadata):
    # Encrypt before storing
    encrypted = encrypt_file(file, key=EU_DATA_KEY)

    # Store in EU-only bucket
    location = s3_client.upload(
        bucket='eu-emails',
        file=encrypted,
        location_constraint='eu-west-3'
    )

    # Record metadata in EU database
    db.execute(
        "INSERT INTO attachments (location, metadata) VALUES (?, ?)",
        (location, metadata)
    )

Results

After 6 months of operation:

Performance Metrics

  • Uptime: 99.97%
  • Deliverability: 99.2% (compared to 98.8% on previous provider)
  • Latency: Average 120ms within EU (vs 280ms from US provider)
  • Cost: 40% reduction compared to US SaaS provider

Compliance Achievements

  • ✅ All data stored within EU borders
  • ✅ GDPR-compliant data handling procedures
  • ✅ Full audit trail of email processing
  • ✅ Right to be forgotten implementation
  • ✅ Data portability features

Business Impact

  • Passed regulatory audits without issues
  • Increased customer trust (fintech sector)
  • Better performance for European users
  • Greater control over infrastructure

Lessons Learned

What Worked Well

  1. European Providers: Hetzner and Scaleway provided excellent performance
  2. Open Source: Full control and transparency
  3. Documentation: Comprehensive docs made audits easier
  4. Monitoring: Early detection of deliverability issues

Challenges

  1. Initial Setup: More complex than SaaS
  2. Deliverability: Required careful IP reputation management
  3. Expertise: Needed specialized email infrastructure knowledge
  4. Maintenance: Ongoing security updates and monitoring

Recommendations

For organizations considering similar migrations:

  • Start Small: Test with a subset of users first
  • IP Warming: Gradually increase email volume on new IPs
  • Monitoring: Invest in comprehensive monitoring from day one
  • Backup Plan: Keep old provider active during transition
  • Documentation: Document every decision for compliance

Code Examples

Health Check Endpoint

from fastapi import FastAPI, HTTPException
from postfix_exporter import get_queue_size

app = FastAPI()

@app.get("/health")
async def health_check():
    queue_size = get_queue_size()

    if queue_size > 1000:
        raise HTTPException(
            status_code=503,
            detail="Mail queue is backed up"
        )

    return {
        "status": "healthy",
        "queue_size": queue_size,
        "region": "eu-central-1"
    }

Conclusion

Building a European email stack is entirely feasible with modern tools and EU-based providers. While it requires more initial effort than using a SaaS provider, the benefits—compliance, control, and cost savings—make it worthwhile for organizations with strict data residency requirements.

The key is proper planning, choosing the right European infrastructure partners, and implementing robust monitoring from the start.

Would you like help building a similar solution? Get in touch