Skip to content
spore-hostPublic

About

Find EC2 instance types, compare spot prices, check quotas

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

truffle — find the right EC2 instance, price, and capacity

truffle

CI codecov Go Reference License: Apache 2.0 DOI

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.

Installation

macOS / Linux (Homebrew)

brew install spore-host/tap/truffle

Windows (Scoop)

scoop bucket add spore-host https://github.com/spore-host/scoop-bucket
scoop install truffle

Debian / Ubuntu

curl -LO https://github.com/spore-host/truffle/releases/latest/download/truffle_linux_amd64.deb
sudo dpkg -i truffle_linux_amd64.deb

RHEL / Fedora

sudo rpm -i https://github.com/spore-host/truffle/releases/latest/download/truffle_linux_amd64.rpm

Direct 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

Quick Start

# 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

Commands

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

Region scope

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

Global Flags

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

Go Library

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})

Testing with awsmock

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.

Python

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.)

Documentation

Full reference at spore.host/docs.

License

Apache 2.0 — Copyright 2025-2026 Scott Friedman.

About

Find EC2 instance types, compare spot prices, check quotas

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages