Last updated 7 August 2026
Symfony deployments divide cleanly into two kinds, and confusing them is where most of the pain comes from. The first is a site: controllers, Twig, a database, deployed by uploading files. Shared hosting runs that perfectly well and costs almost nothing.
The second is an application: Messenger consumers processing a queue, a scheduler firing recurring tasks, Doctrine migrations that must run once and not once per replica, and a container cache that has to be compiled during a build rather than by the first unlucky visitor. That version of Symfony needs a platform that understands build steps, release commands and worker processes — and the difference in hosting cost between the two is much larger than the difference in code.
Unlike Laravel, Symfony has no first-party hosting platform to anchor the comparison, so what follows is general-purpose platforms judged on how well they fit the framework's assumptions.
The short version: Render and Railway are the smoothest managed starts, Fly.io is the cheapest if you are content to run your own database, and Granite — our own platform — fits when the app, its MySQL or Postgres, its Valkey and its consumers should live in one project. If your Symfony project is a small site with no queue, shared hosting beats every option on this page and we will say so more than once.
At a glance
| Provider | From /mo | Free tier | Managed DB | Persistent disk | Deploy from |
|---|---|---|---|---|---|
| Fly.io | ~$2 | Postgres (unmanaged app) | Dockerfile, buildpack | ||
| Railway | $5 | yes ($1 credits) | Git, Dockerfile, template | ||
| Render | $7 | yes (spins down) | Git, Dockerfile | ||
| Granite | $9 | from Advanced | Git, Docker image | ||
| Koyeb | $29 | limited | Serverless Postgres | Git, Dockerfile | |
| Google Cloud Run | usage-based | yes (monthly allowance) | via Cloud SQL | no (use GCS) | Container image |
Entry prices as published by each provider on 7 August 2026, sorted cheapest first. Usage, bandwidth and databases are billed on top almost everywhere — treat this column as a starting point, not a monthly bill.
PaaS, serverless or a plain VPS?
Shared hosting deserves the first mention, as it does for Laravel, because for a large share of Symfony projects it is genuinely adequate rather than a compromise. Point the document root at public/, upload a build, and a content-driven site works. The line is the same one: the first Messenger consumer, or the first scheduled task that matters, turns a cheap host into an evening's work per deploy.
A managed platform is where an application with a queue belongs. What you are buying is not the ability to execute PHP — that is everywhere — but a build step where composer install and cache:warmup can run, a release phase for migrations, and long-running processes for consumers, with a managed database next to them.
Serverless fits Symfony awkwardly for a structural reason. A consumer must run continuously by definition, so it cannot scale to zero; you end up with a request-driven web tier plus an always-on worker, at which point much of the appeal has gone. It remains reasonable for a stateless API with genuinely bursty traffic, especially if the container ships a pre-warmed cache.
Content-driven site, no consumers, no scheduled work that matters, rare deploys
Shared hosting
Cheap and adequate, right up until the first background message.
Any cPanel host
Messenger consumers, a scheduler and migrations on every release
Managed platform
Build step, release phase and workers as first-class things, beside a managed database.
Granite · Railway · Render
Stateless API, bursty traffic, and you are already inside GCP
Serverless
Free while idle — with the cache warmed in the image and consumers hosted elsewhere.
Cloud Run · Koyeb
The options
Fly.io
- Best for
- Teams comfortable operating their own database who want several regions and per-second billing.
- Pricing
- Pay as you go. The smallest shared-cpu-1x machine with 256 MB RAM works out at roughly $2.02/month, billed per second.
- Takes your Dockerfile, so the PHP version, the extensions and whether you run PHP-FPM or FrankenPHP are entirely your decisions.
- Multi-region deployment and Anycast routing are first-class.
- Per-second billing, so stopped machines cost only storage.
- MySQL or Postgres is a Fly app you run and back up yourself — for Symfony, where Doctrine is the centre of the application, that is a real commitment.
- Messenger consumers and the scheduler are processes you define and supervise rather than platform features you enable.
- No free tier for new organisations since October 2024.
Railway
- Best for
- Getting Symfony, MySQL and Redis running together without deciding anything up front.
- Pricing
- Hobby is $5/month including $5 of usage credits; Pro is $20/month per workspace including $20 of credits. A free plan gives $1 of monthly credits, and there is a 30-day trial.
- Databases and Redis sit alongside services in the same project and reach each other privately.
- Workers and cron are ordinary resource types, so Messenger and the scheduler have somewhere proper to live.
- A free plan and a 30-day trial for evaluation.
- Usage-based billing on top of the base fee is hard to forecast.
- The Pro fee is per workspace, which adds up for small teams.
Render
- Best for
- A conventional Symfony production setup with a predictable monthly bill.
- Pricing
- Free web services are available but spin down after 15 minutes without traffic. The cheapest paid instance, Starter, is $7/month for 0.5 vCPU and 512 MB RAM.
- Release commands are first-class, so doctrine:migrations:migrate runs once per deploy in the right place.
- Background workers and cron jobs cover Messenger consumers and the scheduler cleanly.
- Managed Postgres and Redis, plus a real free tier for evaluating.
- Managed MySQL is not offered, so a Symfony project whose Doctrine mapping assumes MySQL either moves to Postgres or looks elsewhere.
- Free services spin down after 15 minutes idle.
Granite
- Best for
- A Symfony application whose database, cache and consumers should sit in the same project as the web app.
- Pricing
- Hobby is $9/month and includes $15 of monthly usage credits. Advanced is $39/month with $50 of credits, Professional $149/month with $200. Every plan has unlimited workspace seats.
- Managed MySQL as well as Postgres, plus Valkey for Messenger transports and cache — all over internal DNS with no public endpoint.
- Web app, Messenger consumer and scheduler are three resources built from one image, so a consumer can never run older code than the site that enqueued the message.
- Cron jobs are a resource type, which is what the Symfony scheduler wants.
- S3-compatible storage with a CDN for uploads, and flat plan pricing that does not move with traffic.
- No free tier — the cheapest way in is $9/month, against genuinely cheap shared hosting.
- Nothing here is Symfony-aware: cache warmup, migrations and consumer restarts are steps you define yourself.
- Fewer regions than the hyperscalers, and no multi-region routing yet.
Koyeb
- Best for
- Low-traffic Symfony apps where paying nothing while idle matters more than anything else.
- Pricing
- The Pro plan is $29/month; Scale is $299/month. Serverless Postgres has a small free allowance.
- Scale-to-zero with edge locations included.
- Managed Postgres available on the platform.
- The highest entry price of the managed options here.
- Scale-to-zero does not apply to a Messenger consumer, which has to keep running — so the saving covers only part of the bill.
Google Cloud Run
- Best for
- Stateless Symfony services with bursty traffic, for teams already invested in GCP.
- Pricing
- No monthly fee. You pay per request and per resource-second, with a monthly free allowance. Cloud SQL and networking are billed separately.
- Scales to zero and has effectively no ceiling.
- Takes any container image, so your PHP version and extensions are pinned by your own Dockerfile.
- A warmed Symfony cache baked into the image means the cold start is a PHP boot rather than a compile.
- No persistent disk, so anything under var/ that you expected to persist — and every upload — has to move to a bucket first.
- Messenger consumers and the scheduler do not fit a request-driven model and need separate infrastructure.
- Database, cache and secrets are separate GCP products you assemble and bill separately.
What a Symfony app actually needs from a host
- A real build step
- composer install --no-dev --optimize-autoloader and cache:warmup belong in the image build, not in the container's start command. A Symfony application with a cold cache compiles the service container on the first request, which means the first visitor after every deploy pays for it — and on a read-only or ephemeral filesystem it may not work at all.
- APP_ENV=prod, and the debug toolbar off
- The single most consequential environment variable here. In dev, Symfony recompiles the container on changes, logs verbosely and serves the profiler — all of which are catastrophic in production, both for performance and because the profiler exposes your configuration. Set it explicitly rather than relying on a default.
- Migrations as a release step
- doctrine:migrations:migrate --no-interaction must run once per deploy, after the build and before the new version takes traffic. In the start command every replica races against the same schema. Look for a release command or pre-deploy hook, and treat its absence as a genuine limitation rather than an inconvenience.
- Messenger consumers restart on deploy
- messenger:consume loads the container once and keeps it in memory, so a consumer started before a deploy keeps running the old code afterwards. Every deploy must end with messenger:stop-workers, and the platform has to restart the process. This produces the most confusing class of bug in a PHP application: the site is correct and the background work is a week stale.
- The scheduler needs real cron
- Whether you use Symfony Scheduler or plain cron entries, something has to fire on a timetable outside the request cycle. A platform with cron as a resource type makes this configuration; without one you end up running a sleep loop in a container and hoping it never dies quietly.
- APP_SECRET, exactly once
- It signs cookies, CSRF tokens and remember-me credentials. Generate it once and supply it as an encrypted environment variable; a value that changes per deploy or differs between replicas invalidates sessions and CSRF tokens in ways that look like a random, intermittent bug.
- var/ is not storage
- var/cache and var/log must be writable, but nothing in them should be expected to survive — the container filesystem is discarded on deploy and not shared between replicas. Logs belong on stdout where the platform collects them, and user uploads belong in object storage through Flysystem, not under public/.
- Trusted proxies behind the load balancer
- Every platform here terminates TLS in front of your container, so Symfony sees plain HTTP and generates http:// URLs, breaking absolute links and redirects in ways that present as a certificate problem. Configure framework.trusted_proxies so the X-Forwarded headers are honoured. It is two lines and it reliably costs an afternoon the first time.
- PHP-FPM or a worker runtime
- Classic PHP-FPM boots the framework on every request and keeps a pool of children, each holding its own copy. A worker runtime such as FrankenPHP boots once and serves many requests, which is markedly faster and changes the memory profile — but it also means your code must not leak state between requests. Decide before sizing the instance, because the two shapes want different plans.
So which should you pick?
A content site with no queue. Shared hosting, honestly. Nothing on this page will serve you better for the money until the application grows a background consumer.
A conventional production app, least ceremony. Render. Release commands, workers and cron behave the way the Symfony docs assume — provided you are on Postgres rather than MySQL.
Fastest path to a running stack. Railway, which will have Symfony, MySQL and Redis talking to each other the same afternoon.
Symfony as one part of a larger system. This is where we would argue for Granite. Managed MySQL — still the default assumption in a great many Symfony projects — sits beside the app with Valkey for Messenger transports and cache, all over internal DNS with no public endpoint. The web app, the consumer and the scheduler are three resources from a single image, so nothing can drift out of sync, and cron is a resource type rather than a workaround. Flat plans from $9/month with $15 of usage credits.
Running other PHP or JavaScript services beside it? The Laravel and Next.js comparisons cover the same platforms with different conclusions, and the app platform page covers workers and cron jobs in detail.
Hosting for other stacks
Six ways to run a Go binary, from a $2 machine to scale-to-zero — and why Go stays cheap longer.
Seven options weighed on the things Django actually needs: media storage, a real Postgres, Celery workers and enough memory for gunicorn.
Vercel and six alternatives, weighed on the things that actually break when you self-host: ISR across replicas, image optimization and build-time env vars.
Six platforms plus Kamal, weighed on what Rails really needs: a release phase for migrations, a job runner, Active Storage and enough memory for Puma.
Laravel Cloud and six alternatives, weighed on queue workers, the scheduler, writable storage and the caches you must rebuild on every deploy.
Six platforms weighed on what an ASGI service actually needs: worker processes, connections that stay open, and a database pool that does not multiply out of control.
Seven options for the framework that ships no opinions — weighed on the WSGI server you have to bring, the session key you must keep stable, and the extensions that decide the rest.
Seven platforms for a framework that renders on every request — weighed on streaming, adapters, and how far the loaders sit from the database.
Six platforms weighed on what the JVM actually asks for: memory it is allowed to use, a container that knows its own limits, and a start-up you can afford to repeat.
Six places to run a container image, compared on what actually bites: architecture mismatches, registry access, signal handling and the volume you assumed would still be there.
Five ways to serve HTML that is already written — and an honest note about which of them we are not the right answer for.