Monitoring application endpoints is one of those tasks that seems simple at first. You send an HTTP request, check the response, and alert someone if something goes wrong.
But once you start thinking about cost, scalability, maintenance, and operational overhead, the architecture becomes much more interesting.
Recently, I explored different ways to monitor multiple HTTP endpoints on AWS while keeping the monthly cost as low as possible.
The requirements were straightforward:
- Monitor 30 HTTP/HTTPS endpoints
- Perform a health check every 2 minutes
- Treat HTTP 200–499 responses as healthy
- Alert only on HTTP 500+ responses or connection failures
- Keep the monthly cost under $10
I evaluated three different approaches and compared their trade-offs.
Option 1 — Amazon EventBridge + AWS Lambda
This was the first architecture I considered.
The idea is simple.
Amazon EventBridge triggers a Lambda function every two minutes. The Lambda function loops through each endpoint, sends an HTTP request, and sends a notification if an endpoint returns a server-side error or cannot be reached.
Why This Approach?
The biggest advantage is that you only pay when the function runs.
There are no virtual machines to manage, no operating system updates, and no cron jobs running in the background.
Everything is serverless.
For a lightweight workload that executes every few minutes, this model is extremely efficient.
Another design decision was using Python's built-in urllib module instead of the popular requests package.
import urllib.request
import urllib.error
Although requests is an excellent library, urllib offers several advantages inside AWS Lambda:
- No external dependency packaging
- Smaller deployment package
- Lower memory footprint
- No Lambda Layers
- Less maintenance
For simple HTTP requests, the built-in library is more than sufficient.
Cost Estimation
With a two-minute schedule, the Lambda function runs approximately:
- 30 times per hour
- 720 times per day
- 21,600 times per month
Using:
- 128 MB memory
- Average execution time of 10 seconds
The estimated monthly cost is approximately:
| Service | Estimated Cost |
|---|---|
| AWS Lambda Compute | ~$0.45 |
| Lambda Requests | ~$0.004 |
| Amazon EventBridge | ~$0.02 |
| Total | ~$0.48/month |
Even if execution time doubled to around 20 seconds, the monthly cost would still remain comfortably below one dollar.
Keeping Costs Predictable
One thing I appreciated about this design is how easy it is to control spending.
Some simple practices help keep costs stable:
- Keep Lambda memory at 128 MB unless more memory is genuinely required.
- Set request timeouts between 5 and 10 seconds.
- Avoid unnecessary retries inside the function.
- Don't schedule executions more frequently than needed.
- Monitor execution duration using Amazon CloudWatch.
If endpoint response times increase over time, Lambda execution duration also increases, which directly affects compute cost.
Adding an AWS Budget and CloudWatch alarm provides an additional safeguard against unexpected spending.
Option 2 — Amazon CloudWatch Synthetics
The second option was Amazon CloudWatch Synthetics.
Unlike the Lambda solution, CloudWatch Synthetics is a fully managed monitoring service designed specifically for availability testing.
The architecture becomes much simpler.
At first glance, this seems like the ideal solution.
No custom code.
Built-in metrics.
Native CloudWatch integration.
Automatic alerting.
However, pricing quickly changes the conversation.
With 30 endpoints checked every two minutes, the estimated monthly cost becomes significantly higher than the Lambda-based solution.
For small-scale monitoring, CloudWatch Synthetics is convenient.
For cost-sensitive workloads with many frequent checks, it may not be the most economical option.
Option 3 — Amazon EC2 with Cron
The final option was using a small EC2 instance running a scheduled Python script through cron.
This approach provides complete control over the runtime environment.
The health check script can be modified freely, additional tooling can be installed, and debugging is straightforward.
However, that flexibility comes with operational responsibility.
Unlike Lambda, an EC2 instance requires:
- Operating system maintenance
- Security patching
- Instance monitoring
- Storage management
- Infrastructure management
For lightweight workloads, the operational overhead begins to outweigh the benefits.
Using a small instance such as t3.micro, together with an 8 GB gp3 volume, results in an estimated monthly cost of around $8–9, regardless of whether the script runs once or thousands of times.
Comparing the Three Approaches
| Criteria | EventBridge + Lambda | CloudWatch Synthetics | EC2 + Cron |
|---|---|---|---|
| Infrastructure Management | None | None | Required |
| Server Maintenance | No | No | Yes |
| Custom Logic | Excellent | Limited | Excellent |
| Cost Efficiency | Excellent | Lower for this use case | Moderate |
| Scalability | High | High | Depends on instance size |
| Best Use Case | Lightweight scheduled monitoring | Availability testing | Long-running or highly customized workloads |
My Takeaway
What I found interesting during this comparison wasn't just the price difference—it was how architecture decisions are driven by workload characteristics.
All three solutions solve the same problem.
The difference lies in how much operational responsibility you're willing to take on.
If the workload is lightweight, runs on a predictable schedule, and doesn't require long-running processes, a serverless approach makes a lot of sense.
If you need browser-based testing, synthetic user journeys, or deep integration with CloudWatch, CloudWatch Synthetics offers powerful capabilities despite the higher cost.
If complete control over the runtime environment is the priority, an EC2 instance remains a valid option, though it introduces additional operational overhead.
For this particular scenario—30 endpoints checked every two minutes with a strict monthly budget—the EventBridge and Lambda architecture provided the best balance between simplicity, scalability, and cost.
Sometimes the most efficient architecture isn't the one with the most features.
It's the one that solves the problem while staying as simple as possible.
Have you designed a similar health monitoring solution on AWS?
I'd be interested to hear whether you chose a serverless approach, CloudWatch Synthetics, or something entirely different.



Top comments (0)