blob: 28e9dfe229a855ad9b35012b91daac5abb7fa8bc [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.18">
<link rel="icon" type="image/png" href="images/favicon.png">
<title>Paging</title>
<link rel="stylesheet" href="css/asciidoctor.css">
<link rel="stylesheet" href="css/font-awesome.css">
<link rel="stylesheet" href="css/rouge-github.css">
</head>
<body class="book toc2 toc-left">
<div id="header">
<h1>Paging</h1>
<div id="toc" class="toc2">
<div id="toctitle"><a href="index.html">User Manual for 2.33.0</a></div>
<ul class="sectlevel1">
<li><a href="#page-files">1. Page Files</a>
<ul class="sectlevel2">
<li><a href="#configuration">1.1. Configuration</a></li>
</ul>
</li>
<li><a href="#paging-mode">2. Paging Mode</a>
<ul class="sectlevel2">
<li><a href="#configuration-2">2.1. Configuration</a></li>
<li><a href="#max-size-bytes-and-max-size-messages-simultaneous-usage">2.2. max-size-bytes and max-size-messages simultaneous usage</a></li>
</ul>
</li>
<li><a href="#global-max-size">3. Global Max Size</a></li>
<li><a href="#global-max-messages">4. Global Max Messages</a></li>
<li><a href="#dropping-messages">5. Dropping messages</a></li>
<li><a href="#dropping-messages-and-throwing-an-exception-to-producers">6. Dropping messages and throwing an exception to producers</a></li>
<li><a href="#blocking-producers">7. Blocking producers</a></li>
<li><a href="#caution-with-addresses-with-multiple-multicast-queues">8. Caution with Addresses with Multiple Multicast Queues</a></li>
<li><a href="#monitoring-disk">9. Monitoring Disk</a>
<ul class="sectlevel2">
<li><a href="#max-disk-usage">9.1. Max Disk Usage</a></li>
<li><a href="#minimum-disk-free">9.2. Minimum Disk Free</a></li>
</ul>
</li>
<li><a href="#page-sync-timeout">10. Page Sync Timeout</a></li>
<li><a href="#memory-usage-from-paged-messages">11. Memory usage from Paged Messages.</a></li>
<li><a href="#page-limits-and-page-full-policy">12. Page Limits and Page Full Policy</a></li>
<li><a href="#example">13. Example</a></li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Apache ActiveMQ Artemis transparently supports huge queues containing millions of messages while the server is running with limited memory.</p>
</div>
<div class="paragraph">
<p>In such a situation it&#8217;s not possible to store all of the queues in memory at any one time, so Apache ActiveMQ Artemis transparently <em>pages</em> messages into and out of memory as they are needed, thus allowing massive queues with a low memory footprint.</p>
</div>
<div class="paragraph">
<p>Apache ActiveMQ Artemis will start paging messages to disk, when the size of all messages in memory for an address exceeds a configured maximum size.</p>
</div>
<div class="paragraph">
<p>The default configuration from Artemis has destinations with paging.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="page-files"><a class="anchor" href="#page-files"></a><a class="link" href="#page-files">1. Page Files</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Messages are stored per address on the file system.
Each address has an individual folder where messages are stored in multiple files (page files).
Each file will contain messages up to a max configured size (<code>page-size-bytes</code>).
The system will navigate the files as needed, and it will remove the page file as soon as all the messages are acknowledged up to that point.</p>
</div>
<div class="paragraph">
<p>Browsers will read through the page-cursor system.</p>
</div>
<div class="paragraph">
<p>Consumers with selectors will also navigate through the page-files and it will ignore messages that don&#8217;t match the criteria.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<div class="paragraph">
<p>When you have a queue, and consumers filtering the queue with a very restrictive selector you may get into a situation where you won&#8217;t be able to read more data from paging until you consume messages from the queue.</p>
</div>
<div class="paragraph">
<p>Example: in one consumer you make a selector as 'color="red"' but you only have one color red 1 millions messages after blue, you won&#8217;t be able to consume red until you consume blue ones.</p>
</div>
<div class="paragraph">
<p>This is different to browsing as we will "browse" the entire queue looking for messages and while we "depage" messages while feeding the queue.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="configuration"><a class="anchor" href="#configuration"></a><a class="link" href="#configuration">1.1. Configuration</a></h3>
<div class="paragraph">
<p>You can configure the location of the paging folder in <code>broker.xml</code>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>paging-directory</code> Where page files are stored.
Apache ActiveMQ Artemis will create one folder for each address being paged under this configured location.
Default is <code>data/paging</code>.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="paging-mode"><a class="anchor" href="#paging-mode"></a><a class="link" href="#paging-mode">2. Paging Mode</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>As soon as messages delivered to an address exceed the configured size, that address alone goes into page mode.
If max-size-bytes == 0 or max-size-messages == 0, an address will always use paging to route messages.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Paging is done individually per address.
If you configure a max-size-bytes or max-messages for an address, that means each matching address will have a maximum size that you specified.
It DOES NOT mean that the total overall size of all matching addresses is limited to max-size-bytes.
Use <a href="#global-max-size">global-max-size</a> or <a href="#global-max-messages">global-max-messages</a> for that!</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="configuration-2"><a class="anchor" href="#configuration-2"></a><a class="link" href="#configuration-2">2.1. Configuration</a></h3>
<div class="paragraph">
<p>Configuration is done at the address settings in <code>broker.xml</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="xml"><span class="nt">&lt;address-settings&gt;</span>
<span class="nt">&lt;address-setting</span> <span class="na">match=</span><span class="s">"jms.someaddress"</span><span class="nt">&gt;</span>
<span class="nt">&lt;max-size-bytes&gt;</span>104857600<span class="nt">&lt;/max-size-bytes&gt;</span>
<span class="nt">&lt;max-size-messages&gt;</span>1000<span class="nt">&lt;/max-size-messages&gt;</span>
<span class="nt">&lt;page-size-bytes&gt;</span>10485760<span class="nt">&lt;/page-size-bytes&gt;</span>
<span class="nt">&lt;address-full-policy&gt;</span>PAGE<span class="nt">&lt;/address-full-policy&gt;</span>
<span class="nt">&lt;page-limit-bytes&gt;</span>10G<span class="nt">&lt;/page-limit-bytes&gt;</span>
<span class="nt">&lt;page-limit-messages&gt;</span>1000000<span class="nt">&lt;/page-limit-messages&gt;</span>
<span class="nt">&lt;page-full-policy&gt;</span>FAIL<span class="nt">&lt;/page-full-policy&gt;</span>
<span class="nt">&lt;/address-setting&gt;</span>
<span class="nt">&lt;/address-settings&gt;</span></code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <a href="management.html#configuring-management">management-address</a> settings cannot be changed or overridden ie management messages aren&#8217;t allowed to page/block/fail and are considered an internal broker management mechanism.
The memory occupation of the <a href="management.html#configuring-management">management-address</a> is not considered while evaluating if <a href="#global-max-size">global-max-size</a> is hit and can&#8217;t cause other non-management addresses to trigger a configured <code>address-full-policy</code>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>This is the list of available parameters on the address settings.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Property Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>max-size-bytes</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">What&#8217;s the max memory the address could have before entering on page mode.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-1 (disabled)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>max-size-messages</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The max number of messages the address could have before entering on page mode.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-1 (disabled)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>page-size-bytes</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The size of each page file used on the paging system</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">10MB</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>address-full-policy</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">This must be set to <code>PAGE</code> for paging to enable.
If the value is <code>PAGE</code> then further messages will be paged to disk.
If the value is <code>DROP</code> then further messages will be silently dropped.
If the value is <code>FAIL</code> then the messages will be dropped and the client message producers will receive an exception.
If the value is <code>BLOCK</code> then client message producers will block when they try and send further messages.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>PAGE</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>max-read-page-messages</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Maximum number of paged messages that the broker can read into memory per-queue. The default value is -1, which means that no limit applies.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-1 (disabled)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>max-read-page-bytes</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Maximum memory, in bytes, that can be used to read paged messages into memory per-queue. When applying this limit, the broker takes into account both messages that are currently delivering and messages that are ready to be delivered to consumers. The default value is 2 * page-size (usually being 20 MB). If consumers are slow to acknowledge messages, you can increase the default value to ensure that the memory is not consumed by messages pending acknowledgment, which can starve the broker of messages.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2 * page-size-bytes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">prefetch-page-messages</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of paged messages that the broker can read from disk into memory per-queue. The default value is taken from max-read-page-messages, usually at -1, which means that no limit applies.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>max-read-page-messages</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">prefetch-page-bytes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of paged messages that the broker can read from disk into memory per-queue. The default value is taken from max-read-page-messages, usually at -1, which means that no limit applies.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">if not defined, <code>max-read-page-bytes</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>page-limit-bytes</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">After entering page mode, how much data would the system allow incoming.
Notice this will be internally converted as number of pages.</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>page-limit-messages</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">After entering page mode, how many messages would the system allow incoming on paging.</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>page-full-policy</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Valid results are DROP or FAIL.
This tells what to do if the system is reaching <code>page-limit-bytes</code> or <code>page-limit-messages</code> after paging</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
When using the JDBC storage, the effective page-size-bytes used is limited to jdbc-max-page-size-bytes, configured in the JDBC storage section.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="max-size-bytes-and-max-size-messages-simultaneous-usage"><a class="anchor" href="#max-size-bytes-and-max-size-messages-simultaneous-usage"></a><a class="link" href="#max-size-bytes-and-max-size-messages-simultaneous-usage">2.2. max-size-bytes and max-size-messages simultaneous usage</a></h3>
<div class="paragraph">
<p>It is possible to define max-size-messages (as the maximum number of messages) and max-messages-size (as the max number of estimated memory used by the address) concurrently.
The configured policy will start based on the first value to reach its mark.</p>
</div>
<div class="sect3">
<h4 id="maximum-read-from-page"><a class="anchor" href="#maximum-read-from-page"></a><a class="link" href="#maximum-read-from-page">2.2.1. Maximum read from page</a></h4>
<div class="paragraph">
<p><code>max-read-page-messages</code>, <code>max-read-page-bytes</code>, <code>prefetch-page-messages</code> and <code>prefetch-page-bytes</code> are used to control reading from paged file into the Queue.
The broker will add messages as long as all these limits are satisfied.</p>
</div>
<div class="paragraph">
<p>If all these values are set to -1 the broker will keep reading messages as long as the consumer is reaching for more messages.
However this would keep the broker unprotected from consumers allocating huge transactions or consumers that don&#8217;t have flow control enabled.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="global-max-size"><a class="anchor" href="#global-max-size"></a><a class="link" href="#global-max-size">3. Global Max Size</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Beyond the <code>max-size-bytes</code> on the address you can also set the global-max-size on the main configuration.
If you set <code>max-size-bytes</code> = <code>-1</code> on paging the <code>global-max-size</code> can still be used.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="global-max-messages"><a class="anchor" href="#global-max-messages"></a><a class="link" href="#global-max-messages">4. Global Max Messages</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can also specify <code>global-max-messages</code> on the main configuration, specifying how many messages the system would accept before entering into the configured full policy mode configured.</p>
</div>
<div class="paragraph">
<p>When you have more messages than what is configured <code>global-max-size</code> any new produced message will make that destination to go through its paging policy.</p>
</div>
<div class="paragraph">
<p><code>global-max-size</code> is calculated as half of the max memory available to the Java Virtual Machine, unless specified on the <code>broker.xml</code> configuration.</p>
</div>
<div class="paragraph">
<p>By default <code>global-max-messages</code> = <code>-1</code> meaning it&#8217;s disabled.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dropping-messages"><a class="anchor" href="#dropping-messages"></a><a class="link" href="#dropping-messages">5. Dropping messages</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Instead of paging messages when the max size is reached, an address can also be configured to just drop messages when the address is full.</p>
</div>
<div class="paragraph">
<p>To do this just set the <code>address-full-policy</code> to <code>DROP</code> in the address settings</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dropping-messages-and-throwing-an-exception-to-producers"><a class="anchor" href="#dropping-messages-and-throwing-an-exception-to-producers"></a><a class="link" href="#dropping-messages-and-throwing-an-exception-to-producers">6. Dropping messages and throwing an exception to producers</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Instead of paging messages when the max size is reached, an address can also be configured to drop messages and also throw an exception on the client-side when the address is full.</p>
</div>
<div class="paragraph">
<p>To do this just set the <code>address-full-policy</code> to <code>FAIL</code> in the address settings</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="blocking-producers"><a class="anchor" href="#blocking-producers"></a><a class="link" href="#blocking-producers">7. Blocking producers</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Instead of paging messages when the max size is reached, an address can also be configured to block producers from sending further messages when the address is full, thus preventing the memory being exhausted on the server.</p>
</div>
<div class="paragraph">
<p>When memory is freed up on the server, producers will automatically unblock and be able to continue sending.</p>
</div>
<div class="paragraph">
<p>To do this just set the <code>address-full-policy</code> to <code>BLOCK</code> in the address settings</p>
</div>
<div class="paragraph">
<p>In the default configuration, all addresses are configured to block producers after 10 MiB of data are in the address.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="caution-with-addresses-with-multiple-multicast-queues"><a class="anchor" href="#caution-with-addresses-with-multiple-multicast-queues"></a><a class="link" href="#caution-with-addresses-with-multiple-multicast-queues">8. Caution with Addresses with Multiple Multicast Queues</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>When a message is routed to an address that has multiple multicast queues bound to it, e.g. a JMS subscription in a Topic, there is only 1 copy of the message in memory.
Each queue only deals with a reference to this.
Because of this the memory is only freed up once all queues referencing the message have delivered it.</p>
</div>
<div class="paragraph">
<p>If you have a single lazy subscription, the entire address will suffer IO performance hit as all the queues will have messages being sent through an extra storage on the paging system.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>An address has 10 multicast queues</p>
</li>
<li>
<p>One of the queues does not deliver its messages (maybe because of a slow consumer).</p>
</li>
<li>
<p>Messages continually arrive at the address and paging is started.</p>
</li>
<li>
<p>The other 9 queues are empty even though messages have been sent.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In this example all the other 9 queues will be consuming messages from the page system.
This may cause performance issues if this is an undesirable state.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="monitoring-disk"><a class="anchor" href="#monitoring-disk"></a><a class="link" href="#monitoring-disk">9. Monitoring Disk</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The broker can be configured to perform scans on the disk to determine if disk is beyond a configured limit.
Since the disk is a critical piece of infrastructure for data integrity the broker will automatically shut itself down if it runs out of disk space.
Configuring a limit allows the broker to enforce flow control on clients sending messages to the broker so that the disk never fills up completely.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
If the protocol used to send the messages doesn&#8217;t support flow control (e.g. STOMP) then an exception will be thrown and the connection for the client will be dropped so that it can no longer send messages and consume disk space.
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="max-disk-usage"><a class="anchor" href="#max-disk-usage"></a><a class="link" href="#max-disk-usage">9.1. Max Disk Usage</a></h3>
<div class="paragraph">
<p>A limit on the <em>maximum</em> disk space used can be configured through <code>max-disk-usage</code>
This is the <strong>percentage</strong> of disk used.
For example, if the disk&#8217;s capacity was 500GiB and <code>max-disk-usage</code> was <code>50</code> then the broker would start blocking producers once 250GiB of disk space was used.</p>
</div>
</div>
<div class="sect2">
<h3 id="minimum-disk-free"><a class="anchor" href="#minimum-disk-free"></a><a class="link" href="#minimum-disk-free">9.2. Minimum Disk Free</a></h3>
<div class="paragraph">
<p>A limit on the <em>minimum</em> disk space free can be configured through <code>min-disk-free</code>
This is specific amount and not a percentage like with <code>max-disk-usage</code>.
For example, if the disk&#8217;s capacity was 500GiB and <code>min-disk-free</code> was <code>100GiB</code> then the broker would start blocking producers once 400GiB of disk space was used.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If <em>both</em> <code>max-disk-usage</code> and <code>min-disk-free</code> are configured then <code>min-disk-free</code> will take priority.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="page-sync-timeout"><a class="anchor" href="#page-sync-timeout"></a><a class="link" href="#page-sync-timeout">10. Page Sync Timeout</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The pages are synced periodically and the sync period is configured through <code>page-sync-timeout</code> in nanoseconds.
When using NIO journal, by default has the same value of <code>journal-buffer-timeout</code>.
When using ASYNCIO, the default should be <code>3333333</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="memory-usage-from-paged-messages"><a class="anchor" href="#memory-usage-from-paged-messages"></a><a class="link" href="#memory-usage-from-paged-messages">11. Memory usage from Paged Messages.</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The system should keep at least one paged file in memory caching ahead reading messages.
Also every active subscription could keep one paged file in memory.
So, if your system has too many queues it is recommended to minimize the page-size.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="page-limits-and-page-full-policy"><a class="anchor" href="#page-limits-and-page-full-policy"></a><a class="link" href="#page-limits-and-page-full-policy">12. Page Limits and Page Full Policy</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Since version <code>2.28.0</code> is possible to configure limits on how much data is paged.
This is to avoid a single destination using the entire disk in case their consumers are gone.</p>
</div>
<div class="paragraph">
<p>You can configure either <code>page-limit-bytes</code> or <code>page-limit-messages</code>, along with <code>page-full-policy</code> on the address settings limiting how much data will be recorded in paging.</p>
</div>
<div class="paragraph">
<p>If you configure <code>page-full-policy</code> as DROP, messages will be simplify dropped while the clients will not get any exceptions, while if you configured FAIL the producers will receive a JMS Exception for the error condition.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="example"><a class="anchor" href="#example"></a><a class="link" href="#example">13. Example</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>See the <a href="examples.html#paging">Paging Example</a> which shows how to use paging with Apache ActiveMQ Artemis.</p>
</div>
</div>
</div>
</div>
</body>
</html>