Project

General

Profile

Feature #8196 ยป tax-engine_design_document_by_kalyan.md

Kalyan Ravula, 03/12/2026 12:51 PM

 

Tax Engine Caching Strategy Design Document

Overview

The Tax Engine is designed to calculate sales tax for line items while minimizing the frequency of external API calls to TaxJar. This is achieved through a multi-level, line-item granular caching strategy.

Core Problem

External tax services like TaxJar often charge per API request. In a Point of Sale (POS) system with high transaction volumes, frequent API calls can become prohibitively expensive.

Solution: Granular Multi-Level Caching

1. Line-Item Granularity

Unlike traditional caching that might store the entire response of a transaction, this system caches tax rates at the Line Item Level.

  • Cache Key: A SHA-256 hash of from_zip + to_zip + product_tax_code.
  • Price Independence: The unit_price is excluded from the cache key. This ensures that if the price of an item changes, the tax rate remains valid and cached. The final tax amount is recalculated dynamically using the cached rate.

2. Multi-Level Storage

The system uses two layers of caching for maximum efficiency:

  1. L1: Redis (Speed): An in-memory cache for ultra-fast lookups during active sessions.
  2. L2: MongoDB (Persistence): A persistent database store to ensure that tax rates remain available across application restarts and provide a long-term historical record.

3. Partial API Execution (Nexus Strategy)

When a request with multiple line items arrives:

  1. The engine iterates through all line items.
  2. It checks L1 (Redis) and then L2 (MongoDB) for each item.
  3. It separates items into Cached and Missing.
  4. Efficiency Gain: If 8 out of 10 items are cached, the engine makes a partial API call to TaxJar containing only the 2 missing items.
  5. Results are then aggregated: cached data is merged with the new API response to return a complete result to the user.

Architecture Diagram

graph TD
    A[POS Request] --> B{Tax Engine}
    B --> C[Iterate Line Items]
    C --> D{Check L1: Redis}
    D -- Hit --> E[Add to Results]
    D -- Miss --> F{Check L2: MongoDB}
    F -- Hit --> G[Backfill L1 & Add to Results]
    F -- Miss --> H[Mark as Missing]
    H --> I{Missing Items > 0?}
    I -- Yes --> J[Call TaxJar API for Missing]
    J --> K[Cache New Rates in L1 & L2]
    K --> L[Aggregate All Results]
    I -- No --> L
    L --> M[Final Tax Response]

Benefits

  • Cost Reduction: Significant decrease in TaxJar API billing by reusing rates for common zip code pairs and product categories.
  • Improved Latency: Cached items are returned in milliseconds, avoiding the network overhead of an external API call.
  • Resilience: The system can still provide tax rates for previously seen items even if the external tax service is temporarily unreachable.
  • Scalability: Decoupling the tax calculation from the external service allows the POS system to handle higher bursts of traffic.

Data Schema (MongoDB)

Cached items are stored with the following structure:

  • cacheKey: Unique identifier (hash).
  • taxRate: The combined tax rate.
  • stateTaxRate, countryTaxRate, shippingTaxRate: Breakdown for audit purposes.
  • requestPayload: Metadata about the original request (zips, tax code) for debugging.
  • createdAt: TTL management.
    (1-1/1)