Migrate from Heroku to AZIN
Salesforce put Heroku into "sustaining engineering" mode on February 6, 2026 — no new features, no new enterprise contracts, security patches only. If you're planning your exit, this guide walks you through migrating to AZIN: same deployment simplicity, but your code runs on your own GCP account.
Migration time for a typical web app with a PostgreSQL database: a few hours. Difficulty: straightforward. Your application code usually needs zero changes.
#Why migrate now
Heroku's shift to sustaining engineering (as of February 2026) means the platform receives security patches and stability fixes, but Salesforce has not announced plans for new runtimes, new regions, or new integrations.
The practical risks of staying:
- No new language or framework support announced. Salesforce has not indicated plans for new runtime or framework additions.
- Pricing unchanged since 2015. A Standard-1X dyno costs $25/mo for 512 MB of RAM (as of February 2026, per heroku.com/pricing).
- Two regions only. US and EU. If your users are in Asia-Pacific, you're adding latency on every request.
- No BYOC. Your data runs on Salesforce's shared infrastructure. You can't peer with your VPC, use cloud credits, or control data residency beyond "US" or "EU."
AZIN gives you Heroku's deployment model — push code, get a running app — on infrastructure you own. GCP BYOC is live today. AWS and Azure support are on the roadmap.
#What changes, what stays the same
Your application code stays the same. Only the deployment target changes. Here's how Heroku concepts map to AZIN.
| Heroku concept | AZIN equivalent | What changes |
|---|---|---|
| Dynos | Services (Web Service, Worker) | Services run on GKE Autopilot in your GCP account, not shared dynos |
| Procfile | Railpack auto-detection | Railpack reads your Procfile and auto-detects processes. No changes needed. |
| Heroku Postgres | Cloud SQL (PostgreSQL) | Managed PostgreSQL in your GCP VPC. You own backups, encryption, and access. |
| Heroku Key-Value Store (Redis) | Memorystore (Redis) | Cloud-native Redis, managed by GCP in your account |
| Add-ons | GCP managed services | No marketplace. Services provisioned directly in your cloud account. |
| Config Vars | Environment variables | Same concept. Set via the AZIN Console, scoped per environment. |
| Heroku Pipelines | Environments + Preview envs | Staging, production, and per-PR preview environments |
| Heroku CI | Preview environments | Every PR gets a full-stack preview deployment |
| Custom domains | Custom domains | Same. Automatic TLS included. |
| Heroku CLI | AZIN Console (CLI planned) | Web-based Console today. CLI is on the roadmap. |
| Buildpacks | Railpack | Zero-config builder that auto-detects your language and framework. Covers 13+ languages. |
| Heroku Scheduler | Cron Jobs | First-class cron job service type in AZIN |
#Step-by-step migration
Export your Heroku data
Start by capturing everything you need from Heroku. Run these commands in your terminal.
# Capture a fresh database backup
heroku pg:backups:capture --app your-app
# Download the backup locally
heroku pg:backups:download --app your-app
# This creates a latest.dump file in your current directory
# Export all environment variables
heroku config --app your-app --shell > .env.heroku
# List your current add-ons for reference
heroku addons --app your-appReview .env.heroku and note which variables are Heroku-specific (like DATABASE_URL, REDIS_URL, HEROKU_* variables). These will be replaced with GCP equivalents.
Connect your GCP account to AZIN
AZIN deploys to your own GCP account via GKE Autopilot. The first GKE Autopilot cluster is free — you pay only for pod resources (as of February 2026).
In the AZIN Console:
- Click Connect GCP
- Run the provided setup command in Google Cloud Shell
- The script creates a service account and provisions your VPC, GKE cluster, and base resources
- Status is tracked in real-time in the Console
This takes a few minutes on first setup. After that, deploys are fast.
Connect your repository
AZIN deploys from GitHub. Connect your repo in the Console:
- Select your GitHub organization and repository
- Choose the branch to deploy (typically
main) - AZIN auto-detects your language and framework via Railpack
Railpack recognizes the same project structures Heroku buildpacks do. If your app has a Procfile, requirements.txt, package.json, Gemfile, or go.mod, Railpack knows what to do.
Configure your services
In the AZIN Console, set up the services that match your Heroku configuration.
From a typical Heroku Procfile:
# Heroku Procfile
web: gunicorn myapp.wsgi:application --bind 0.0.0.0:$PORT
worker: celery -A myapp worker --loglevel=info
release: python manage.py migrateOn AZIN, this becomes:
- A Web Service — Railpack auto-detects your web process from the Procfile
- A Worker — background process, no public URL
- Release commands run during the deploy phase
No YAML config file required. Railpack reads your Procfile and sets up the services. You can also configure services through the Console's visual service graph.
# AZIN CLI (planned — commands shown are illustrative)
azin init --cloud gcp --region europe-west4
# Railpack auto-detects processes from your Procfile
# Web, worker, and release commands are picked up automatically
azin deployNote: The AZIN CLI is planned and not yet available. Use the AZIN Console (web UI) to configure and deploy today. The CLI commands above show the planned experience.
Migrate your PostgreSQL database
This is the step that takes the most care. You already have a latest.dump file from the export step.
Create a Cloud SQL instance in AZIN:
Add a Database service in the AZIN Console. This provisions a Cloud SQL PostgreSQL instance in your GCP account with automatic backups and high availability options.
Restore the dump:
# Get your Cloud SQL connection details from the AZIN Console
# The DATABASE_URL will look like:
# postgresql://user:password@<cloud-sql-ip>:5432/dbname
# Restore the Heroku backup to Cloud SQL
pg_restore --verbose --clean --no-acl --no-owner \
-d "postgresql://user:password@<cloud-sql-ip>:5432/dbname" \
latest.dumpIf your database is large (10 GB+), consider using pg_dump with --format=custom and --jobs for parallel restore. For zero-downtime cutover on very large databases, set up logical replication between Heroku Postgres and Cloud SQL before switching.
Update your DATABASE_URL:
In the AZIN Console, set the DATABASE_URL environment variable to point to your new Cloud SQL instance. AZIN auto-injects connection strings for services you add through the Console, so in most cases this is handled automatically.
Migrate Redis (if applicable)
If you use Heroku Key-Value Store (Redis), add a Cache service in the AZIN Console. This provisions a Memorystore (Redis) instance in your GCP account.
Update your REDIS_URL environment variable. Session data and cache entries will repopulate naturally. If you need to migrate persistent Redis data, use redis-cli --rdb to export and import.
Set environment variables
Import your Heroku config vars into AZIN:
# Review your .env.heroku file
# Remove Heroku-specific variables:
# HEROKU_APP_NAME, HEROKU_DYNO_ID, HEROKU_SLUG_COMMIT
# DATABASE_URL (replaced by Cloud SQL)
# REDIS_URL (replaced by Memorystore)
# Set remaining variables in the AZIN Console
# Or via CLI when available:
# azin env set SECRET_KEY=your-secret-key
# azin env set ALLOWED_HOSTS=yourdomain.comSet variables through the AZIN Console's environment variable panel. Variables are scoped per environment (production, staging, preview) and secrets are masked.
Replace Heroku add-ons
Heroku's 200+ add-on marketplace doesn't transfer. Here are the most common replacements.
| Heroku add-on | Replacement on AZIN | Notes |
|---|---|---|
| Heroku Postgres | Cloud SQL (PostgreSQL) | Managed in your GCP account. Automatic backups, HA option. |
| Heroku Key-Value Store | Memorystore (Redis) | Cloud-native Redis in your VPC |
| Heroku Scheduler | AZIN Cron Jobs | First-class service type. Standard cron syntax. |
| Papertrail / Logentries | AZIN Logs or Axiom / Betterstack | Real-time logs in Console. Or bring your own logging. |
| SendGrid / Mailgun | Continue using directly | Email services work with any platform. Update webhook URLs. |
| New Relic / Scout APM | Continue using or GCP Cloud Monitoring | APM agents work anywhere. Or use native GCP monitoring. |
| Cloudinary / S3 | Google Cloud Storage (GCS) | Object storage via AZIN's GCS integration |
| Heroku Connect (Salesforce) | Direct Salesforce API | No direct equivalent. Call Salesforce APIs from your app. |
Most third-party add-ons (SendGrid, New Relic, Sentry, Cloudinary) work with any platform — just update the webhook URLs and API endpoints. The only add-ons that require migration are Heroku-native services (Postgres, Redis, Scheduler).
Configure custom domains and DNS
In the AZIN Console:
- Add your custom domain under the Web Service settings
- AZIN provisions a TLS certificate automatically
- Update your DNS records to point to the AZIN-provided endpoint
DNS cutover strategy:
- Lower your TTL to 60 seconds 24-48 hours before migration
- Point DNS to AZIN once verification passes
- Monitor for 24 hours
- Raise TTL back to your normal value (3600 seconds)
Verify and cut over
Before switching DNS, verify your AZIN deployment.
Checklist:
- Application responds correctly on the AZIN preview URL
- Database connections work (Cloud SQL)
- Background workers are processing jobs
- Cron jobs fire on schedule
- Environment variables are all set
- Custom domain TLS is provisioned
- Logs are flowing in the Console
- Health checks pass
Parallel running: Run both Heroku and AZIN simultaneously for 24-48 hours. Route a percentage of traffic to AZIN using your DNS provider's weighted routing, or simply test the AZIN URL directly before cutting over.
Rollback plan: Keep your Heroku app running until you're confident. If something goes wrong after DNS cutover, revert DNS to Heroku. With a 60-second TTL, rollback takes about a minute.
Decommission Heroku
Once you've verified the AZIN deployment and run in parallel for your comfort period:
# Scale down Heroku dynos (keep the app for rollback)
heroku ps:scale web=0 worker=0 --app your-app
# After your confidence period (7-14 days), delete
heroku apps:destroy --app your-app --confirm your-appDon't rush this step. Keep Heroku running at minimum scale ($5/mo Eco dyno, as of February 2026) for a week or two as a safety net.
Deploy to your own cloud
Migrate from Heroku to infrastructure you own. AZIN deploys to your GCP account with zero Kubernetes overhead. Your cloud credits apply directly.
#Heroku vs AZIN: cost comparison
Heroku's per-dyno pricing gets expensive at scale. AZIN separates platform fees from cloud costs — you pay GCP directly for compute at cloud-native rates.
| Workload | Heroku cost (as of Feb 2026) | AZIN approach |
|---|---|---|
| Simple web app + Postgres | $32-50/mo (Basic dyno + Postgres Mini/Basic) | Platform fee + ~$15-30/mo GCP costs |
| Production app (2x Standard-1X + Postgres Standard) | $100-150/mo | Platform fee + cloud-direct pricing |
| Scaled workload (Performance-M + Postgres Standard) | $300-500/mo | Platform fee + GKE Autopilot autoscaling |
Key cost differences:
- GKE Autopilot first cluster is free — no cluster management fee. You pay only for pod resources (CPU and RAM). Porter's comparable EKS setup starts at an estimated ~$225/mo in underlying AWS costs (based on typical AWS EKS pricing, as of February 2026).
- Cloud credits apply. GCP for Startups credits offset your compute costs directly. Heroku doesn't accept cloud provider credits.
- Autoscaling saves money. AZIN scales horizontally on GKE Autopilot. Heroku charges per dyno regardless of utilization — a Standard-1X dyno costs $25/mo even when idle (as of February 2026, per heroku.com/pricing).
#Build system: Heroku buildpacks vs Railpack
Heroku uses buildpacks to detect and build your application. AZIN uses Railpack — the successor to Nixpacks, built by Railway and MIT-licensed.
Railpack scans your repository, detects your language and framework from project files (package.json, requirements.txt, Gemfile, go.mod), and generates an optimized container image. It supports 13+ languages out of the box (as of February 2026).
| Feature | Heroku Buildpacks | AZIN Railpack |
|---|---|---|
| Languages | Node.js, Python, Ruby, Java, Go, PHP, Scala, Clojure | Node.js, Python, Ruby, Java, Go, PHP, Rust, Elixir, Deno, .NET, C/C++ + more |
| Custom builds | Custom buildpacks | Custom Dockerfile |
| Procfile support | Yes | Yes |
| Caching | Layer caching | BuildKit layer caching |
| Configuration | app.json, Procfile | Auto-detection, optional railpack.json |
In most cases, apps that build on Heroku will build on AZIN without any changes. Railpack reads your Procfile and handles the rest. If you need full control, AZIN also supports custom Dockerfiles via BuildKit.
Head to Head
AZIN vs Heroku — Full Comparison
Feature-by-feature comparison: pricing, regions, scaling, compliance, and BYOC.
#Common migration issues
"My app uses a Heroku-specific feature"
Heroku Review Apps: AZIN has preview environments. Every PR gets a full-stack preview deployment with its own URL, database, and cache.
Heroku Pipelines: AZIN supports environments (production, staging). Deploy different branches to different environments with isolated configuration.
Heroku release phase: Railpack detects release commands in your Procfile. Database migrations run during the deploy phase, just like on Heroku.
Heroku HEROKU_* environment variables: Remove these. AZIN doesn't set HEROKU_APP_NAME, HEROKU_DYNO_ID, or HEROKU_SLUG_COMMIT. If your code references them, replace with equivalent AZIN variables or hardcoded values.
"My database is too large for pg_dump"
For databases over 50 GB, a dump-and-restore takes hours and means downtime. Consider:
- Logical replication: Set up PostgreSQL logical replication from Heroku Postgres to Cloud SQL. Replicate in real-time, then cut over when the replica is caught up. Near-zero downtime.
- Off-peak migration: Schedule the dump/restore during your lowest-traffic window. Put your app in maintenance mode during the restore.
- Incremental approach: Migrate read replicas first. Verify queries work. Then promote the Cloud SQL instance to primary.
"I depend on Heroku Connect for Salesforce"
Heroku Connect syncs Salesforce data to Heroku Postgres automatically. There's no direct equivalent on AZIN. Options:
- Use the Salesforce REST API directly from your app
- Use a third-party integration tool (Stitch, Fivetran, Airbyte) to sync Salesforce data to Cloud SQL
- If Heroku Connect is critical and can't be replaced, this may be a reason to stay on Heroku for now
"My app needs specific system dependencies"
If Railpack auto-detection doesn't cover your system dependencies (e.g., ImageMagick, FFmpeg, specific C libraries), use a custom Dockerfile. AZIN supports any valid Dockerfile.
FROM python:3.13-slim
RUN apt-get update && apt-get install -y \
imagemagick \
ffmpeg \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "myapp.wsgi:application", "--bind", "0.0.0.0:8000"]For more on Docker-based deployment, see the Docker deployment guide.
#Frequently asked questions
#Related pages
- AZIN vs Heroku — Feature-by-feature comparison of both platforms
- Best Heroku Alternatives in 2026 — 9 platforms compared on pricing, DX, BYOC, and scaling
- Deploy Django with AZIN — Django-specific deployment guide with Cloud SQL integration
- Deploy Docker with AZIN — Docker-based deployment for custom stacks
- Host PostgreSQL with AZIN — Managed Cloud SQL setup and configuration
- AZIN vs Railway — How AZIN compares to Railway for Heroku refugees
Heroku is a registered trademark of Salesforce, Inc. All product names and trademarks are the property of their respective owners. AZIN is not affiliated with or endorsed by the companies mentioned on this page.
Deploy on private infrastructure
Managed AI environments with built-in isolation. Zero DevOps required.