Your application is only as reliable as the servers it runs on. The most carefully tested Laravel codebase becomes worthless when a deployment corrupts the database, a disk fills up at 3am, or a certificate expires without anyone noticing. Web application infrastructure is the set of decisions and systems that prevent those failures.
Since 2005, we have provisioned and managed infrastructure for 50+ Laravel applications. Some of those systems have been running continuously for over a decade. The patterns described here come from that history: real failures, real fixes, and the operational discipline that keeps production systems alive.
The Constraint: Why Infrastructure Decisions Compound
Most development teams treat infrastructure as an afterthought. The application gets attention; the server gets whatever the default setup provides. This works until it does not.
A single misconfigured Nginx worker pool causes request queuing under load. A database running on the same disk as the application means a large import fills the volume and crashes both. An SSL certificate that renews manually gets forgotten and takes the site offline on a Saturday morning.
The compounding effect: Every infrastructure decision constrains future options. The hosting provider you choose determines your scaling options. Your deployment method determines your rollback speed. Your monitoring setup determines whether you find problems or your users do.
The constraint is this: infrastructure must be reproducible, observable, and recoverable. If you cannot rebuild a server from scratch in under an hour, you do not have infrastructure. You have a snowflake.
The Naive Approach: Manual Servers and Hope
The tutorial version of deployment looks like this: SSH into a server, run git pull, run composer install, run php artisan migrate, restart PHP-FPM. It works on the first deploy. It fails on the fiftieth.
The problems accumulate gradually. File permissions drift. Environment variables get edited directly on the server and never recorded anywhere. A failed migration leaves the database in a half-applied state. A composer install downloads a new dependency version that breaks the application, and there is no way to roll back without restoring a full backup.
The pattern extends to hosting decisions. A team starts on shared hosting because it is cheap. The application grows. Shared hosting throttles CPU during peak hours. The response is to upgrade to a bigger plan, then a VPS, then a managed platform, each migration requiring a full rebuild because nothing was documented or automated.
The Robust Pattern: Infrastructure as a Managed System
We treat web application infrastructure as code, not as a set of manual configurations. Every server we provision follows a repeatable process. Every deployment is atomic. Every failure mode has a documented recovery path.
The stack
Our standard Laravel infrastructure stack uses these components, each chosen for a specific reason and managed against a specific failure mode.
Ubuntu LTS on a VPS
Hetzner or DigitalOcean, depending on region and requirements. Long-term support releases provide security patches without breaking changes.
Laravel Forge for provisioning
Server provisioning, SSL management, and deployment orchestration. Handles PHP installation, Nginx configuration, and Let's Encrypt certificates.
Nginx + PHP-FPM
Nginx handles request routing and SSL termination. PHP-FPM manages application worker processes, with pool sizes calculated from available memory (each worker consumes roughly 30-50MB).
PostgreSQL + Redis
PostgreSQL on a separate volume or server for I/O isolation. Redis provides sub-millisecond reads for cache, session storage, and queue processing.
This is not a complex stack. It is deliberately simple. Fewer moving parts means fewer failure points, and every component has been battle-tested across hundreds of thousands of production hours.
Why Laravel Forge
We use Laravel Forge to provision and manage servers. Forge handles the tedious parts of server setup while still allowing SSH access for the remaining 10% that requires custom configuration. The alternative is maintaining Ansible playbooks or shell scripts for server provisioning. We have done both. Forge reduces the operational burden for the 90% case.
Forge also provides a deployment pipeline: pull code, install dependencies, run migrations, build assets, restart PHP-FPM. Each step is logged. Failures halt the pipeline before the application is affected.
Hosting Decisions: VPS, Cloud, and Managed Platforms
Choosing where to host a web application is a decision with long-term consequences. The wrong choice costs money, limits scaling options, or creates vendor dependency.
VPS hosting (our default)
For most Laravel applications serving under 50,000 daily users, a well-configured VPS is the correct choice. A single server with 4 vCPUs, 8GB RAM, and SSD storage handles more traffic than most businesses generate.
We default to Hetzner for European hosting. The cost difference is significant: a Hetzner CPX31 (4 vCPU, 8GB RAM, 160GB SSD) costs approximately €15/month. The equivalent DigitalOcean droplet costs $48/month. The equivalent AWS EC2 instance costs roughly $70/month before storage and data transfer. That price gap compounds over years.
VPS hosting also means you own your infrastructure. No platform lock-in, no proprietary APIs, no sudden pricing changes.
When to use cloud platforms
AWS, Google Cloud, and Azure make sense when you need specific managed services: object storage with CDN (S3 + CloudFront), managed database clusters with automated failover, or serverless compute for unpredictable workloads.
Cost warning: Cloud billing is notoriously difficult to predict. Egress charges, NAT gateway fees, and per-request pricing on managed services can triple the expected monthly cost. We have seen AWS bills double overnight because a misconfigured logging pipeline was writing gigabytes to CloudWatch.
Our rule: start with a VPS. Move specific services to cloud platforms when you have a concrete requirement that a VPS cannot satisfy. Do not start on AWS because it feels professional. Start on a VPS because it is simple, fast, and cheap.
Managed application platforms
Laravel Vapor, Railway, and similar platforms abstract away server management entirely. These platforms suit applications with highly variable traffic or teams with no infrastructure expertise. The cost per request is higher, but the operational burden is near zero. The limitation is control: when something goes wrong at the platform level, you wait for their support team.
Zero-Downtime Deployments
Every production deployment we run follows the atomic deployment pattern. A deployment pipeline is not a luxury. It is the difference between a five-second rollback and a two-hour recovery.
Create a new release directory
Clone or pull the latest code into a fresh directory on the server. Install Composer dependencies with --no-dev --optimize-autoloader.
Run migrations and build assets
Run database migrations with a pre-flight check. Build frontend assets if required. Run a health check against the new release.
Swap the symlink
Point the current symlink at the new release directory. This is atomic. The application serves the old release until the exact moment the symlink changes.
Reload and clean up
Graceful PHP-FPM restart (no dropped connections). Purge old releases, keeping the last five for rollback. Rollback means pointing the symlink at a previous directory: a one-second operation.
The naive approach (running git pull in the live directory) means the application serves partially-updated code during deployment. A request hitting the server mid-pull might load old controllers with new views. This causes errors that are difficult to reproduce and diagnose.
Monitoring and Alerting
Monitoring without alerting is data collection. Alerting without monitoring is guesswork. We configure both.
| Metric | Alert Threshold | Why It Matters |
|---|---|---|
| HTTP 5xx rate | Above 1% | Application errors affecting users |
| Response time (p95) | Above 500ms | Performance degradation under load |
| Disk usage | 80% warning, 90% critical | Most common infrastructure failure |
| Memory | Below 500MB free | Process starvation and OOM kills |
| SSL certificate expiry | 14 days before expiry | Auto-renewal can fail silently |
| Queue depth | Above configured threshold | Background work is backing up |
Lessons from production
Certain monitoring lessons only come from experience. These are the ones that have saved us repeatedly.
--max-jobs=1000).Backup Strategy
We follow the 3-2-1 rule: three copies of data, on two different storage types, with one copy off-site.
Database backups
Automated daily PostgreSQL dumps, stored locally and replicated to off-site object storage. Point-in-time recovery enabled for production databases.
Uploaded files
Synced to off-site storage nightly. Large media files stored directly in object storage (S3 or equivalent) rather than on the application server.
Server configuration
Managed through Forge. A new server can be provisioned from scratch in under 30 minutes.
The critical discipline is testing restores. A backup that has never been restored is a hope, not a backup. We test database restores monthly and document the recovery time. If a full restore takes longer than the business can tolerate, we adjust the strategy.
Scaling: Vertical First, Then Horizontal
Premature scaling wastes money and adds operational complexity. Most Laravel applications never need horizontal scaling. Vertical scaling (upgrading the server) is simpler, cheaper, and sufficient for the vast majority of workloads.
Vertical scaling
A single well-configured server handles more traffic than most teams expect. Nginx serves static assets from memory. Redis eliminates repeated database queries. PHP-FPM worker tuning ensures available memory is used efficiently. When a server is genuinely under-resourced, the fix is straightforward: increase RAM, add CPU cores, switch to faster storage.
When horizontal scaling is necessary
Horizontal scaling becomes necessary when a single server cannot handle the requirements regardless of size, or when you need geographic distribution for latency reasons. It requires architectural changes that are best planned before they are needed.
The decision rule: if your monthly hosting cost is under £500 and you are not experiencing performance problems, you do not need horizontal scaling. Invest that engineering time in application-level optimisation instead: query optimisation, caching strategies, and efficient background job processing.
Infrastructure as an Asset
Web application infrastructure is not a cost centre. It is an operational asset that determines uptime, deployment speed, and recovery capability.
-
Deployments happen multiple times per day Atomic deploys with one-second rollback. No stress, no downtime, no maintenance windows.
-
Failures are detected before users notice Continuous monitoring with targeted alerts. Problems found in minutes, not days.
-
Recovery follows a documented procedure Tested backups, rehearsed restores, known recovery times. No panicked improvisation.
-
Provider independence Standard Linux servers on standard infrastructure. Move providers in a day, not a quarter.
This is closely related to the question of owning versus renting your systems. Infrastructure decisions also affect your security and operational posture. Every component in the stack is a potential attack surface. Fewer components, kept current and monitored, means a smaller surface to defend.
Get Your Infrastructure Right
Since 2005, we have built and managed infrastructure for businesses that depend on their web applications daily. The first conversation is free and comes with no obligation.
Book a discovery call →