How to Monitor Your Cloudflare R2 Storage with Vigilmon
Cloudflare R2 is an S3-compatible object storage service with zero egress fees. It's increasingly popular for storing user uploads, static assets, AI model weights, and application backups. Like any storage infrastructure, R2 needs monitoring to detect outages and access failures before they cascade into application errors.
This guide explains how to monitor your Cloudflare R2 storage with Vigilmon.
Why Monitor Cloudflare R2?
R2 failures manifest as:
- 403 Forbidden errors from expired or misconfigured API tokens
- CORS failures blocking direct browser uploads
- Custom domain outages when your R2 public bucket's custom domain fails
- Regional connectivity issues for specific R2 endpoints
- Signed URL failures when your URL signing logic breaks
Monitoring R2's Public Bucket URL
If you're using R2 with a public bucket or custom domain, the easiest monitoring approach is to check a known object's URL directly:
1. Upload a Health Check Object
Upload a small static file to your R2 bucket that serves as a health check sentinel:
# Using wrangler CLI
echo '{"status":"ok","service":"r2"}' > health.json
wrangler r2 object put your-bucket/health.json --file=health.json
Make this object publicly accessible.
2. Monitor the Object URL
In Vigilmon:
- Go to vigilmon.online → Add Monitor
- Type: HTTP(S)
- URL:
https://pub-your-account-id.r2.dev/health.json(or your custom domain) - Interval: 1 minute
- Timeout: 10 seconds
- Expected status: 200
- Keyword check:
"status":"ok"
This monitors both R2 availability and your CDN layer (Cloudflare's cache in front of R2).
Monitoring R2 API Access (For Private Buckets)
For private R2 buckets accessed via the S3-compatible API:
import boto3
import botocore
from flask import Flask, jsonify
app = Flask(__name__)
r2_client = boto3.client(
"s3",
endpoint_url="https://your-account-id.r2.cloudflarestorage.com",
aws_access_key_id="your-r2-access-key-id",
aws_secret_access_key="your-r2-secret-key",
config=botocore.config.Config(signature_version="s3v4"),
region_name="auto"
)
@app.route("/health/r2")
def r2_health():
try:
# Lightweight: head request on the health check object
r2_client.head_object(Bucket="your-bucket", Key="health.json")
return jsonify({"status": "ok"})
except botocore.exceptions.ClientError as e:
code = e.response["Error"]["Code"]
if code == "404":
return jsonify({"status": "error", "reason": "health object missing"}), 503
elif code in ("403", "AccessDenied"):
return jsonify({"status": "error", "reason": "access_denied"}), 503
return jsonify({"status": "error", "code": code}), 503
except Exception as e:
return jsonify({"status": "error", "message": str(e)}), 503
Add this endpoint to Vigilmon with a 5-minute check interval.
Monitoring R2 Upload Capabilities
If your application lets users upload directly to R2 (via presigned URLs), you need to monitor the upload path too:
@app.route("/health/r2/upload")
def r2_upload_health():
try:
# Try to generate a presigned URL (doesn't actually upload)
url = r2_client.generate_presigned_url(
"put_object",
Params={"Bucket": "your-bucket", "Key": "health-upload-test.tmp"},
ExpiresIn=60
)
if url and url.startswith("https://"):
return jsonify({"status": "ok", "presigned_url_generated": True})
return jsonify({"status": "error"}), 503
except Exception as e:
return jsonify({"status": "error", "message": str(e)}), 503
Presigned URL generation fails if your R2 credentials are invalid, bucket doesn't exist, or R2 API is unreachable — without making any actual PUT request.
Custom Domain Monitoring
Many R2 deployments use Cloudflare custom domains. Monitor the custom domain separately from the R2 origin:
-
Monitor 1: Your custom domain (
https://assets.yourdomain.com/health.json) -
Monitor 2: The R2 public URL (
https://pub-xxx.r2.dev/health.json)
If Monitor 1 fails but Monitor 2 is healthy, the issue is in your Cloudflare DNS/cache config, not R2 itself.
Alert Configuration
| Scenario | Priority | Response |
|---|---|---|
| R2 completely unreachable | P0 | Check Cloudflare status page |
| 403 Access Denied | P1 | Rotate R2 API keys immediately |
| Custom domain down, R2 up | P2 | Fix Cloudflare DNS/routing |
| Upload presigning fails | P1 | Check R2 token permissions |
Checking Cloudflare Status
When Vigilmon alerts on R2 issues, check cloudflarestatus.com to distinguish R2 platform issues from your own configuration problems.
Conclusion
Cloudflare R2's zero egress fee model makes it attractive for high-traffic applications — but that traffic concentration makes outages more impactful. Set up R2 monitoring with Vigilmon at vigilmon.online and get instant alerts when your storage layer fails.
Top comments (0)