Skip to main content

TAG — Tigris Acceleration Gateway

TAG is a high-performance S3-compatible caching proxy for Tigris object storage. You deploy it between your application and Tigris, and it transparently caches objects on local NVMe storage — giving you sub-millisecond read latency without sacrificing S3 API compatibility.

Training InstanceTraining CodeS3 APIAcceleration Gatewaycache hitLocal NVMe Cachecache missfill cacheTigris ObjectStorageEpoch 1 fetches from Tigris · Epoch 2+ reads from local NVMe at disk speed

You don't need to change any application code. Just point your S3 client at TAG instead of Tigris and your reads are automatically accelerated.

Why TAG

Object storage is durable and scalable, but every read crosses the network. If you're serving ML models, running real-time analytics, or pushing data through high-throughput pipelines, those round-trips add up fast.

TAG eliminates them for repeated reads. It maintains a local RocksDB-backed cache that serves objects in microseconds instead of milliseconds. Unlike a generic HTTP cache, TAG understands S3 natively — it coalesces concurrent requests into a single upstream fetch, serves range requests from cached full objects, revalidates stale entries with conditional requests, and invalidates cache entries the moment you write or delete an object.

Bottom line: One endpoint change. Zero code changes. Sub-millisecond reads.

Use Cases

ML Model Training

Cache training datasets on local NVMe so multi-epoch training runs don't re-fetch data from remote storage on every epoch. The first epoch populates the cache; subsequent epochs read entirely from local storage, removing the network bottleneck without requiring you to pre-download datasets, shard data into tar archives, or adopt a new storage API. Works with PyTorch DataLoaders, S3 Connector for PyTorch, and any S3-compatible data loading library.

Inference Data Caching

Cache model weights, configuration files, or other assets that inference workloads read repeatedly. Reduces cold-start latency and eliminates redundant network traffic.

High-Throughput Data Pipelines

For real-time analytics or data processing pipelines that repeatedly read the same objects, TAG eliminates redundant network round-trips and serves data at local NVMe speeds.

Performance

Benchmarked on AWS (c6in.16xlarge client, i3en.24xlarge server with NVMe storage):

Object SizeOps/secBandwidthTTFB p50
1 KiB75,71773.9 MiB/s< 1 ms
100 KiB33,3503.2 GiB/s< 1 ms
1 MiB10,95510.7 GiB/sSingle-digit ms
4 MiB2,77510.8 GiB/sSingle-digit ms

TAG saturates a 100 Gbps NIC at 85+ Gbps for 1 MiB+ objects, with CPU utilization at only about 12%, leaving significant headroom for additional workloads.

note

These numbers reflect cache-warm steady state. First requests for uncached objects incur a round-trip to Tigris.

For full methodology, environment specs, and complete warp and go-ycsb results, see Benchmarks.

Key Features

S3-Compatible API

TAG implements the S3 REST API for commonly used Tigris operations. Clients interact with TAG using standard AWS SDKs, the AWS CLI, or any S3-compatible library. The only change is the endpoint URL.

Path-Style Addressing Only

