A high-performance Rust library for fetching and caching AWS S3 pricing information dynamically using the AWS Pricing API.
- 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
Add this to your Cargo.toml:
[dependencies]
s3-pricing = "0.1.0"
tokio = { version = "1.50", features = ["full"] }
anyhow = "1.0"use s3_pricing::S3PricingClient;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Create a new pricing client (uses default AWS credentials)
let client = S3PricingClient::new(None).await?;
// Get storage price for STANDARD class in us-east-1
let price = client.get_storage_price("us-east-1", "STANDARD").await?;
println!("S3 STANDARD storage: ${:.4} per GB-month", price);
// Get Class A request price (PUT, COPY, POST, LIST)
let put_price = client.get_class_a_request_price("us-east-1", "STANDARD").await?;
println!("PUT requests: ${:.10} per request (${:.4} per 1,000)", put_price, put_price * 1000.0);
// Get Class B request price (GET, SELECT)
let get_price = client.get_class_b_request_price("us-east-1", "STANDARD").await?;
println!("GET requests: ${:.10} per request (${:.4} per 10,000)", get_price, get_price * 10000.0);
// Get data transfer to internet price
let transfer_price = client.get_data_transfer_price("us-east-1").await?;
println!("Data transfer to internet: ${:.4} per GB", transfer_price);
// Get cross-region transfer price
let cross_region_price = client.get_cross_region_transfer_price("us-east-1", "eu-west-1").await?;
println!("Transfer us-east-1 → eu-west-1: ${:.4} per GB", cross_region_price);
// Display formatted pricing information
client.display_pricing("us-east-1", "STANDARD", None).await?;
client.display_pricing("eu-west-1", "GLACIER", Some(&"us-east-1".to_string())).await?;
Ok(())
}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 = S3PricingClient::new(Some("my-profile")).await?;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)
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
let price = client.get_storage_price("us-east-1", "STANDARD_IA").await?;
// Returns price per GB-month in USD// Class A: PUT, COPY, POST, LIST
let put_price = client.get_class_a_request_price("us-east-1", "STANDARD").await?;
// Class B: GET, SELECT, and all other operations
let get_price = client.get_class_b_request_price("us-east-1", "STANDARD").await?;// Transfer to internet
let internet_price = client.get_data_transfer_price("us-east-1").await?;
// Cross-region transfer
let cross_region = client.get_cross_region_transfer_price("us-east-1", "eu-west-1").await?;// Display with internet transfer pricing
client.display_pricing("us-east-1", "STANDARD", None).await?;
// Display with cross-region transfer pricing
let dest = "eu-west-1".to_string();
client.display_pricing("us-east-1", "STANDARD", Some(&dest)).await?;AWS China regions require a separate client instance using new_china():
use s3_pricing::S3PricingClient;
// For global AWS regions (USD pricing)
let client = S3PricingClient::new(None).await?;
let price_usd = client.get_storage_price("us-east-1", "STANDARD").await?;
println!("US East: ${:.4} per GB-month", price_usd);
// For AWS China regions (CNY pricing)
let china_client = S3PricingClient::new_china(None).await?;
let price_cny = china_client.get_storage_price("cn-north-1", "STANDARD").await?;
println!("China (Beijing): ¥{:.4} per GB-month", price_cny);
// Display formatted pricing for China regions
china_client.display_pricing("cn-north-1", "STANDARD", None).await?;use s3_pricing::S3PricingClient;
if S3PricingClient::is_china_region("cn-north-1") {
// Use new_china() for CNY pricing
}
if S3PricingClient::is_china_region("us-east-1") {
// false - use new() for USD pricing
}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.
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
- 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
use s3_pricing::S3PricingClient;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
let client = S3PricingClient::new(None).await?;
let regions = ["us-east-1", "eu-west-1", "ap-northeast-1"];
for region in ®ions {
let price = client.get_storage_price(region, "STANDARD").await?;
println!("{}: ${:.4} per GB-month", region, price);
}
Ok(())
}#[tokio::main]
async fn main() -> Result<()> {
let client = S3PricingClient::new(None).await?;
let storage_classes = ["STANDARD", "STANDARD_IA", "GLACIER"];
for class in &storage_classes {
client.display_pricing("us-east-1", class, None).await?;
}
Ok(())
}- Rust 1.93.0 or later
- AWS credentials configured
git clone https://github.com/bartleboeuf/s3-pricing.git
cd s3-pricing
cargo buildcargo test# Run clippy for linting
cargo clippy -- -D warnings
# Format code
cargo fmt| 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 |
- 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.
This project is licensed under the MIT License - see the LICENSE file for details.
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
- Documentation: docs.rs/s3-pricing
- Issues: GitHub Issues
- Repository: github.com/bartleboeuf/s3-pricing
- Built on the AWS SDK for Rust
- Caching powered by quick-cache
- Error handling with anyhow
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