Caching

BoxLang ships with an enterprise Caching Engine and Cache Agnostic API Aggregator!

BoxLang Cache Engine

BoxCache Diagram

The BoxLang Cache Engine is a high-performance caching solution designed to optimize data retrieval speeds for applications using the BoxLang programming language. By leveraging advanced caching algorithms and memory management techniques, it minimizes latency, enhances scalability, and improves the overall efficiency of data access. Whether handling frequent read operations or reducing server load, the BoxLang Cache Engine serves as an essential component for deploying robust and responsive applications.

Cache Aggregation

The BoxLang Cache Engine also functions as a powerful cache aggregator. This capability allows it to aggregate various cache providers under a single, unified interface, simplifying the management and operation of caching systems. By providing a centralized API, BoxLang Cache Engine streamlines access to multiple caching solutions, ensuring seamless integration and enhanced flexibility. This feature is particularly beneficial for applications that require a diverse set of caching tactics, as it reduces complexity and boosts overall system coherence.

Features at a Glance

  • Cache Aggregator

    • Ability to aggregate different caching engines via our ICacheProvider interface

    • Ability to aggregate different configurations of the same caches

    • Rich aggregation event model

    • Granular logging

  • Fast and Simple to use

    • Simple API and configuration parameters

    • Small Footprint

  • Solid Core

    • Multi-Threaded

    • Based on Java Concurrency Classes

    • Multiple Eviction Policies: FIFO, LFU, LIFO, LRU, MFU, MRU, Random

    • Memory Management & Memory Sensitive Caching based on Java Soft References

    • Distributed caching support via JDBC Store

  • Extensible & Flexible

    • CachelListeners for event broadcasting

    • Create custom eviction policies

    • Create custom cache providers

    • Create custom cache key filters

    • Create custom object storages

    • Pluggable storage backends (Memory, Disk, JDBC)

  • Highly Configurable

    • JVM Threshold Checks

    • Object Limits

    • Ability to time-expire objects

    • Eternal (singletons) and time-lived objects

    • Fully configurable at runtime via dynamic configurations and hot updates

    • Database-backed distributed caching

Configuration

The main BoxLang configuration file configures the BoxCache boxlang.json which can be found in your $BOXLANG_HOME/config/boxlang.json. You can find all the documentation about configuration in the caches area.

Default Caches

Every BoxLang runtime comes pre-configured with the following mandatory caches for operation. You can configure them as you see fit. Please see the caches configuration area.

Cache
Object Store
Hint

default

ConcurrentStore

The default cache in BoxLang is used for queries, templates, and many more internal usages.

bxSessions

ConcurrentStore

If you activate session management in your web or client applications, user session information will be stored here.

bxRegex

ConcurrentSoftReferenceStore

This is where all dynamic regular expressions are compiled and kept.

Providers

Here are the available providers for BoxLang. The table shows the status of completion for each provider and its availability for the open-source version of BoxLang, as well as for +/++ subscribers.

Provider
Description
Status
OS
+/++

BoxLang

The enterprise BoxLang native cache provider can leverage many different object stores.

Done

Redis

A Redis single-node provider

Done

RedisCluster

A Redis cluster cache provider

Done

MongoDB

A MongoDB based Provider

In Progress

Couchbase

A Couchbase based provider

In Progress

ElasticSearch

An Elastic Search provider

In Progress

EhCache

An EhCacheProvider

In Progress

You can also find more providers through third-party providers at www.forgebox.io.

Object Stores

Object stores are the foundational storage layer of the BoxLang cache engine. They provide the actual mechanism for storing, retrieving, and managing cached objects. While cache providers coordinate user interactions and act as a service layer, object stores handle the low-level data persistence and retrieval operations.

Type
Description

BlackHoleStore

Mocking store, just simulates a store, nothing is stored.

ConcurrentSoftReferenceStore

Memory-sensitive storage leveraging Java Soft References.

ConcurrentStore

Leverages concurrent hashmaps for storage.

FileSystemStore

Stores the cache items in a serialized fashion on disk

JDBCStore

Distributed cache store backed by JDBC databases for multi-instance cache sharing

Each store can have different configuration properties as well.

Eviction Policies

The BoxCache also ships with several different eviction policies that are triggered on eviction conditions like:

  • Max objects reached

  • Memory threshold

  • Garbage collections

  • Much more.

Policy
Purpose

LRU (Least Recently Used)

Evicts the objects that haven't been accessed for the longest time. Best for applications with temporal locality where recently accessed items are more likely to be accessed again. Ideal for general-purpose caching scenarios.

MRU (Most Recently Used)