TAG supports path-style addressing only (http://host:port/bucket/key). Virtual-hosted style is not supported. Configure your S3 client accordingly.

Transparent Proxy Mode

In default mode, TAG preserves the client's original AWS SigV4 Authorization header and forwards requests to Tigris as-is. TAG adds cryptographically signed proxy headers so Tigris can validate both the client's identity and TAG's identity in a single round-trip.

Security

TAG never sees or stores client secret keys. Clients authenticate directly with Tigris using their own credentials.

Embedded Cache with RocksDB

Each TAG node runs an embedded cache backed by RocksDB, optimized for NVMe storage. Objects are stored using a two-key pattern:

KeyStored data
meta|my-bucket|photo.jpgContent-Type, ETag, Content-Length, Last-Modified
body|my-bucket|photo.jpgRaw object bytes

Separating metadata from body enables efficient HEAD requests and conditional operations without reading the full object.

Request Coalescing

If four clients ask for the same uncached object at the same time, TAG doesn't make four trips to Tigris. It fetches once and streams the result to everyone:

Client AClient BClient CClient DGET same keyTAG Coalescersingle GETTigrisstream chunksbroadcast to all

Range Request Optimization

When you send a byte-range request, TAG serves it from the cached full object if available. On a range miss, TAG does two things at once: it serves you the requested range directly from Tigris while also fetching the full object in the background. After that, any future range request for any byte range comes straight from cache.

tip

This is especially useful for ML workloads that access model weights with random-access patterns. The first range request warms the full object into cache.

Write-Through Invalidation

When you write, delete, or copy an object through TAG, it invalidates the corresponding cache entry before forwarding the request to Tigris. A tombstone mechanism prevents any in-flight background cache writes from accidentally resurrecting objects you've already deleted.

caution

Objects modified directly on Tigris (bypassing TAG) remain cached until the TTL expires (default 60 minutes) or a client forces revalidation with Cache-Control: no-cache. Route writes through TAG for immediate consistency.

Optional Multi-Node Clustering

When a single node's storage isn't enough, you can run multiple TAG nodes as a distributed cache cluster. They coordinate automatically:

Load BalancerTAG-1keys A–FTAG-2keys G–RTAG-3keys S–ZgRPCgRPCgossip protocol

Nodes discover each other via gossip, consistent hashing spreads keys across the cluster, and gRPC forwards requests for remote keys transparently. You don't need to manually assign keys or configure sharding.

Architecture

Here's how a request flows through TAG's internals:

S3 ClientsSDK / CLI / boto3TAG ProcessHTTP :8080SigV4 AuthProxy ServiceCoalescingRange OptimizationRocksDB CacheNVMe DiskTigris ObjectStoragegRPC :9000Gossip :7000

Request Flows

Cache hit: Your request arrives, TAG validates your SigV4 signature locally, finds the object in cache, and returns it with X-Cache: HIT. Tigris is never contacted.

Cache miss: TAG forwards your request to Tigris, streams the response back to you while writing it to cache, and returns X-Cache: MISS. The next request for the same object is a hit.

Coalesced request: Multiple clients GET the same uncached object — the first becomes the fetcher, the rest attach as broadcast listeners. Everyone gets the data simultaneously from a single upstream request.

Range request: You send Range: bytes=0-1023 — if the full object is cached, TAG serves your range from cache. If not, it serves the range from Tigris while fetching the full object in the background for future requests.

Ports

PortProtocolPurpose
8080HTTP/HTTPSS3 API (client-facing)
7000TCPMemberlist gossip (cluster discovery)
9000TCPgRPC (cache key routing between nodes)
macOS port conflict

On macOS, port 7000 is used by AirPlay Receiver. Use ports 17000 (gossip) and 19000 (gRPC) instead when running TAG locally on macOS. See Configuration Reference for details.

S3 API Coverage

TAG supports commonly used S3 operations, validated against 214 tests from the ceph/s3-tests compatibility suite.

CategoryOperations
ObjectsGet, Head, Put, Delete, Copy, Tagging, ACL
BucketsList, Create, Delete, Head, ListV1/V2, Location, Versioning, ACL, Policy, CORS, Tagging, Lifecycle, DeleteObjects (bulk)
Multipart UploadsInitiate, UploadPart, UploadPartCopy, Complete, Abort, ListParts, ListMultipartUploads
AuthSigV4 headers, presigned URLs, chunked encoding
Not Supported

Object versioning, server-side encryption (SSE-C/S3/KMS), Object Lock, POST object (browser uploads), multi-range requests, and virtual-hosted style addressing.

For client SDK examples (AWS CLI, Python boto3, and more), see S3 Client Usage.

Cache Behavior

TAG adds an X-Cache response header to every response:

ValueMeaning
HITServed from cache (includes successful revalidations)
MISSFetched from Tigris, now cached
REVALIDATEDRevalidated with Tigris; object changed and new content returned
BYPASSCache skipped (client sent Cache-Control: no-store)
DISABLEDCaching turned off server-side

What gets cached: HTTP 200 responses within the size threshold (default 1 GiB) that do not include Cache-Control: no-store or private.

What does not: Non-200 responses, objects above the size threshold, and objects with cache-prevention headers.

For revalidation, client cache-control headers, and automatic invalidation details, see Cache Control and Revalidation.

Security Model

Your clients sign requests with their own Tigris credentials, and TAG forwards them to Tigris as-is — it never sees or stores your secret keys. After a client's first request, TAG learns derived signing keys from Tigris (encrypted with AES-256-GCM), so it can validate subsequent requests locally without calling home.

TAG requires its own Tigris credentials (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY) with read-only access to all buckets in the same organization as clients it serves.

Important

Authorization is per-bucket. Access to one bucket does not grant access to others. Entries are revoked immediately on a Tigris 403 response.

For the full authentication flow, authorization lifecycle, proxy header security, and endpoint validation, see Security and Access Control.

Monitoring

TAG exposes 30+ Prometheus metrics at /metrics covering request throughput, cache effectiveness, request coalescing, upstream health, authentication, and connection stats.

For the full metrics reference, PromQL examples, alerting recommendations, and scrape configuration, see Metrics Reference.