Find EC2 instance types, compare spot prices, check quotas.
All discovery commands require AWS credentials (configured via aws configure, environment variables, or IAM role). Only truffle app list and truffle version work without credentials.
macOS / Linux (Homebrew)
brew install spore-host/tap/truffleWindows (Scoop)
scoop bucket add spore-host https://github.com/spore-host/scoop-bucket
scoop install truffleDebian / Ubuntu
curl -LO https://github.com/spore-host/truffle/releases/latest/download/truffle_linux_amd64.deb
sudo dpkg -i truffle_linux_amd64.debRHEL / Fedora
sudo rpm -i https://github.com/spore-host/truffle/releases/latest/download/truffle_linux_amd64.rpmDirect download — pre-built binaries for Linux, macOS, and Windows (amd64/arm64) on the releases page.
Build from source
git clone https://github.com/spore-host/truffle
cd truffle && make build && sudo make install# Find instance types by pattern (glob or regex; configured region by default)
truffle find "m7i*" # glob: all m7i sizes
truffle find "c[6-8]i.large" # regex: c6i/c7i/c8i large
truffle find g5.2xlarge g5.4xlarge # compare named types side by side
# Compare spot prices (every enabled region by default: the point is the cheapest one)
truffle spot m7i.large --regions us-east-1
truffle spot "c6a*" --sort-by-price --lookback-hours 24
truffle spot "c7a.*" --sort-by-price --limit 10 # first 10 rows; keeps the table border, unlike | head
# Find by natural language (searches your configured region by default —
# AWS_REGION / AWS_DEFAULT_REGION / profile region; all regions if none is set)
truffle find "h100 8 gpus efa"
truffle find "amd turin 32 cores 64gb" --exact
truffle find "A100-80GB" # GPU memory in a card name counts: 80 GB A100s only
truffle find "gpu 24gb" # each GPU ≥24 GB/GiB as sold; "64gb ram" means host memory (GiB)
truffle find graviton --regions us-east-1,us-west-2
truffle find graviton --all-regions # every enabled region (slower)
# Check EC2 quotas
truffle quotas --regions us-east-1 --family P
truffle quotas --regions us-east-1 -o json
# Check SageMaker quotas
truffle quotas --service sagemaker --family g5 --regions us-west-2
# Discover SageMaker ml.* instance types (specs, pricing, managed-spot eligibility)
truffle find "ml.g5.*" --service sagemaker --regions us-east-1
truffle find "ml.g5.*" --service sagemaker --show-quota --regions us-east-1
# Find available capacity reservations
truffle capacity --gpu-only
# Output formats (all commands)
truffle find "m7i*" -o json
truffle find "intel 8 vcpu" -o csv| Command | Description |
|---|---|
find <query> |
Natural language (amd turin 32 cores 64gb), glob (m7i*), or regex (c[6-8]i.large) search; --service sagemaker for ml.* types |
spot <pattern> |
Spot pricing with savings vs on-demand |
search <pattern> |
Deprecated: use find, which detects patterns itself |
az <pattern> |
AZ-first availability view |
available <type> |
Can you actually get it? Spot score, AZ footprint, quota headroom, capacity blocks |
capacity |
On-demand capacity reservations (ODCRs) |
capacity-blocks |
Discover purchasable EC2 Capacity Block for ML offerings |
list |
List instance families or sizes |
quotas |
EC2 and SageMaker service quotas |
app list |
Browse application catalog (no credentials needed) |
version |
Show version, build info, and project URL |
Every multi-region command takes --regions (pick regions) and --all-regions
(every enabled region); giving both is an error. With neither, the default
depends on what the command is for:
| Command | Default scope | Why |
|---|---|---|
find (and the deprecated search) |
your configured region (spore config, AWS_REGION / AWS_DEFAULT_REGION, profile region); all enabled regions if none is set |
describing instance types; most people launch in one region |
spot |
all enabled regions | finding the cheapest region/AZ |
az |
all enabled regions (or the regions of --az zones) |
comparing AZ coverage across regions |
capacity |
all enabled regions | your reservations can be in any region |
capacity-blocks |
all enabled regions | offerings vary by region |
quotas, available |
your configured region (same lookup as find); us-east-1 if none is set |
quota headroom and obtainability are per-region answers; not multi-region by default, use --regions (available checks one region) |
list |
your configured region (same lookup as find); us-east-1 if none is set |
one region per run (the first --regions entry); some instance types are region-limited |
| Flag | Description |
|---|---|
-o, --output |
Output format: table, json, yaml, csv |
-r, --regions |
Filter by regions (comma-separated); see Region scope |
--no-emoji |
Disable emoji in output |
--no-color |
Disable colorized output |
--lang |
Language: en, es, fr, de, ja, pt |
import "github.com/spore-host/truffle/pkg/aws"
client, _ := aws.NewClient(ctx)
results, _ := client.SearchInstanceTypes(ctx, regions, matcher, opts)
// On-demand rate for one type (live AWS Price List, cached)
rate, _ := client.HourlyRate(ctx, "c6i.4xlarge", "us-east-1", "on-demand")
// Same, plus where the rate came from. If the Price List API is unreachable,
// truffle falls back to a built-in table and reports PriceSourceStatic — check
// this before gating spending on the number. An unpriceable type is an error,
// never a guess.
rate, source, err := client.OnDemandPriceWithSource(ctx, "c6i.4xlarge", "us-east-1")
// Same, with the full origin: for a static rate, why the live Price List was
// not used and when the table was collected. Show a price with its origin —
// a static price must say it is static, why, and when.
rate, origin, err := client.OnDemandPriceWithOrigin(ctx, "c6i.4xlarge", "us-east-1")
fmt.Println(aws.DescribeOnDemandPrice(rate, origin))
// $0.6800/hr on-demand (static, collected 2026-10-07: live AWS Price List unavailable: ...)
// Spot prices with on-demand comparison populated
prices, _ := client.GetSpotPricing(ctx, results, aws.SpotOptions{ShowSavings: true})The aws.Finder interface allows downstream projects to mock truffle's discovery layer:
import (
"github.com/spore-host/truffle/pkg/aws"
"github.com/spore-host/truffle/pkg/aws/awsmock"
)
mock := awsmock.New(
awsmock.WithRegions([]string{"us-east-1"}),
awsmock.WithInstances([]aws.InstanceTypeResult{
{InstanceType: "m7i.large", Region: "us-east-1", VCPUs: 2, MemoryMiB: 8192},
}),
awsmock.WithOnDemandPrices(map[string]float64{"m7i.large/us-east-1": 0.1008}),
)
// Use mock anywhere an aws.Finder is accepted.Use the spore-host SDK
(pip install spore-host) for Python access — spore.truffle.find(...) wraps
truffle's discovery via the hosted REST API.
(An earlier native-CGO binding experiment was never completed; its design notes
live in docs/design/native-cgo-binding/ —
not an installable package. See truffle#76.)
Full reference at spore.host/docs.
- SageMaker (
ml.*) instance discovery —--service sagemaker, pricing, managed-spot eligibility, quotas.
Apache 2.0 — Copyright 2025-2026 Scott Friedman.
