s3-pricing
A high-performance Rust library for fetching and caching AWS S3 pricing information dynamically using the AWS Pricing API.
🚀 Features
- Real-time Pricing: Fetch up-to-date S3 pricing directly from AWS Pricing API
- Intelligent Caching: Automatic caching with negative result caching to minimize API calls
- Comprehensive Coverage: Support for all S3 storage classes and AWS regions (global and China)
- Multiple Price Types:
- Storage costs (per GB-month)
- API request costs (Class A: PUT/COPY/POST/LIST, Class B: GET/SELECT)
- Data transfer costs (to internet and cross-region)
- High Performance: Optimized with static filter caching and early-return algorithms
- Error Handling: Type-safe region validation and descriptive error messages
- Async/Await: Built on tokio for non-blocking operations
- China Regions: Full support for AWS China regions (cn-north-1, cn-northwest-1) with CNY pricing
📦 Installation
Add this to your Cargo.toml:
[]
= "0.1.0"
= { = "1.50", = ["full"] }
= "1.0"
🚀 Quick Start
use S3PricingClient;
use Result;
async
📚 Usage
AWS Credentials
The library automatically resolves AWS credentials using the standard AWS SDK credential chain:
- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY) - Shared credentials file (
~/.aws/credentials) - AWS SSO profiles
- IAM roles for EC2 instances
- IAM roles for ECS tasks
You can optionally specify a named profile:
let client = new.await?;
Supported S3 Storage Classes
STANDARD- Standard S3 storageSTANDARD_IA- Standard Infrequent AccessONEZONE_IA- One Zone Infrequent AccessINTELLIGENT_TIERING- Intelligent-TieringGLACIER/GLACIER_FLEXIBLE_RETRIEVAL- Glacier Flexible RetrievalDEEP_ARCHIVE- Glacier Deep ArchiveGLACIER_IR/GLACIER_INSTANT_RETRIEVAL- Glacier Instant RetrievalEXPRESS_ONEZONE- S3 Express One ZoneREDUCED_REDUNDANCY- Reduced Redundancy (legacy)
Supported AWS Regions
All AWS regions are supported, including:
- Global Regions: US, Europe, Asia Pacific, Middle East, Africa, South America, Canada
- Pricing in USD
- Endpoint:
api.pricing.us-east-1.amazonaws.com
- China Regions: cn-north-1 (Beijing), cn-northwest-1 (Ningxia)
- Pricing in CNY
- Endpoint:
api.pricing.cn-northwest-1.amazonaws.com.cn
Pricing Methods
Storage Pricing
let price = client.get_storage_price.await?;
// Returns price per GB-month in USD
Request Pricing
// Class A: PUT, COPY, POST, LIST
let put_price = client.get_class_a_request_price.await?;
// Class B: GET, SELECT, and all other operations
let get_price = client.get_class_b_request_price.await?;
Data Transfer Pricing
// Transfer to internet
let internet_price = client.get_data_transfer_price.await?;
// Cross-region transfer
let cross_region = client.get_cross_region_transfer_price.await?;
Display Formatted Pricing
// Display with internet transfer pricing
client.display_pricing.await?;
// Display with cross-region transfer pricing
let dest = "eu-west-1".to_string;
client.display_pricing.await?;
AWS China Regions
AWS China regions require a separate client instance using new_china():
use S3PricingClient;
// For global AWS regions (USD pricing)
let client = new.await?;
let price_usd = client.get_storage_price.await?;
println!;
// For AWS China regions (CNY pricing)
let china_client = new_china.await?;
let price_cny = china_client.get_storage_price.await?;
println!;
// Display formatted pricing for China regions
china_client.display_pricing.await?;
Check if a Region is a China Region
use S3PricingClient;
if is_china_region
if is_china_region
Note: AWS China regions require AWS credentials configured for the China partition. The pricing API endpoint is api.pricing.cn-northwest-1.amazonaws.com.cn.
⚙️ Configuration
Cache Behavior
The library uses a two-tier caching strategy:
- Positive Cache: Successful price lookups cached with 1-hour TTL
- Negative Cache: Failed lookups cached with 5-minute TTL to prevent repeated API calls
Cache capacity:
- Positive cache: 1000 entries
- Negative cache: 500 entries
Performance Optimizations
- Static Filter Caching: Commonly used filters are cached using
OnceLock - Early Return: Price extraction returns immediately when first-tier price is found
- Efficient JSON Parsing: Uses
serde_json::Valuefor filtering instead of string matching - Region Validation: Type-safe region validation catches errors early
🔍 Examples
Compare Pricing Across Regions
use S3PricingClient;
use Result;
async
Multi-Storage Class Comparison
async
🛠️ Development
Prerequisites
- Rust 1.93.0 or later
- AWS credentials configured
Building from Source
Running Tests
Code Quality
# Run clippy for linting
# Format code
📊 Performance Benchmarks
| Optimization | Improvement |
|---|---|
| Negative caching | ~30-50% fewer API calls |
| Static filter caching | ~10-15% fewer allocations |
| Early return extraction | ~50% faster price extraction |
| Efficient JSON filtering | ~20-30% faster lookups |
⚠️ Important Notes
- Pricing API Endpoints:
- Global regions:
api.pricing.us-east-1.amazonaws.com - China regions:
api.pricing.cn-northwest-1.amazonaws.com.cn
- Global regions:
- Currency: Prices are returned in USD for global regions, CNY for China regions.
- Pricing Tiers: The library returns first-tier (base) pricing where available.
- Cache TTL: Prices are cached for 1 hour. Restart the application to fetch fresh data.
- China Regions: Requires AWS credentials configured for the China partition.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📞 Support
- Documentation: docs.rs/s3-pricing
- Issues: GitHub Issues
- Repository: github.com/bartleboeuf/s3-pricing
🙏 Acknowledgments
- Built on the AWS SDK for Rust
- Caching powered by quick-cache
- Error handling with anyhow
📦 Dependencies
aws-sdk-pricing- AWS Pricing API clientaws-config- AWS configuration and credentialstokio- Async runtimeserde_json- JSON parsinganyhow- Error handlingquick_cache- Fast in-memory caching
Last updated: March 14, 2026