On this page:



Applications such as patient dashboards need to quickly extract rich data from FHIR Endpoints. The volume of complex queries these applications generate can result in slow response times. Smile CDR provides a resource bundle caching service called “LiveBundle” to improve the performance of applications in situations like this. Administrators configure aggregation rules that store named FHIR Resource Bundles on the server and keep the list of references behind these bundles "warm" so they can be instantly retrieved by applications at runtime.

This is best illustrated with an example. Imagine a maternity ward with a patient dashboard that monitors the health of patients on the ward. It calculates a Modified Early Obstetric Warning Score (MEOWS) for each patient using 5 vitals.


Without using LiveBundle, this application would regularly query the FHIR repository for the most recent Observation for each vital for each patient.

In place of such queries, we could set up a LiveBundle to keep track of these vitals for us. To do this, we would first create a Watchlist called "MATERNITY". When a new patient is admitted to the ward, we add them to this Watchlist so LiveBundle will start tracking data for this patient. We would then create a new LiveBundle rule called "MEOWS" attached to this Watchlist that stores the most recent Observation for each vital. Then, when the app needs to display this dashboard, it would request the MEOWS LiveBundle for each patient to retrieve these stored Observations.



LiveBundle configuration is managed on a FHIR Storage module. When you enable the LiveBundle feature on a FHIR Storage module, Smile CDR adds an interceptor to that matches incoming resources against LiveBundle filters and aggregates rules. Enabling the LiveBundle feature on a FHIR Storage module also adds new LiveBundle Operations to FHIR Endpoint modules attached to that FHIR Storage module.

LiveBundle aggregation rules are configured using JavaScript. This JavaScript can either be stored in a file on disk or in the database. To store the LiveBundle rules in a file, specify an absolute filepath in livebundle_service.script.file. Alternatively, store the JavaScript in the database directly in livebundle_service.script.text.

See LiveBundle Rule Definition and LiveBundle Keepers for details on how LiveBundle aggregation rules are defined in JavaScript.

By default, LiveBundle watchlists are cached in memory and refreshed once per minute. If a matching resource for a just-added subscriber arrives on a different server within that minute, then that resource will be missed and not stored in that subscriber's bundle. For this reason, it's best to add subscribers at a time when new resources are not being submitted for them. This LiveBundle watchlist cache can be disabled by switching off the Watchlist Cache Enabled configuration option. When the cache is disabled, the matching operation for incoming resources is reversed: With cache enabled, first the resource is checked against the in-memory watchlist cache and then if it's on the list it is matched against the filter criteria. However, when the Watchlist Cache is disabled, first the resource will be matched against the Filter Criteria and then a database lookup checks to see if any subscriber references are on the watchlist for that Filter.



See LiveBundle API for details on how to call LiveBundle Operations on a FHIR Endpoint.

6.0.3LiveBundle Architecture


An overview of LiveBundle architecture is illustrated in the following diagram:

The top row of this diagram represents the flow of resources into the CDR. This means resources being created and updated, which are then used as sources of data for LiveBundles. It is described in the LiveBundle Aggregation section.

The bottom row represents requests for data stored in a LiveBundle, e.g. to display to a user in a dashboard. It is described in the LiveBundle Retrieval section.

LiveBundle Overview

6.0.4LiveBundle Aggregation


A LiveBundle aggregation rule has two parts, a "Filter" and a "Keeper". The Filter determines whether an incoming resource triggers aggregation and the Keeper determines which references derived from that incoming resource is stored. A Filter has a Watchlist associated with it that maintains a list of Subscribers to that Filter.

In our MEOWS example, the Filter would match Observations that have a code for one of the vitals we are tracking. The MEOWS Keeper would be configured to store only the latest Observation for each vital.

The LiveBundle aggregation is triggered when any resource is created, updated or deleted on the FHIR Storage module. It checks to see if the resource matches any LiveBundle Filters. Matching follows these steps:

  1. First the resource type is compared to the "Root Resource Type" of the Filter.
  2. If the resource type matches, then it checks to see if the incoming resource references a subscriber on the Watchlist for that Filter.
  3. If it matches a Subscriber, then we check if the incoming resource matches the Filter Criteria.

If the incoming resource matches, it is passed to the "Keeper" associated with that Filter. The Keeper adds and/or removes LiveBundle references according to its algorithm. See LiveBundle Keepers for details on how Keepers work.

6.0.5LiveBundle Retrieval


The LiveBundle aggregation accumulates references for your Subscriber, so that they can later be retrieved as a resource bundle. A LiveBundle is retrieved by a Rule Name and SubscriberId.

In our MEOWS example, the Subscriber would be the maternity patient id and the Rule Name would be MEOWS.

LiveBundle retrieval follows these steps:

  1. The Retriever collects all LiveBundle references stored for that Rule and SubscriberId (or list of SubscriberIds or SubscriberGroup).
  2. If an _include parameter is on the LiveBundle request, those _included references are added to the list of references.
  3. All references are expanded into resources and collected into a FHIR Bundle Resource.
  4. FHIR Composition resources are added to the top of the bundle, serving as a table of contents for each SubscriberId in the bundle.

6.0.6LiveBundle Seeding


Sometimes when a Watchlist and Rule are defined and a new Subscriber is added to that Watchlist, there will already be pre-existing data for that rule that should be accumulated for that Subscriber. This is called "Seeding" the bundle for that Subscriber. When a Subscriber is added to the Watchlist, Smile CDR searches the FHIR Storage repository for matching resources and aggregates a starting set of references for that Subscriber. Going forward, as new resources arrive, this list is updated.

In our MEOWS example, perhaps the patient was initially admitted to the Emergency ward where and vitals Observations had been collected for them. When that patient is added to the MATERNITY watchlist, the MEOWS LiveBundle would search for these Observations and seed the MEOWS bundle for that patient with their most recent vitals.

LiveBundle seeding works as follows:

  1. Search for Resources of the "Root Resource Type" of the filter.
    1. Start with the Filter criteria
    2. If the Keeper for this rule has a KeeperFilter (e.g. only keep resources less than 6 months old) then append this criteria
    3. Cap the search results to the "Seed Count" of the Rule.
  2. These search results are then fed to the Keeper one at a time as if they had been intercepted. The Keeper updates the LiveBundle references for that Subscriber according to its algorithm.

6.0.7LiveBundle Troubleshooting


The LiveBundle Troubleshooting Log can be helpful in diagnosing issues relating to Live Bundles.