Evicts the most recently accessed objects first. Useful when you want to keep older, established data and remove newly added items. Good for scenarios where recent additions are less valuable than historical data.

LFU (Least Frequently Used)

Evicts objects with the lowest access frequency count. Maintains items that are accessed often, regardless of when they were last accessed. Perfect for caching frequently requested data like popular products or common API responses.

MFU (Most Frequently Used)

Evicts the most frequently accessed objects first. Counterintuitive but useful in scenarios where you want to cycle out "hot" data to make room for less popular items that might become important. Rare use case but valuable for specialized applications.

FIFO (First In, First Out)

Evicts objects in the order they were added to the cache. Simple queue-based eviction that doesn't consider access patterns. Good for time-sensitive data where older entries naturally become less relevant, like news feeds or log entries.

LIFO (Last In, First Out)

Evicts the most recently added objects first, like a stack. Keeps older established data while removing newer additions. Useful when you want to maintain a stable core dataset and only temporarily cache additional items.

Random

Evicts objects randomly without considering access patterns or insertion order. Provides consistent average performance without the overhead of tracking access metadata. Good for scenarios where no clear access pattern exists or when you want to avoid the worst-case behaviors of other policies.

Cache BIFs (Built-in Functions)

BoxLang provides a comprehensive set of Built-in Functions (BIFs) that offer convenient access to the caching infrastructure. These BIFs provide a developer-friendly interface for working with caches, filters, and the cache service, eliminating the need for direct Java interaction.

Overview

Cache BIFs serve as the primary interface for BoxLang developers to interact with the caching system. They provide:

  • Simple Access: Easy retrieval of cache instances and services

  • Functional Approach: Chainable operations for cache manipulation

  • Filter Support: Powerful pattern matching for bulk operations

  • Service Discovery: Introspection capabilities for registered caches and providers

  • BoxLang Integration: Native BoxLang syntax and conventions

Available Cache BIFs

Summary Table

BIF
Purpose
Returns

cache()

Get a cache instance by name

ICacheProvider

cacheFilter()

Create filters for cache key operations

ICacheKeyFilter

cacheNames()

List all registered cache names

Array

cacheProviders()

List all registered cache providers

Array

cacheService()

Access the cache service directly

CacheService

cache(cacheName)

The primary BIF for accessing cache instances. Returns a cache provider that implements the ICacheProvider interface.

Syntax:

Parameters:

  • cacheName (string, optional): The name of the cache to retrieve. Defaults to "default"

Returns: ICacheProvider - The requested cache instance

Examples:

cacheFilter( filter, useRegex )

Creates filter objects for performing bulk operations on cache keys using pattern matching.

Syntax:

Parameters:

  • filter (string, required): The pattern to match against cache keys

  • useRegex (boolean, optional): Use regex pattern instead of wildcard. Defaults to false

Returns: ICacheKeyFilter - A filter object for cache operations

Wildcard Patterns:

  • * - Matches any sequence of characters

  • ? - Matches any single character

  • [abc] - Matches any character in the brackets

  • [a-z] - Matches any character in the range

Examples:

Custom Filter Functions:

You can also use closures/lambdas as filters:

cacheNames()

Returns an array of all registered cache names in the system.

Syntax:

Returns: Array - Array of cache names as strings

Examples:

cacheProviders()

Returns an array of all registered cache provider names.

Syntax:

Returns: Array - Array of provider names as strings

Examples:

cacheService()

Provides direct access to the underlying cache service for advanced operations.

Syntax:

Returns: CacheService - The cache service instance

Examples:

Practical Usage Patterns

Basic Caching Pattern

API Response Caching

Cache Warming and Preloading

Cache Statistics and Monitoring

Dynamic Cache Creation

Error Handling and Fallbacks

Advanced Patterns

Cache Hierarchies

Multi-Cache Operations

Cache Synchronization

Best Practices

1. Cache Naming Conventions

2. Efficient Filter Usage

3. Error Handling

4. Performance Monitoring

Keep Exploring

BoxLang's Cache BIFs provide a powerful and intuitive interface for working with the caching infrastructure. They enable developers to:

  • Access Caches Easily: Simple syntax for retrieving and using cache instances

  • Filter Operations: Powerful pattern matching for bulk cache operations

  • Service Discovery: Easy introspection of available caches and providers

  • Advanced Management: Direct access to cache service capabilities

By leveraging these BIFs, developers can implement sophisticated caching strategies while maintaining clean, readable BoxLang code. The functional approach supports both simple use cases and complex enterprise caching scenarios. Now that we have the basics, we will explore more in-depth how to use the BoxCache engine.

Last updated

Was this helpful?