Introduction: What is BunnyCDN and Why Use It?
BunnyCDN is a globally distributed content delivery network (CDN) designed to speed up website loading times by serving content from servers geographically closer to users. Founded in 2014, BunnyCDN has built a reputation for offering high-performance CDN services at more affordable prices than many competitors, with a focus on simplicity and developer-friendly features.
Key advantages:
- Global network with 110+ POPs (Points of Presence) across 6 continents
- Up to 10x faster website loading with edge caching and optimization
- Pay-as-you-go pricing model with no hidden fees
- Built-in security features including DDoS protection
- Edge storage solutions with automatic replication
- User-friendly control panel and robust API
- Advanced performance optimization features
- Significantly lower costs compared to premium CDN providers
Core Services & Features
BunnyCDN Service Overview
Service | Description | Use Case |
---|---|---|
Pull Zone | Traditional CDN for caching website assets | Static content, images, CSS/JS files |
Storage Zone | Distributed object storage | File hosting, backups, media libraries |
Edge Script | Serverless JavaScript at the edge | Custom routing, authentication, optimization |
Stream | Video streaming platform | Video-on-demand, live streaming |
Perma-Cache | Long-term persistent caching | Rarely changing assets, software downloads |
Bunny Optimizer | Image and code optimization | Automatic image optimization, code minification |
Account Setup & Management
API Authentication
# Basic API request format with API key
curl -H "AccessKey: YOUR_API_KEY" \
https://api.bunny.net/endpoint
API Key Management
Action | Description |
---|---|
Generate API Key | Control Panel → Account → API → Generate New API Key |
Scope API Keys | Create keys with limited permissions for specific services |
Key Rotation | Regularly rotate API keys for enhanced security |
Account Limits
Feature | Standard Plan | Business Plan | Enterprise Plan |
---|---|---|---|
Storage | Pay as you go | Pay as you go | Custom |
Bandwidth | Pay as you go | Pay as you go | Custom |
Purge API Rate | 10,000/day | 100,000/day | Custom |
Monthly Fee | $0 | $100 | Custom |
Pull Zones
Pull Zone Setup
# Create a Pull Zone via API
curl -X POST \
-H "Content-Type: application/json" \
-H "AccessKey: YOUR_API_KEY" \
-d '{
"Name": "my-website-cdn",
"OriginUrl": "https://origin.example.com",
"Type": 0,
"EnableGeoZoneUS": true,
"EnableGeoZoneEU": true,
"EnableGeoZoneASIA": true,
"EnableGeoZoneSA": true,
"EnableGeoZoneAF": true
}' \
https://api.bunny.net/pullzone
Pull Zone Configuration
Setting | Description | Recommendation |
---|---|---|
Origin URL | The source of your content | Use HTTPS, dedicated origin server |
Hostname | CDN URL (e.g., cdn.example.com) | Custom domain with SSL certificate |
Edge Rules | Custom routing and request handling | Use for complex routing requirements |
Cache Settings | Control how content is cached | Enable browser cache, set reasonable TTLs |
Optimizer | Image and code optimization | Enable for automatic optimization |
Cache Control
Header | Example | Description |
---|---|---|
Cache-Control | max-age=3600 | Browser cache lifetime in seconds |
s-maxage | s-maxage=86400 | CDN-specific cache lifetime |
Surrogate-Control | max-age=86400 | Alternative CDN cache control |
Cache-Tag | Cache-Tag: product-123 | Tag content for selective purging |
Cache Purging
# Purge individual URL
curl -X POST \
-H "AccessKey: YOUR_API_KEY" \
https://api.bunny.net/purge?url=https://cdn.example.com/image.jpg
# Purge by cache tag
curl -X POST \
-H "Content-Type: application/json" \
-H "AccessKey: YOUR_API_KEY" \
-d '{
"TagName": "product-123"
}' \
https://api.bunny.net/pullzone/123/purgeCacheTag
Storage Zones
Storage Zone Setup
# Create a Storage Zone via API
curl -X POST \
-H "Content-Type: application/json" \
-H "AccessKey: YOUR_API_KEY" \
-d '{
"Name": "my-files",
"Region": "DE",
"ReplicationRegions": ["NY", "SG"]
}' \
https://api.bunny.net/storagezone
Storage Regions
Code | Location |
---|---|
DE | Frankfurt, Germany |
UK | London, UK |
SE | Stockholm, Sweden |
NY | New York, USA |
LA | Los Angeles, USA |
SG | Singapore |
SYD | Sydney, Australia |
BR | São Paulo, Brazil |
JH | Johannesburg, South Africa |
File Operations with Storage API
Operation | Method | Endpoint |
---|---|---|
Upload File | PUT | https://storage.bunnycdn.com/{storage-zone}/{path} |
Download File | GET | https://storage.bunnycdn.com/{storage-zone}/{path} |
List Files | GET | https://storage.bunnycdn.com/{storage-zone}/{path}/ |
Delete File | DELETE | https://storage.bunnycdn.com/{storage-zone}/{path} |
Create Directory | PUT | https://storage.bunnycdn.com/{storage-zone}/{path}/ |
Upload File Example
# Upload a file to storage zone
curl -X PUT \
-H "AccessKey: YOUR_API_KEY" \
-H "Content-Type: application/octet-stream" \
--data-binary @"local-file.jpg" \
https://storage.bunnycdn.com/my-files/images/file.jpg
Download File Example
# Download a file from storage zone
curl -H "AccessKey: YOUR_API_KEY" \
https://storage.bunnycdn.com/my-files/images/file.jpg > downloaded-file.jpg
List Files Example
# List files in a directory
curl -H "AccessKey: YOUR_API_KEY" \
https://storage.bunnycdn.com/my-files/images/
Edge Script
Sample Edge Script
// Redirect non-www to www
if (bunny.request.host === "example.com") {
bunny.response.status = 301;
bunny.response.headers.set("Location", "https://www.example.com" + bunny.request.uri);
bunny.response.end();
}
// A/B testing
if (Math.random() < 0.5) {
bunny.request.path = "/variant-a" + bunny.request.path;
} else {
bunny.request.path = "/variant-b" + bunny.request.path;
}
// Basic authentication
const authHeader = bunny.request.headers.get("Authorization");
if (!authHeader || authHeader !== "Basic dXNlcjpwYXNz") {
bunny.response.status = 401;
bunny.response.headers.set("WWW-Authenticate", "Basic");
bunny.response.end("Authentication required");
}
Edge Script Functions
Object | Example | Description |
---|---|---|
bunny.request | bunny.request.path | Access request information |
bunny.response | bunny.response.status = 302 | Modify response |
bunny.cache | bunny.cache.set("key", "value") | Edge caching operations |
bunny.log | bunny.log("Debug message") | Log messages (visible in logs) |
bunny.fetch | await bunny.fetch("https://api.example.com") | Make HTTP requests from edge |
Bunny Optimizer
Image Optimization Parameters
Parameter | Values | Description |
---|---|---|
width | Numeric | Resize image width in pixels |
height | Numeric | Resize image height in pixels |
quality | 1-100 | JPEG/WebP compression quality |
format | webp, jpeg, png, etc. | Force specific image format |
sharpen | 0-100 | Apply sharpening to image |
blur | 0-100 | Apply blur to image |
crop | smart, true, false | Enable automatic smart cropping |
Example Optimized URLs
# Basic resizing
https://cdn.example.com/image.jpg?width=600
# WebP with quality setting
https://cdn.example.com/image.jpg?format=webp&quality=80
# Smart cropping for thumbnails
https://cdn.example.com/image.jpg?width=300&height=300&crop=smart
Bunny Stream
Stream Service Setup
# Create a new video library
curl -X POST \
-H "Content-Type: application/json" \
-H "AccessKey: YOUR_API_KEY" \
-d '{
"Name": "my-videos",
"ReplicationRegions": ["DE", "NY", "SG"]
}' \
https://api.bunny.net/videolibrary
Video Management API
Operation | Method | Endpoint |
---|---|---|
List Videos | GET | /library/{libraryId}/videos |
Get Video | GET | /library/{libraryId}/videos/{videoId} |
Upload Video | POST | /library/{libraryId}/videos |
Delete Video | DELETE | /library/{libraryId}/videos/{videoId} |
Create Collection | POST | /library/{libraryId}/collections |
Add Video to Collection | PUT | /library/{libraryId}/collections/{collectionId}/videos/{videoId} |
Video Embed Codes
<!-- Standard iframe embed -->
<iframe
src="https://iframe.mediadelivery.net/embed/12345/my-video-id?autoplay=false"
loading="lazy"
style="border: none; position: absolute; top: 0; height: 100%; width: 100%;"
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
allowfullscreen="true">
</iframe>
<!-- Video.js embed -->
<video id="player" class="video-js" controls preload="auto">
<source src="https://video.bunnycdn.com/play/12345/my-video-id" type="application/x-mpegURL">
</video>
Performance Optimization
Performance Tips
Enable Browser Caching:
Cache-Control: public, max-age=31536000 s-maxage: 31536000
Smart Image Optimization:
<!-- Use srcset for responsive images --> <img srcset=" https://cdn.example.com/image.jpg?width=320 320w, https://cdn.example.com/image.jpg?width=480 480w, https://cdn.example.com/image.jpg?width=800 800w" sizes="(max-width: 600px) 320px, (max-width: 1200px) 480px, 800px" src="https://cdn.example.com/image.jpg?width=800">
Implement HTTP/2 or HTTP/3:
- Enable HTTP/2 in Pull Zone settings
- Enable HTTP/3 for faster connections with less latency
Use Cache Tags:
Cache-Tag: product-123, category-456
Enable Gzip/Brotli Compression:
- Enable in Pull Zone settings
- Verify with
curl -I --compressed https://cdn.example.com/file.js
Security Features
Secure Token Authentication
// PHP example of generating a secure token
$securityKey = "your-security-key";
$expiration = time() + 3600; // 1 hour from now
$pathToProtect = "/path/to/file.mp4";
$ipAddress = "*"; // any IP, or specific IP
$countries = "*"; // any country, or specific countries
$referrers = "*"; // any referrer, or specific referrers
$token = hash('sha256', $securityKey . $pathToProtect . $expiration . $ipAddress . $countries . $referrers);
$tokenizedUrl = "https://cdn.example.com" . $pathToProtect . "?token=" . $token . "&expires=" . $expiration;
GeoLocation Restriction
# Set country blocking via API
curl -X POST \
-H "Content-Type: application/json" \
-H "AccessKey: YOUR_API_KEY" \
-d '{
"BlockedCountries": ["RU", "CN", "IR"]
}' \
https://api.bunny.net/pullzone/123
IP Blocking
# Block specific IP addresses
curl -X POST \
-H "Content-Type: application/json" \
-H "AccessKey: YOUR_API_KEY" \
-d '{
"BlockedIPs": ["192.168.1.1", "10.0.0.1"]
}' \
https://api.bunny.net/pullzone/123
Common Challenges & Solutions
Challenge 1: Origin Connectivity Issues
Problem: CDN cannot connect to origin server.
Solution:
- Verify origin server is accessible from the internet
- Check firewall settings to allow BunnyCDN IP ranges
- Verify SSL certificates are valid and not self-signed
- Increase origin connection timeout settings
- Set up a backup origin server
Challenge 2: Cache Control Conflicts
Problem: Unexpected caching behavior.
Solution:
- Check for conflicting cache headers (
Cache-Control
,Expires
, etc.) - Use
s-maxage
directive specifically for CDN - Override origin cache headers in Pull Zone settings
- Use cache-debug header to troubleshoot:
curl -I -H "Cache-Debug: true" https://cdn.example.com/asset.jpg
Challenge 3: Large File Uploads to Storage
Problem: Large file uploads failing.
Solution:
- Use chunked uploading for files > 200MB
- Implement resumable upload logic
- Use S3-compatible clients with multipart upload support
- Verify network stability during uploads
- Use FTP for very large files (with FTP bridge)
Best Practices & Tips
1. Optimize Origin Delivery
- Keep origin server close to a BunnyCDN POP
- Compress content at origin
- Use Keep-Alive connections
- Pre-compress static assets (gzip, brotli)
- Enable HTTP/2 on origin server
2. Effective Cache Strategy
- Set appropriate TTLs based on content type:
- Static assets (JS, CSS): 1 year (31536000s)
- Images, videos: 1 month+ (2592000s)
- API responses: Varies by data volatility
- HTML pages: Short TTL or no-cache if personalized
- Use cache tags for content grouping
- Implement cache versioning with query parameters
3. Cost Optimization
- Use Perma-Cache for rarely changed assets
- Enable optimization features to reduce bandwidth
- Set up proper cache TTLs to reduce origin requests
- Use lowest-cost storage regions for non-latency-sensitive content
- Monitor and analyze traffic patterns regularly
- Use tiered cache approach for highly accessed content
4. Security Hardening
- Implement Secure Token Authentication for sensitive content
- Use HTTPS everywhere (origin and CDN)
- Set up appropriate CORS headers
- Enable hotlink protection for valuable assets
- Implement proper HTTP security headers
- Regularly rotate API keys and access credentials
5. Performance Monitoring
- Use RUM (Real User Monitoring) to track actual user experience
- Monitor cache hit rates and optimize for higher rates
- Use the BunnyCDN logging for troubleshooting
- Set up alerts for unusual traffic patterns
- Regularly test from different global locations
Resources for Further Learning
Official Documentation
Code Libraries & SDKs
Community Resources
Tutorials & Guides
- BunnyCDN with WordPress
- Setting up BunnyCDN with Laravel
- Video Streaming Implementation Guide
- Image Optimization Best Practices
This cheatsheet covers the essentials of BunnyCDN. For more detailed information and examples, refer to the official documentation at docs.bunny.net.