Let's Connect

Server racks in a modern data center

I have deployed Laravel to AWS for startups doing a few hundred users a day and platforms handling millions of requests. The architecture below is the shape I keep coming back to, because every piece scales independently and nothing is exotic.

The core architecture

  • Application Load Balancer terminating TLS and health-checking instances
  • EC2 instances (or ECS Fargate containers) running PHP-FPM + Nginx in an Auto Scaling Group
  • RDS MySQL or PostgreSQL with Multi-AZ for failover
  • ElastiCache Redis for cache, sessions, and queues
  • S3 for user uploads, served through CloudFront
  • A small dedicated worker instance (or ECS service) for queue workers and the scheduler

Make the app stateless first

Before anything scales horizontally, the application must hold no local state: sessions in Redis, files in S3 via the s3 filesystem driver, and cache in Redis. Once that is true, adding or removing instances is a non-event, and deploys stop being scary.

Separate web and worker workloads

Queue workers and cron (the Laravel scheduler) should not run on web instances. Auto-scaling kills instances; a terminated worker mid-job is a corrupted import. A small dedicated worker tier with Supervisor keeps background processing predictable, and you can scale it on queue depth instead of web traffic.

Deploys without downtime

My pipeline builds a release artifact (composer install, npm build, config:cache), ships it, runs migrations with --force, and switches a symlink — or, on ECS, rolls a new task definition. Either way the rollback story is 'point back at the previous release', which has saved me more times than I can count.

Cost notes from real projects

Most teams over-provision EC2 and under-provision RDS. Start with smaller app instances behind the ALB (they scale out), put the budget into the database, and turn on RDS Performance Insights — it is the best money-saver AWS gives you for free.