Currently Available: Need a skilled Software Developer for your next project?
Categories
Linux Servers

What 99.9% Uptime Really Requires for a Small Laravel and MySQL App on a Budget

For a small Laravel app that uses MySQL, 99.9% uptime means users can reach the service for at least 99.9% of a set period. In a 30-day month, the service can be down for 43.2 minutes total. That time includes failures, deployments, and the time it takes to detect and fix problems.

A particular server or database plan does not guarantee this target. You must define what counts as available, find failures quickly, and restore service reliably. A single-host setup costs less, but an operator must notice a problem and bring the app back. Redundancy can shorten some recovery delays, but it also adds cost and work.

Define what counts as uptime

Measure whether users can complete a meaningful task, not just whether a server responds. For example, a Laravel app might count as available only when a user can load a page and complete a key database-backed action. A health endpoint that returns success while the database is unavailable would give an incomplete picture.

A service-level indicator (SLI) is the measurement, such as the share of successful requests. A service-level objective (SLO) is the target for that measurement, such as 99.9% over a month. A provider’s service-level agreement (SLA) is a contractual commitment for a defined service. The provider’s SLA does not set the uptime of the complete app. The app depends on its code and hosting, and its database and deployments also affect availability, along with any other dependencies.

Choose the measurement window and failure rules before comparing hosting options. The Google SRE availability table gives 43.2 minutes of allowed downtime for a 30-day month and 8.76 hours for a year at 99.9%. The monthly allowance changes with the length of the month. Planned maintenance also consumes the allowance if your measurement counts it; excluding it can make the metric less representative of users’ experience.

A five-minute outage uses about 11.6% of a 30-day month’s allowance. The remaining time must cover every other interruption, including a failed release or a database recovery. Treating the allowance as an error budget, or the amount of failure permitted by the SLO, helps make trade-offs concrete. When an incident consumes a large share, investigate its cause before adding more change risk. Google’s error-budget guidance describes this approach as a way to balance reliability work and releases.

Monitor the Laravel service users depend on

Laravel’s /up health route can report whether the app booted without an exception. By default, it returns HTTP 200 when boot succeeds and HTTP 500 when boot fails. Laravel also lets developers add checks for dependencies such as a database. The deployment documentation explains the route and its health-check event.

A successful /up response still does not prove that a customer can complete a critical task. Check the public service from outside its hosting environment, and add a synthetic check that exercises a representative user journey when practical. A synthetic check is an automated test that sends requests as a user would. AWS recommends monitoring workload components and testing customer-facing behavior in its reliability guidance.

An alert speeds recovery only when it reaches someone who can act. Choose where alerts go and who can inspect the app and database, roll back a release, or restore service. Monitor background work when users depend on it. Laravel’s queue documentation says production workers need a process monitor to restart them if they exit. After a deployment, reload workers so they use the new code. If the app relies on scheduled tasks, check that the system cron entry still runs Laravel’s scheduler. A broken scheduler can stop those tasks even while web requests succeed.

Deployments count toward uptime too. Laravel maintenance mode returns a 503 response, and the configuration documentation notes that entering maintenance mode requires several seconds of downtime. Keep a clear rollback path and ensure the deployment reloads long-running workers. Laravel also warns that production APP_DEBUG should be false because debug output can expose sensitive configuration.

Separate database recovery from database failover

A backup helps recover data after loss or corruption. It does not keep the database available during an outage. Restoring a backup takes time, and the restored data may not include the most recent changes.

MySQL’s backup guidance recommends periodic full backups and incremental backups using binary logs. Those logs can support recovery to a point in time when they are available and retained. Store backups outside the main database environment when possible. A failure in that environment is then less likely to affect both the database and its backups. Monitor backup jobs, and periodically restore a copy in a test environment.

Set two recovery goals. The recovery time objective (RTO) is how long the service can take to return. The recovery point objective (RPO) is how much recent data the business can afford to lose, expressed as time. Google Cloud recommends testing restores and measuring these goals in its recovery-testing guidance. Until a restore has been tested, a successful backup job does not show how long recovery will take or how much data it will recover.

A MySQL replica does not automatically take over when the original database fails. Failover means directing the app to a healthy database. MySQL’s replication FAQ explains that automatic failover requires active monitoring and additional tools. For manual failover, someone must change the database destination or the relevant DNS. A managed database with standby capacity can shift some of this work to the provider. Check how it handles failover and data recovery, and review the contract.

Provider commitments also cover only the service named in the contract. For example, DigitalOcean documents a 99.95% monthly SLA for MySQL clusters with at least one standby node and 99.5% for clusters without one in its cluster creation documentation. Those figures apply to the documented database configurations, not automatically to the Laravel host, deployment, or complete user experience. Standby nodes also increase cost.

Spend for the failure you cannot accept

A lean setup can improve detection and recovery without adding custom clustering. Run external checks against the public app. Supervise queue workers and verify scheduled tasks. Keep separate database backups, and practice restoring them. Write down where alerts arrive and how to roll back or restore. Then compare actual failures and deployment interruptions with the monthly error budget.

These measures make failures easier to detect and recover from, but a single app host or database node can still take the service offline. If a host failure would leave the service down until an operator steps in, compare that recovery time with the remaining budget. If you have made a firm 99.9% commitment, assess redundancy for both the app and database tiers. Confirm that someone responsible can respond to alerts.

No single monthly price applies to every setup that meets 99.9%. Provider and region affect costs, as do capacity and standby configuration. Monitoring and support also affect the price. Compare those costs with the time it takes to run and recover a simpler setup. A low-cost single-node design can work when the business accepts manual recovery and has tested restore times. It does not fit a strict target if nobody can respond promptly or the business has never tested its recovery plan.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *