How Quote Caching Improves Performance for Repeated Swap Queries in Osmosis Agent Toolkit

The toolkit uses an in-memory LRU cache to store swap quote responses, eliminating redundant network calls to the remote SQS service for identical requests.

The osmosis-agent-toolkit repository provides a TypeScript-based agent framework for interacting with the Osmosis decentralized exchange. When users repeatedly query swap quotes for the same token pairs and amounts, the toolkit avoids expensive remote lookups by leveraging quote caching through bounded in-memory storage.

How Quote Caching Works

The implementation relies on two specialized LRUCache instances that store quote responses with distinct eviction policies and retrieval mechanisms.

Cache Initialization

When OsmosisAgentToolkit is instantiated, it creates two separate caches in packages/core/src/toolkit.ts to handle different quote directions:

protected readonly _quoteAmountOutMemory = new LRUCache<string, SidecarInGivenOutQuoteResponse>({ max: 100 })
protected readonly _quoteAmountInMemory  = new LRUCache<string, SidecarOutGivenInQuoteResponse>({ max: 100 })

Each cache is bounded to 100 entries to prevent unbounded memory growth, automatically evicting the least-recently-used entries when the limit is exceeded.

Storing Quotes

After fetching a quote from the SQS backend, the swap tools in packages/core/src/tools/swap.ts generate a deterministic cache key and store the raw response:

const id = `${params.tickerIn}-${params.tickerOut}-${params.amountOut}`
this.memory?.set(id, quote)

The key combines the input token symbol, output token symbol, and amount, ensuring that identical queries map to the same cache entry.

Retrieving Cached Quotes

When executing a swap transaction, the toolkit checks for existing cached quotes before making remote requests:

const quote = this.memory.get(params.quoteId)
if (!quote) throw new Error(`Quote not found: ${params.quoteId}`)

This lookup operates in O(1) time, returning the full quote response object including routing information and price data.

Cache Eviction After Use

To prevent stale quote data from being reused indefinitely, the toolkit immediately deletes cache entries after they are consumed for transaction construction:

this.memory.delete(params.quoteId)

This ensures that each quote is used exactly once for trading, while the LRU mechanism handles cleanup of unused entries.

Performance Impact

Quote caching transforms the performance characteristics of repeated swap queries:

Metric Without Caching With Caching
Latency 100ms–several seconds (network round-trip) Microseconds (in-memory lookup)
Backend Load Linear increase with query volume Bounded by cache size; duplicates served locally
Reliability Fails if SQS service is unavailable Cached quotes remain usable during outages
Memory Usage Minimal Bounded to 200 entries maximum (100 per cache)

Practical Implementation Examples

Getting and Caching a Quote

const toolkit = new OsmosisAgentToolkit(mnemonic)

// Request quote: 1 OSMO → 100 USDC
const quote = await toolkit.swapQuoteInGivenOutTool.call({
  tickerIn: 'OSMO',
  amountOut: '100',
  tickerOut: 'USDC',
})

// Response cached with key "OSMO-USDC-100"

Reusing a Cached Quote

// Execute swap using cached quote ID
const result = await toolkit.sendSwapInGivenOutQuoteTxTool.call({
  quoteId: 'OSMO-USDC-100',
  slippageTolerancePercent: 0.5,
})

// Cache entry automatically deleted after use

Direct Cache Inspection

// Access cache directly for debugging
const cached = toolkit['_quoteAmountOutMemory'].get('OSMO-USDC-100')
console.log(cached?.amount_in)  // Raw quote data

Summary

  • LRU caching eliminates redundant network calls to the SQS service for identical swap quote requests.
  • Two bounded caches (_quoteAmountOutMemory and _quoteAmountInMemory) store up to 100 entries each in packages/core/src/toolkit.ts.
  • Cache keys are deterministic strings combining token symbols and amounts, generated in packages/core/src/tools/swap.ts.
  • Quotes are retrieved in O(1) time and immediately evicted after use to prevent stale data reuse.
  • The implementation reduces latency from hundreds of milliseconds to microseconds while providing resilience against SQS service outages.

Frequently Asked Questions

How does the toolkit prevent memory leaks with quote caching?

The toolkit uses LRUCache instances with a fixed max size of 100 entries per cache. When the cache reaches capacity, the least-recently-used entries are automatically evicted, ensuring memory usage remains bounded regardless of query volume.

What happens if a cached quote expires or becomes stale?

Each quote is used exactly once. After a transaction tool retrieves a quote from the cache to build and broadcast a swap transaction, it immediately calls this.memory.delete(params.quoteId) to remove the entry. This prevents any possibility of reusing stale price data.

Can developers access or inspect the cache contents directly?

Yes, though the caches are marked as protected, TypeScript allows access via bracket notation for debugging purposes. Developers can inspect cached entries using toolkit['_quoteAmountOutMemory'].get(key) to view raw SidecarInGivenOutQuoteResponse objects.

Does quote caching work when the SQS backend is temporarily unavailable?

Yes, cached quotes remain available in local memory even if the SQS service experiences downtime. Since the toolkit serves identical requests from the LRU cache without requiring network connectivity, users can continue executing swaps based on previously fetched quotes during brief outages.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →