In a distributed cache environment, it’s often crucial for certain data to be readily available in the cache as soon as the application begins execution. Typically, when a cache starts, it is empty, leading to expensive trips to the data source to fetch necessary data, which negatively impacts application performance. To address this, it’s important to preload the cache with essential reference data before the application starts using it.
Unlike manual cache-aside loading where the first request suffers from high latency (the “Cache Miss” penalty), the NCache Startup Loader ensures 100% data availability from the moment the cache starts. Fortunately, NCache offers a Cache Startup Loader feature that allows users to implement an interface for preloading specific reference data into the cache at startup. This shifts the heavy lifting from the application tier to the NCache Execution Service, significantly reducing database pressure during traffic spikes. By pre-populating the cache, the application experiences fewer cache misses and avoids the performance penalties of a “cold start,” resulting in improved response times.
Key Takeaways
Preloading Reference Data: The NCache Cache Startup Loader is a specialized feature that preloads critical reference data into the distributed cache during the initial startup process.
Eliminating Cold Start Latency: By pre-populating the cache, the loader eliminates “cold start” latency, ensuring the first user request is served at high speed without a “cache miss” penalty.
Offloading with NCache Execution Service: The system offloads data-loading tasks to a dedicated NCache Execution Service, which runs independently of the main cache process to prevent resource contention.
Parallel Loading with Datasets: Data is organized into Datasets, allowing for parallel loading across multiple cluster nodes using a Round-Robin distribution strategy for maximum efficiency.
Built-in Fault Tolerance: The feature provides resilience through configurable Retry Mechanisms (intervals and attempts) and allows for On-Demand Refreshes via PowerShell without a cache restart.

Figure 1: High-level architecture of NCache Startup Loader distributing data loading tasks across a cluster.
Properties of Cache Startup Loader
Every time the cache starts up, the Cache Startup Loader automatically loads data from the data source for the application to use beforehand. Therefore, before moving onto how the Cache Loader works, it’s important to understand some of its key properties:
| Property | Technical Description | Impact on Performance & Control |
|---|---|---|
| NCache Execution Service | A dedicated service that manages the loading of data from the source into the cache at startup. | Isolates loading processes from the main cache service to ensure stability. |
| Datasets | Named logical groups of data types that can be loaded or refreshed at different intervals. | Enables parallelism by allowing different data types to load simultaneously. |
| Dataset Assignment | The process of distributing datasets across cluster nodes in a Round Robin fashion. | Maximizes cluster utilization and prevents resource bottlenecks during startup. |
| Loading Mechanism | Defines specific objects to be loaded from the master data source as CacheItems. | Ensures only relevant, high-priority data is preloaded into the distributed cache. |
| Cache Loader Retries | Configures the total number of allowed retry attempts for any failed data loading operation. | Increases system reliability by handling transient database or network failures. |
| Retry Interval | The specific time delay between failed attempts to load a dataset. | Prevents “retry storms” and gives the backend time to recover. |
| On-Demand Refresh | Provides manual control via the Invoke-RefresherDataset cmdlet to update data instantly. | Offers operational flexibility to refresh specific data groups without a full restart. |
How to Implement Cache Startup Loader?
To enable Cache Startup Loader, the user needs to implement the ICacheLoader interface. NCache uses this interface with the methods explained below to load data from the data source in the cache on cache-startup.
Initialize Cache Startup Loader
To initialize the Cache Startup Loader, the Init method is called on the Cache Startup to pass the configured parameters so that the user can use it accordingly to initialize their cache and the data source. To do so, just create the connection by opening a database connection like SQL and initialize a cache with the given name like the below sample implementation for .NET and Java.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using System; using System.Collections.Generic; using System.Data.SqlClient; using Alachisoft.NCache.Client; public class CacheLoader { private ICache _cache; private SqlConnection _connection; private string _connectionString; public void Init (IDictionary<string, string> parameters, string cacheName) { // Initialize NCache using the latest API _cache = CacheProvider.GetCache(cacheName); // Retrieve connection string safely if (parameters.TryGetValue("ConnectionString", out _connectionString) && !string.IsNullOrEmpty(_connectionString)) { _connection = new SqlConnection(_connectionString); } } // ... } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import com.alachisoft.ncache.client.*; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Map; public class CacheLoader { private ICache cache; private Connection connection; private String connectionString; public void init(Map<String, String> parameters, String cacheName) { // Initialize NCache using the latest API cache = CacheProvider.getCache(cacheName); // Retrieve connection string safely connectionString = parameters.getOrDefault("ConnectionString", null); // Establish database connection if connection string is available if (connectionString != null && !connectionString.isEmpty()) { try { connection = DriverManager.getConnection(connectionString); } catch (SQLException e) { throw new RuntimeException("Failed to establish database connection.", e); } } } // ... } |
Load Data on Cache Startup
After the successful initialization of the Cache Startup Loader, comes the LoadDatasetOnStartup method of the ICacheLoader interface. It fetches the data from the data source and adds it into the cache upon startup. It returns a user context that holds the information about the data loaded in the cache.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
using System; using System.Collections.Generic; using Alachisoft.NCache.Client; public class CacheLoader { private ICache _cache; private SqlConnection _connection; private string _connectionString; public object LoadDatasetOnStartup (string dataset) { if (string.IsNullOrEmpty(dataset)) throw new ArgumentException("Dataset name cannot be null or empty.", nameof(dataset)); // Standardize dataset name dataset = dataset.ToLowerInvariant(); // Use a dictionary for dynamic dataset retrieval var datasetLoaders = new Dictionary<string, Func<IList<object>>> { { "products", FetchProductsFromDataSource }, { "suppliers", FetchSuppliersFromDataSource } }; if (datasetLoaders.TryGetValue(dataset, out var fetchFunction)) { IList<object> datasetToLoad = fetchFunction.Invoke(); foreach (var item in datasetToLoad) { string key = dataset switch { "products" => $"ProductID:{((Product)item).Id}", "suppliers" => $"SupplierID:{((Supplier)item).Id}", => throw new InvalidOperationException("Unsupported dataset.") }; _cache.Insert(key, item); } } else { throw new ArgumentException($"Invalid dataset: {dataset}", nameof(dataset)); } // Return the time of dataset loading return DateTime.UtcNow; } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import com.alachisoft.ncache.client.*; import java.time.Instant; import java.util.*; public class CacheLoader { private ICache cache; private Connection connection; private String connectionString; public Object loadDatasetsOnStartup (String dataset) { if (dataset == null || dataset.isEmpty()) { throw new IllegalArgumentException("Dataset name cannot be null or empty."); } // Standardize dataset name dataset = dataset.toLowerCase(); // Use a Map for dynamic dataset retrieval Map<String, List<Object> > datasetMap = Map.of( "products", fetchProductsFromDataSource(), "suppliers", fetchSuppliersFromDataSource() ); // Check if the dataset exists and process it if (datasetMap.containsKey(dataset)) { List<Object> datasetToLoad = datasetMap.get(dataset); for (Object item : datasetToLoad) { String key = switch (dataset) { case "products" -> "ProductID:" + ((Product) item).getId(); case "suppliers" -> "SupplierID:" + ((Supplier) item).getId(); default -> throw new IllegalStateException("Unexpected dataset: " + dataset); }; cache.insert(key, item); } } else { throw new IllegalArgumentException("Invalid dataset: " + dataset); } // Return the time of dataset loading return Instant.now(); } } |
To learn more about the Cache Refresher, refer to the Cache Refresher documentation.
Configure Cache Loader through the NCache Management Center
Once the user has implemented the Cache Startup Loader, they can configure it through the NCache Management Center. Below is how it can be done.

Figure 2: Configure Cache Loader through the NCache Management Center
Conclusion
NCache’s Cache Startup Loader feature offers a robust solution for preloading data into your cache, ensuring that your application starts with all the necessary information readily available. This automation minimizes manual tasks and minimizes database trips, leading to faster application performance and enhanced scalability. By leveraging NCache’s capabilities, you can significantly boost your application’s efficiency and responsiveness, making it well-equipped to handle high-demand scenarios and dynamic data requirements.
Frequently Asked Questions (FAQ)
How do I configure the Cache Startup Loader in NCache?
The loader is configured through the config.ncconf file or via the NCache Management Center, where you specify the assembly name and class implementing the ICacheLoader interface, along with optional parameters like retry intervals.
What is the role of the ICacheLoader interface?
The ICacheLoader interface acts as the bridge between NCache and your backend data source; it contains the custom logic required to fetch data and package it into CacheItems for the initial load.
Can I manually trigger a data refresh without a cache restart?
Yes, you can use the Invoke-RefresherDataset PowerShell cmdlet to manually trigger an on-demand refresh of specific datasets, providing operational flexibility for data that changes frequently.
Does the Startup Loader block client requests during execution?
No, the loader runs as a background process via the NCache Execution Service. This allows the cache to become available for client connections immediately, while data is being preloaded in the background.
What happens if a data loading operation fails?
NCache utilizes a built-in Retry Mechanism where you can define the number of “Retry Attempts” and the “Retry Interval” to ensure the loader handles transient network or database connectivity issues gracefully.




