Fastly CDN
Introduction
Fastly is a modern edge cloud platform built on top of Varnish Cache that provides Content Delivery Network (CDN), security, and edge computing services. Unlike traditional CDNs, Fastly provides real-time content updates (measured in milliseconds, not minutes) and powerful VCL customization capabilities for each service domain.
This documentation covers how Fastly operates as a CDN and how VCL configuration is managed and deployed for different domains like www.prabasiva.com and api.prabasiva.com.
Fastly CDN Architecture
Key Components
- Point of Presence (POP): Fastly has 80+ POPs globally, each running Varnish
- Shield: Optional intermediate cache layer between edge and origin
- Anycast Network: DNS routes clients to nearest POP automatically
- VCL Engine: Varnish-based request processing per domain
- Real-time Purging: Instant cache invalidation across all POPs
Request Flow Through Fastly CDN
Multi-Domain Service Architecture
Fastly supports multiple domains within a single service or separate services. Each domain can have different VCL logic, caching rules, and backend configurations.
VCL Management for Multiple Domains
Service Structure
Each Fastly service can have:
- Multiple domains mapped to the service
- Domain-specific VCL logic using conditionals
- Shared VCL snippets for common logic
- Backend definitions for each origin server
- Version control for VCL configurations
Domain-Specific VCL Example
# vcl_recv - Route by domain
sub vcl_recv {
# Domain: www.prabasiva.com
if (req.http.host == "www.prabasiva.com") {
set req.backend = www_origin;
# Static assets - long cache
if (req.url ~ "^/static/|\.(?:css|js|jpg|png|svg|woff2)$") {
set req.http.X-TTL = "1 week";
}
# HTML pages - shorter cache
else {
set req.http.X-TTL = "5 minutes";
}
}
# Domain: api.prabasiva.com
else if (req.http.host == "api.prabasiva.com") {
set req.backend = api_origin;
# API endpoints - no cache for POST/PUT/DELETE
if (req.method != "GET" && req.method != "HEAD") {
return(pass);
}
# GET requests - short cache with stale-while-revalidate
set req.http.X-TTL = "30 seconds";
set req.http.X-Grace = "2 hours";
}
# Domain: blog.prabasiva.com
else if (req.http.host == "blog.prabasiva.com") {
set req.backend = blog_origin;
# Blog posts - long cache
set req.http.X-TTL = "1 hour";
}
return(hash);
}
# vcl_backend_response - Set TTL based on domain logic
sub vcl_backend_response {
# Apply TTL from vcl_recv
if (req.http.X-TTL) {
set beresp.ttl = std.duration(req.http.X-TTL, 60s);
}
# Apply grace period
if (req.http.X-Grace) {
set beresp.grace = std.duration(req.http.X-Grace, 1h);
}
# Enable stale-while-revalidate for API domain
if (req.http.host == "api.prabasiva.com") {
set beresp.stale_while_revalidate = 3600s;
}
return(deliver);
}
# vcl_deliver - Add custom headers per domain
sub vcl_deliver {
# Add cache status header
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
# Domain-specific headers
if (req.http.host == "www.prabasiva.com") {
set resp.http.X-Domain = "www";
} else if (req.http.host == "api.prabasiva.com") {
set resp.http.X-Domain = "api";
set resp.http.X-API-Version = "v1";
}
return(deliver);
}VCL Deployment Workflow
Deployment Steps
1. Local Development & Testing
# Install Varnish locally for testing
brew install varnish
# Test VCL syntax
varnishd -C -f your-config.vcl
# Run local Varnish instance
varnishd -a localhost:8080 -f your-config.vcl
# Test with curl
curl -H "Host: www.prabasiva.com" http://localhost:8080/2. Version Control
# VCL files in Git repository
git add vcl/www.prabasiva.com.vcl
git add vcl/api.prabasiva.com.vcl
git commit -m "Update cache TTL for API endpoints"
git push origin feature/update-api-cache3. Fastly API Deployment
# Using Fastly CLI
fastly service-version clone --version=latest
# Upload VCL snippet
fastly vcl snippet create \
--version=<VERSION> \
--name="www_domain_logic" \
--type=recv \
--content="$(cat vcl/www.prabasiva.com.vcl)"
# Validate the version
fastly service-version validate --version=<VERSION>
# Activate the version
fastly service-version activate --version=<VERSION>4. Using Fastly Web UI
- Navigate to your service in Fastly console
- Click "Edit configuration" to clone current version
- Go to "VCL snippets" or "Custom VCL"
- Upload or edit VCL code
- Click "Validate" to check syntax
- Click "Activate" to deploy
VCL Snippet Organization
Fastly allows organizing VCL into snippets for better maintainability:
Example Snippet Structure
# Snippet: www_domain_routing (Type: recv, Priority: 100)
if (req.http.host == "www.prabasiva.com") {
set req.backend = www_origin;
call www_caching_rules;
}
# Snippet: www_caching_rules (Type: recv, Priority: 101)
if (req.url ~ "^/static/") {
set req.http.X-Cache-TTL = "604800"; # 1 week
}
# Snippet: api_domain_routing (Type: recv, Priority: 100)
if (req.http.host == "api.prabasiva.com") {
set req.backend = api_origin;
call api_caching_rules;
}
# Snippet: api_caching_rules (Type: recv, Priority: 101)
if (req.method != "GET" && req.method != "HEAD") {
return(pass);
}
# Snippet: security_headers (Type: deliver, Priority: 100)
set resp.http.Strict-Transport-Security = "max-age=31536000";
set resp.http.X-Content-Type-Options = "nosniff";
set resp.http.X-Frame-Options = "DENY";Fastly Service Configuration
Backend Definitions
# Backend: www.prabasiva.com
backend www_origin {
.host = "www-origin.prabasiva.com";
.port = "443";
.ssl = true;
.ssl_sni_hostname = "www-origin.prabasiva.com";
.ssl_cert_hostname = "www-origin.prabasiva.com";
.ssl_check_cert = always;
.connect_timeout = 5s;
.first_byte_timeout = 30s;
.between_bytes_timeout = 10s;
.max_connections = 200;
# Health check
.probe = {
.request = "GET /health HTTP/1.1"
"Host: www-origin.prabasiva.com"
"Connection: close";
.interval = 30s;
.timeout = 5s;
.window = 5;
.threshold = 3;
}
}
# Backend: api.prabasiva.com
backend api_origin {
.host = "api-origin.prabasiva.com";
.port = "443";
.ssl = true;
.ssl_sni_hostname = "api-origin.prabasiva.com";
.ssl_cert_hostname = "api-origin.prabasiva.com";
.ssl_check_cert = always;
.connect_timeout = 3s;
.first_byte_timeout = 15s;
.between_bytes_timeout = 10s;
.max_connections = 500;
# Healthcheck for API
.probe = {
.request = "GET /api/health HTTP/1.1"
"Host: api-origin.prabasiva.com"
"Connection: close";
.interval = 10s;
.timeout = 3s;
.window = 5;
.threshold = 3;
}
}Shield Configuration
Shield is Fastly's origin protection feature that adds an intermediate cache layer.
Benefits of Shield
- Reduced Origin Load: Only shield fetches from origin
- Better Cache Hit Ratio: Consolidates cache across all POPs
- Origin Protection: Single point of contact with origin
- Cost Optimization: Fewer origin requests = lower bandwidth costs
Enabling Shield
sub vcl_recv {
# Enable shield for all requests
set req.backend = F_Shield_Ashburn_VA_US;
# Or conditionally by domain
if (req.http.host == "www.prabasiva.com") {
set req.backend = F_Shield_Ashburn_VA_US;
}
}Real-Time Cache Purging
One of Fastly's key features is instant cache purging across all POPs.
Purge Methods
1. URL Purge
# Purge specific URL
curl -X PURGE \
-H "Fastly-Key: YOUR_API_KEY" \
https://www.prabasiva.com/blog/post-1
# Using Fastly API
curl -X POST \
-H "Fastly-Key: YOUR_API_KEY" \
https://api.fastly.com/purge/www.prabasiva.com/blog/post-12. Surrogate Key Purge
# Purge by surrogate key (soft purge)
curl -X POST \
-H "Fastly-Key: YOUR_API_KEY" \
https://api.fastly.com/service/SERVICE_ID/purge/blog-posts3. Purge All
# Purge entire service (use with caution!)
curl -X POST \
-H "Fastly-Key: YOUR_API_KEY" \
https://api.fastly.com/service/SERVICE_ID/purge_allSetting Surrogate Keys in VCL
sub vcl_backend_response {
# Add surrogate keys for purging
if (bereq.url ~ "^/blog/") {
set beresp.http.Surrogate-Key = "blog-posts blog-" + bereq.url;
}
if (bereq.url ~ "^/api/") {
set beresp.http.Surrogate-Key = "api-responses";
}
}Monitoring and Observability
Key Metrics to Monitor
- Cache Hit Ratio: Should be > 80% for static content
- Response Time: P95 should be < 100ms for cached content
- Error Rate: 5xx errors should be < 0.1%
- Origin Load: Should remain low with good cache hit ratio
Best Practices
1. VCL Organization
- Separate snippets by domain for clarity
- Use descriptive names for snippets and backends
- Version control all VCL code in Git
- Test locally with Varnish before deploying
2. Caching Strategy
- Static assets: Cache for weeks/months
- API responses: Short TTL with stale-while-revalidate
- HTML pages: Medium TTL (5-15 minutes)
- Personalized content: Use vary headers or don't cache
3. Security
- Always use HTTPS for origin connections
- Validate SSL certificates (.ssl_check_cert = always)
- Implement rate limiting for API domains
- Add security headers in vcl_deliver
- Use ACLs for IP-based restrictions
4. Performance
- Enable Shield to reduce origin load
- Use surrogate keys for efficient purging
- Set appropriate TTLs per content type
- Implement stale-while-revalidate for better UX
5. Deployment
- Always validate VCL before activating
- Test on staging service first
- Use versioning for easy rollback
- Monitor after deployment for errors
Troubleshooting
Common Issues
1. Low Cache Hit Ratio
# Debug: Log cache status
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache-Hits = obj.hits;
}
set resp.http.X-Cache-TTL = obj.ttl;
}Solutions:
- Check if requests have varying query parameters
- Ensure proper cache key normalization
- Verify TTL is set correctly
2. Origin Connection Errors
sub vcl_backend_error {
# Log backend errors
set beresp.http.X-Backend-Error = beresp.status;
# Return cached stale content if available
if (stale.exists) {
return(deliver_stale);
}
}Solutions:
- Verify backend health checks
- Check origin server connectivity
- Increase timeout values if needed
3. VCL Syntax Errors
# Validate VCL before deployment
fastly service-version validate --version=<VERSION>Solutions:
- Test locally with Varnish first
- Use VCL linter
- Check Fastly VCL documentation for supported features
Summary
Fastly CDN provides:
- Global edge network with 80+ POPs for low latency
- VCL customization for domain-specific caching logic
- Real-time purging for instant cache updates
- Shield layer for origin protection
- Instant deployment with version control
- Comprehensive monitoring and observability
Domain Management Strategy
- www.prabasiva.com (opens in a new tab): Long cache for static assets, short for HTML
- api.prabasiva.com: Short TTL with stale-while-revalidate
- blog.prabasiva.com: Medium TTL with surrogate key purging
Key Takeaways
- Each domain can have custom VCL logic within the same service
- VCL snippets provide modular configuration
- Shield reduces origin load and improves cache efficiency
- Real-time purging enables instant content updates
- Comprehensive monitoring ensures optimal performance
Additional Resources
- Fastly Documentation (opens in a new tab)
- Fastly VCL Reference (opens in a new tab)
- Fastly API Documentation (opens in a new tab)
- VCL Basics
Last Updated: 2025